Bug 509438 - [traditional] Show a Tooltip for all bytes in range of a

cross reference information

Change-Id: Id5821c0f4c68832f060e6b091ff611e35de6e15d
This commit is contained in:
Alvaro Sanchez-Leon 2016-12-19 07:46:36 -05:00
parent 377f0cc815
commit 84d765d241
4 changed files with 90 additions and 4 deletions

View file

@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.cdt.debug.ui.memory.traditional;singleton:=true
Bundle-Version: 1.4.0.qualifier
Bundle-Version: 1.5.0.qualifier
Bundle-Localization: plugin
Require-Bundle: org.eclipse.debug.core,
org.eclipse.debug.ui,

View file

@ -11,7 +11,7 @@
<relativePath>../../pom.xml</relativePath>
</parent>
<version>1.4.0-SNAPSHOT</version>
<version>1.5.0-SNAPSHOT</version>
<artifactId>org.eclipse.cdt.debug.ui.memory.traditional</artifactId>
<packaging>eclipse-plugin</packaging>
</project>

View file

@ -163,11 +163,22 @@ public class Rendering extends Composite implements IDebugEventSetListener
/**
* Maintains the subset of items visible in the current view address range.
* This information is refreshed when the associated Panes are about to be redrawn
* Note: Only the start address of each entry is included i.e. one entry per information item
* @since 1.4
*/
protected final Map<BigInteger, List<IMemoryBlockAddressInfoItem>> fMapStartAddrToInfoItems = Collections
.synchronizedMap(new HashMap<BigInteger, List<IMemoryBlockAddressInfoItem>>());
/**
* Maps any address within a memory information range to a corresponding list of information items
* sharing that address.
* This is useful to e.g. produce a tooltip while hovering over any memory location of a memory information range
*
* @since 1.5
*/
protected final Map<BigInteger, List<IMemoryBlockAddressInfoItem>> fMapAddrToInfoItems = Collections
.synchronizedMap(new HashMap<BigInteger, List<IMemoryBlockAddressInfoItem>>());
public Rendering(Composite parent, TraditionalRendering renderingParent)
{
super(parent, SWT.DOUBLE_BUFFERED | SWT.NO_BACKGROUND | SWT.H_SCROLL
@ -1198,6 +1209,7 @@ public class Rendering extends Composite implements IDebugEventSetListener
}
fMapStartAddrToInfoItems.clear();
fMapAddrToInfoItems.clear();
super.dispose();
}

View file

@ -132,6 +132,7 @@ public class RenderingAddressInfo extends Rendering
fSelectedContext = null;
fMapStartAddrToInfoItems.clear();
fMapAddrToInfoItems.clear();
fAddressInfoTypeStatusMap.clear();
fAddressInfoItems = null;
@ -261,6 +262,7 @@ public class RenderingAddressInfo extends Rendering
// The selection has changed, so our Address information may no longer be valid
fAddressInfoItems = addressInfoItems;
fMapStartAddrToInfoItems.clear();
fMapAddrToInfoItems.clear();
if (fBinaryPane.isVisible()) {
redrawPanes();
@ -334,6 +336,7 @@ public class RenderingAddressInfo extends Rendering
IMemoryBlockAddressInfoItem[] items = fAddressInfoItems;
if (items == null || !fParent.isShowCrossRefInfoGlobalPref()) {
fMapStartAddrToInfoItems.clear();
fMapAddrToInfoItems.clear();
return fMapStartAddrToInfoItems;
}
@ -343,6 +346,7 @@ public class RenderingAddressInfo extends Rendering
// unless the cell size matches the addressable size of the target system
if (fParent.getAddressableSize() != getBytesPerColumn()) {
fMapStartAddrToInfoItems.clear();
fMapAddrToInfoItems.clear();
return fMapStartAddrToInfoItems;
}
}
@ -357,6 +361,7 @@ public class RenderingAddressInfo extends Rendering
synchronized (fMapStartAddrToInfoItems) {
// Refreshing the Address to InfoItem data map
fMapStartAddrToInfoItems.clear();
fMapAddrToInfoItems.clear();
BigInteger startAddress = getViewportStartAddress();
// Get the endAddress considering a page that uses single height,
// Note: The UI may some times present rows with double height even if the user does not see items
@ -395,6 +400,29 @@ public class RenderingAddressInfo extends Rendering
if (itemStartIsInRange || itemEndIsInRange || itemSpansOverVisibleRange) {
fMapStartAddrToInfoItems.put(item.getAddress(), allValuesMap.get(item.getAddress()));
filteredValuesMap.put(item.getAddress(), allValuesMap.get(item.getAddress()));
// Add information items for each address within the range
// But establish the limits to only add information to visible items (i.e. limiting the processing)
BigInteger firstItemVisibleAddress = itemStartIsInRange ? item.getAddress() : startAddress;
BigInteger lastItemVisibleAddress = itemEndIsInRange ? item.getAddress().add(item.getRangeInAddressableUnits().subtract(BigInteger.ONE)) : endAddress;
for (BigInteger candidateAddress=firstItemVisibleAddress; candidateAddress.compareTo(lastItemVisibleAddress) <=0; candidateAddress = candidateAddress.add(BigInteger.ONE)) {
List<IMemoryBlockAddressInfoItem> allItemsAtBase = allValuesMap.get(item.getAddress());
List<IMemoryBlockAddressInfoItem> newInfoItems = filterToItemsValidForAddress(allItemsAtBase, item.getAddress(), candidateAddress);
// Add new valid items to the map, associating it to candidate address
List<IMemoryBlockAddressInfoItem> existingItems = fMapAddrToInfoItems.get(candidateAddress);
if (existingItems == null) {
// Brand new list of items
fMapAddrToInfoItems.put(candidateAddress, newInfoItems);
} else {
// Appending new items to the existing list
for (IMemoryBlockAddressInfoItem newItem : newInfoItems) {
if (!existingItems.contains(newItem)) {
existingItems.add(newItem);
}
}
}
}
}
}
}
@ -402,10 +430,56 @@ public class RenderingAddressInfo extends Rendering
return filteredValuesMap;
}
/**
* @param allBaseItems - Set of items sharing the same starting address
* @param baseAddress - The starting address
* @param candidateAddress - An address higher than base address
* @return - The set of items that are still overlapping at the incremented address
*/
private List<IMemoryBlockAddressInfoItem> filterToItemsValidForAddress(List<IMemoryBlockAddressInfoItem> allBaseItems,
BigInteger baseAddress, BigInteger candidateAddress) {
List<IMemoryBlockAddressInfoItem> items = new ArrayList<>();
// Keep info items applicable for the given address
BigInteger range = candidateAddress.subtract(baseAddress);
// sanity check - should not happen
if (range.compareTo(BigInteger.ZERO) < 0) {
// return empty list
return items;
}
else if (range.compareTo(BigInteger.ZERO) == 0) {
// Since all items share the same start address,
// all items must be valid for a single address span
return allBaseItems;
}
// Aggregate elements having a length equal or higher than the span between base address and current address
for (IMemoryBlockAddressInfoItem item : allBaseItems) {
if (item.getRangeInAddressableUnits().compareTo(range) >=0 ) {
items.add(item);
}
}
return items;
}
@Override
String buildAddressInfoString(BigInteger cellAddress, String separator, boolean addTypeHeaders) {
List<IMemoryBlockAddressInfoItem> infoItems = fMapStartAddrToInfoItems.get(cellAddress);
List<IMemoryBlockAddressInfoItem> infoItems;
if (addTypeHeaders) {
// Tooltip information
infoItems = fMapAddrToInfoItems.get(cellAddress);
} else {
// element information
infoItems = fMapStartAddrToInfoItems.get(cellAddress);
}
return buildAddressInfoString(cellAddress, separator, addTypeHeaders, infoItems);
}
private String buildAddressInfoString(BigInteger cellAddress, String separator, boolean addTypeHeaders, List<IMemoryBlockAddressInfoItem> infoItems) {
if (infoItems == null || infoItems.size() < 1) {
// No information to display
return "";
@ -455,7 +529,7 @@ public class RenderingAddressInfo extends Rendering
@Override
boolean hasAddressInfo(BigInteger cellAddress) {
return fMapStartAddrToInfoItems.keySet().contains(cellAddress);
return fMapAddrToInfoItems.keySet().contains(cellAddress);
}
/**