GP-1359 - Updated the Listing and Byte Viewer to show selection size as the user drags

This commit is contained in:
dragonmacher 2024-08-12 12:04:38 -04:00
parent 5047c00359
commit 4cda642e9c
9 changed files with 175 additions and 117 deletions

View file

@ -105,7 +105,10 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
private CoordinatedListingPanelListener coordinatedListingPanelListener; private CoordinatedListingPanelListener coordinatedListingPanelListener;
private FormatManager formatMgr; private FormatManager formatMgr;
private FieldPanelCoordinator coordinator; private FieldPanelCoordinator coordinator;
private ProgramSelectionListener liveProgramSelectionListener = (selection, trigger) -> {
liveSelection = selection;
updateSubTitle();
};
private FocusingMouseListener focusingMouseListener; private FocusingMouseListener focusingMouseListener;
private CodeBrowserClipboardProvider codeViewerClipboardProvider; private CodeBrowserClipboardProvider codeViewerClipboardProvider;
@ -116,6 +119,7 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
private CloneCodeViewerAction cloneCodeViewerAction; private CloneCodeViewerAction cloneCodeViewerAction;
private ProgramSelection currentSelection; private ProgramSelection currentSelection;
private ProgramSelection liveSelection;
private ProgramSelection currentHighlight; private ProgramSelection currentHighlight;
private String currentStringSelection; private String currentStringSelection;
@ -163,6 +167,7 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
createActions(); createActions();
listingPanel.setProgramLocationListener(this); listingPanel.setProgramLocationListener(this);
listingPanel.setProgramSelectionListener(this); listingPanel.setProgramSelectionListener(this);
listingPanel.setLiveProgramSelectionListener(liveProgramSelectionListener);
listingPanel.setStringSelectionListener(this); listingPanel.setStringSelectionListener(this);
listingPanel.addIndexMapChangeListener(this); listingPanel.addIndexMapChangeListener(this);
@ -542,11 +547,18 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
private void doSetSelection(ProgramSelection selection) { private void doSetSelection(ProgramSelection selection) {
liveSelection = null;
currentSelection = selection; currentSelection = selection;
codeViewerClipboardProvider.setSelection(currentSelection); codeViewerClipboardProvider.setSelection(currentSelection);
listingPanel.setSelection(currentSelection); listingPanel.setSelection(currentSelection);
plugin.selectionChanged(this, currentSelection); plugin.selectionChanged(this, currentSelection);
contextChanged(); contextChanged();
updateSubTitle();
}
private void updateSubTitle() {
ProgramSelection selection = liveSelection != null ? liveSelection : currentSelection;
String selectionInfo = null; String selectionInfo = null;
if (!selection.isEmpty()) { if (!selection.isEmpty()) {
long n = selection.getNumAddresses(); long n = selection.getNumAddresses();

View file

@ -345,10 +345,8 @@ public class ListingModelAdapter implements LayoutModel, ListingModelListener {
return ps; return ps;
} }
} }
Program program = model.getProgram();
addrSet = model.adjustAddressSetToCodeUnitBoundaries(addrSet); addrSet = model.adjustAddressSetToCodeUnitBoundaries(addrSet);
AddressFactory factory = program == null ? null : program.getAddressFactory(); return new ProgramSelection(null, addrSet);
return new ProgramSelection(factory, addrSet);
} }
// this methods does NOT work for structures inside of unions, but handles structures // this methods does NOT work for structures inside of unions, but handles structures

View file

@ -63,7 +63,19 @@ public class ListingPanel extends JPanel implements FieldMouseListener, FieldLoc
private ProgramLocationListener programLocationListener; private ProgramLocationListener programLocationListener;
private ProgramSelectionListener programSelectionListener; private ProgramSelectionListener programSelectionListener;
private ProgramSelectionListener liveProgramSelectionListener;
private StringSelectionListener stringSelectionListener; private StringSelectionListener stringSelectionListener;
private FieldSelectionListener fieldPanelLiveSelectionListener = (selection, trigger) -> {
if (liveProgramSelectionListener == null) {
return;
}
ProgramSelection ps = layoutModel.getProgramSelection(selection);
if (ps != null) {
liveProgramSelectionListener.programSelectionChanged(ps, trigger);
}
};
private ListingModel listingModel; private ListingModel listingModel;
private FieldHeader headerPanel; private FieldHeader headerPanel;
@ -106,6 +118,7 @@ public class ListingPanel extends JPanel implements FieldMouseListener, FieldLoc
fieldPanel.addFieldMouseListener(this); fieldPanel.addFieldMouseListener(this);
fieldPanel.addFieldLocationListener(this); fieldPanel.addFieldLocationListener(this);
fieldPanel.addFieldSelectionListener(this); fieldPanel.addFieldSelectionListener(this);
fieldPanel.addLiveFieldSelectionListener(fieldPanelLiveSelectionListener);
fieldPanel.addLayoutListener(this); fieldPanel.addLayoutListener(this);
propertyBasedColorModel = new PropertyBasedBackgroundColorModel(); propertyBasedColorModel = new PropertyBasedBackgroundColorModel();
fieldPanel.setBackgroundColorModel(propertyBasedColorModel); fieldPanel.setBackgroundColorModel(propertyBasedColorModel);
@ -207,6 +220,16 @@ public class ListingPanel extends JPanel implements FieldMouseListener, FieldLoc
programSelectionListener = listener; programSelectionListener = listener;
} }
/**
* Sets the ProgramSelectionListener for selection changes while dragging. Only one listener is
* supported
*
* @param listener the ProgramSelectionListener to use.
*/
public void setLiveProgramSelectionListener(ProgramSelectionListener listener) {
liveProgramSelectionListener = listener;
}
public void setStringSelectionListener(StringSelectionListener listener) { public void setStringSelectionListener(StringSelectionListener listener) {
stringSelectionListener = listener; stringSelectionListener = listener;
} }

View file

@ -32,15 +32,6 @@ public class ProgramSelection implements AddressSetView {
* Construct a new empty ProgramSelection. * Construct a new empty ProgramSelection.
*/ */
public ProgramSelection() { public ProgramSelection() {
this((AddressFactory) null);
}
/**
* Construct a new empty ProgramSelection.
* @param addressFactory the address factory for the address set
* associated with this program selection.
*/
public ProgramSelection(AddressFactory addressFactory) {
addressSet = new AddressSet(); addressSet = new AddressSet();
} }
@ -50,18 +41,6 @@ public class ProgramSelection implements AddressSetView {
* @param to the end of the selection * @param to the end of the selection
*/ */
public ProgramSelection(Address from, Address to) { public ProgramSelection(Address from, Address to) {
this(null, from, to);
}
/**
* Constructor.
* @param addressFactory the address factory for the address set
* associated with this program selection.
* @param from the start of the selection
* @param to the end of the selection
*/
public ProgramSelection(AddressFactory addressFactory, Address from, Address to) {
this(addressFactory);
if (to.compareTo(from) < 0) { if (to.compareTo(from) < 0) {
Address temp = to; Address temp = to;
to = from; to = from;
@ -75,36 +54,59 @@ public class ProgramSelection implements AddressSetView {
* @param setView address set for the selection * @param setView address set for the selection
*/ */
public ProgramSelection(AddressSetView setView) { public ProgramSelection(AddressSetView setView) {
this(null, setView);
}
/**
* Construct a new ProgramSelection
* @param addressFactory the address factory for the address set
* associated with this program selection.
* @param setView address set for the selection
*/
public ProgramSelection(AddressFactory addressFactory, AddressSetView setView) {
addressSet = new AddressSet(setView); addressSet = new AddressSet(setView);
} }
/**
* Construct a new ProgramSelection from the indicated interior selection.
* @param addressFactory the address factory for the address set
* associated with this program selection.
* @param sel the interior selection
*/
public ProgramSelection(AddressFactory addressFactory, InteriorSelection sel) {
this(addressFactory, sel.getStartAddress(), sel.getEndAddress());
interiorSelection = sel;
}
/** /**
* Construct a new ProgramSelection from the indicated interior selection. * Construct a new ProgramSelection from the indicated interior selection.
* @param sel the interior selection * @param sel the interior selection
*/ */
public ProgramSelection(InteriorSelection sel) { public ProgramSelection(InteriorSelection sel) {
this(null, sel); this(sel.getStartAddress(), sel.getEndAddress());
interiorSelection = sel;
}
/**
* Construct a new empty ProgramSelection.
* @param addressFactory NOT USED
* @deprecated use {@link #ProgramSelection()}
*/
@Deprecated(since = "11.2", forRemoval = true)
public ProgramSelection(AddressFactory addressFactory) {
this();
}
/**
* Constructor.
* @param addressFactory NOT USED
* @param from the start of the selection
* @param to the end of the selection
*/
@Deprecated(since = "11.2", forRemoval = true)
public ProgramSelection(AddressFactory addressFactory, Address from, Address to) {
this(from, to);
}
/**
* Construct a new ProgramSelection
* @param addressFactory NOT USED
* @param setView address set for the selection
* @deprecated use {@link #ProgramSelection(AddressSetView)}
*/
@Deprecated(since = "11.2", forRemoval = true)
public ProgramSelection(AddressFactory addressFactory, AddressSetView setView) {
this(setView);
}
/**
* Construct a new ProgramSelection from the indicated interior selection.
* @param addressFactory NOT USED
* @param sel the interior selection
* @deprecated use {@link #ProgramSelection(InteriorSelection)}s
*/
@Deprecated(since = "11.2", forRemoval = true)
public ProgramSelection(AddressFactory addressFactory, InteriorSelection sel) {
this(sel);
} }
/** /**

View file

@ -68,6 +68,11 @@ public class ByteViewerComponent extends FieldPanel implements FieldMouseListene
private ByteViewerHighlighter highlightProvider = new ByteViewerHighlighter(); private ByteViewerHighlighter highlightProvider = new ByteViewerHighlighter();
private int highlightButton = MouseEvent.BUTTON2; private int highlightButton = MouseEvent.BUTTON2;
private FieldSelectionListener liveSelectionListener = (selection, trigger) -> {
ByteBlockSelection sel = processFieldSelection(selection);
panel.updateLiveSelection(ByteViewerComponent.this, sel);
};
/** /**
* Constructor * Constructor
* *
@ -206,12 +211,12 @@ public class ByteViewerComponent extends FieldPanel implements FieldMouseListene
if (blockSet == null || doingRefresh) { if (blockSet == null || doingRefresh) {
return; return;
} }
ByteBlockSelection sel = processFieldSelection(selection); ByteBlockSelection sel = processFieldSelection(selection);
// notify panel to update other components // notify panel to update other components
panel.updateSelection(this, sel); panel.updateSelection(this, sel);
setViewerSelection(sel); setViewerSelection(sel);
} }
/** /**
@ -339,12 +344,10 @@ public class ByteViewerComponent extends FieldPanel implements FieldMouseListene
return null; return null;
} }
/**
* Add listeners.
*/
void addListeners() { void addListeners() {
addFieldLocationListener(this); addFieldLocationListener(this);
addFieldSelectionListener(this); addFieldSelectionListener(this);
addLiveFieldSelectionListener(liveSelectionListener);
addFieldInputListener(this); addFieldInputListener(this);
addFieldMouseListener(this); addFieldMouseListener(this);
} }

View file

@ -429,6 +429,8 @@ public abstract class ByteViewerComponentProvider extends ComponentProviderAdapt
protected abstract void updateSelection(ByteBlockSelection selection); protected abstract void updateSelection(ByteBlockSelection selection);
protected abstract void updateLiveSelection(ByteBlockSelection selection);
void dispose() { void dispose() {
updateManager.dispose(); updateManager.dispose();
updateManager = null; updateManager = null;

View file

@ -101,9 +101,8 @@ public class ByteViewerPanel extends JPanel implements LayoutModel, LayoutListen
height += dim.height; height += dim.height;
} }
boolean addHeight = true; boolean addHeight = true;
for (int i = 0; i < viewList.size(); i++) { for (ByteViewerComponent c : viewList) {
ByteViewerComponent c = viewList.get(i);
Dimension d = c.getPreferredSize(); Dimension d = c.getPreferredSize();
width += d.width; width += d.width;
width += 2; // for separator width += 2; // for separator
@ -133,54 +132,47 @@ public class ByteViewerPanel extends JPanel implements LayoutModel, LayoutListen
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
void setCurrentCursorColor(Color c) { void setCurrentCursorColor(Color c) {
currentCursorColor = c; currentCursorColor = c;
for (int i = 0; i < viewList.size(); i++) { for (ByteViewerComponent comp : viewList) {
ByteViewerComponent comp = viewList.get(i);
comp.setCurrentCursorColor(c); comp.setCurrentCursorColor(c);
} }
} }
void setCurrentCursorLineColor(Color c) { void setCurrentCursorLineColor(Color c) {
currentCursorLineColor = c; currentCursorLineColor = c;
for (int i = 0; i < viewList.size(); i++) { for (ByteViewerComponent comp : viewList) {
ByteViewerComponent comp = viewList.get(i);
comp.setCurrentCursorLineColor(c); comp.setCurrentCursorLineColor(c);
} }
} }
void setHighlightButton(int highlightButton) { void setHighlightButton(int highlightButton) {
this.highlightButton = highlightButton; this.highlightButton = highlightButton;
for (int i = 0; i < viewList.size(); i++) { for (ByteViewerComponent comp : viewList) {
ByteViewerComponent comp = viewList.get(i);
comp.setHighlightButton(highlightButton); comp.setHighlightButton(highlightButton);
} }
} }
void setMouseButtonHighlightColor(Color color) { void setMouseButtonHighlightColor(Color color) {
this.highlightColor = color; this.highlightColor = color;
for (int i = 0; i < viewList.size(); i++) { for (ByteViewerComponent comp : viewList) {
ByteViewerComponent comp = viewList.get(i);
comp.setMouseButtonHighlightColor(color); comp.setMouseButtonHighlightColor(color);
} }
} }
void setCursorColor(Color c) { void setCursorColor(Color c) {
for (int i = 0; i < viewList.size(); i++) { for (ByteViewerComponent comp : viewList) {
ByteViewerComponent comp = viewList.get(i);
comp.setNonFocusCursorColor(c); comp.setNonFocusCursorColor(c);
} }
} }
void setSeparatorColor(Color c) { void setSeparatorColor(Color c) {
indexFactory.setMissingValueColor(c); indexFactory.setMissingValueColor(c);
for (int i = 0; i < viewList.size(); i++) { for (ByteViewerComponent comp : viewList) {
ByteViewerComponent comp = viewList.get(i);
comp.setSeparatorColor(c); comp.setSeparatorColor(c);
} }
} }
void setNonFocusCursorColor(Color c) { void setNonFocusCursorColor(Color c) {
for (int i = 0; i < viewList.size(); i++) { for (ByteViewerComponent comp : viewList) {
ByteViewerComponent comp = viewList.get(i);
comp.setNonFocusCursorColor(c); comp.setNonFocusCursorColor(c);
} }
} }
@ -217,13 +209,11 @@ public class ByteViewerPanel extends JPanel implements LayoutModel, LayoutListen
// Do the following loop twice - once with update off and then with update on. // Do the following loop twice - once with update off and then with update on.
// need to do this because all the byte view components must have their models // need to do this because all the byte view components must have their models
// updated before any one of them tells their dependents about the change. // updated before any one of them tells their dependents about the change.
for (int i = 0; i < viewList.size(); i++) { for (ByteViewerComponent c : viewList) {
ByteViewerComponent c = viewList.get(i);
c.enableIndexUpdate(false); c.enableIndexUpdate(false);
c.setIndexMap(indexMap); c.setIndexMap(indexMap);
} }
for (int i = 0; i < viewList.size(); i++) { for (ByteViewerComponent c : viewList) {
ByteViewerComponent c = viewList.get(i);
c.enableIndexUpdate(true); c.enableIndexUpdate(true);
c.setIndexMap(indexMap); c.setIndexMap(indexMap);
} }
@ -235,8 +225,7 @@ public class ByteViewerPanel extends JPanel implements LayoutModel, LayoutListen
} }
void setViewerSelection(ByteBlockSelection selection) { void setViewerSelection(ByteBlockSelection selection) {
for (int i = 0; i < viewList.size(); i++) { for (ByteViewerComponent c : viewList) {
ByteViewerComponent c = viewList.get(i);
c.setViewerSelection(selection); c.setViewerSelection(selection);
} }
} }
@ -249,8 +238,7 @@ public class ByteViewerPanel extends JPanel implements LayoutModel, LayoutListen
} }
void setViewerHighlight(ByteBlockSelection highlight) { void setViewerHighlight(ByteBlockSelection highlight) {
for (int i = 0; i < viewList.size(); i++) { for (ByteViewerComponent c : viewList) {
ByteViewerComponent c = viewList.get(i);
c.setViewerHighlight(highlight); c.setViewerHighlight(highlight);
} }
} }
@ -279,8 +267,7 @@ public class ByteViewerPanel extends JPanel implements LayoutModel, LayoutListen
void setCursorLocation(ByteBlock block, BigInteger index, int column) { void setCursorLocation(ByteBlock block, BigInteger index, int column) {
int modelIndex = -1; int modelIndex = -1;
for (int i = 0; i < viewList.size(); i++) { for (ByteViewerComponent c : viewList) {
ByteViewerComponent c = viewList.get(i);
modelIndex = c.setViewerCursorLocation(block, index, column); modelIndex = c.setViewerCursorLocation(block, index, column);
} }
if (modelIndex >= 0) { if (modelIndex >= 0) {
@ -411,8 +398,7 @@ public class ByteViewerPanel extends JPanel implements LayoutModel, LayoutListen
} }
void setEditMode(boolean editMode) { void setEditMode(boolean editMode) {
for (int i = 0; i < viewList.size(); i++) { for (ByteViewerComponent c : viewList) {
ByteViewerComponent c = viewList.get(i);
c.setEditMode(editMode); c.setEditMode(editMode);
} }
} }
@ -428,8 +414,7 @@ public class ByteViewerPanel extends JPanel implements LayoutModel, LayoutListen
* Force the current view to be refreshed. * Force the current view to be refreshed.
*/ */
void refreshView() { void refreshView() {
for (int i = 0; i < viewList.size(); i++) { for (ByteViewerComponent c : viewList) {
ByteViewerComponent c = viewList.get(i);
c.refreshView(); c.refreshView();
} }
} }
@ -469,8 +454,7 @@ public class ByteViewerPanel extends JPanel implements LayoutModel, LayoutListen
* @throws InvalidInputException if a model cannot support the bytesPerLine value * @throws InvalidInputException if a model cannot support the bytesPerLine value
*/ */
void checkBytesPerLine(int numBytesPerLine) throws InvalidInputException { void checkBytesPerLine(int numBytesPerLine) throws InvalidInputException {
for (int i = 0; i < viewList.size(); i++) { for (ByteViewerComponent c : viewList) {
ByteViewerComponent c = viewList.get(i);
DataFormatModel model = c.getDataModel(); DataFormatModel model = c.getDataModel();
int groupSize = model.getGroupSize(); int groupSize = model.getGroupSize();
if (groupSize > 0) { if (groupSize > 0) {
@ -531,8 +515,7 @@ public class ByteViewerPanel extends JPanel implements LayoutModel, LayoutListen
} }
insertionField.setText(locRep); insertionField.setText(locRep);
} }
for (int i = 0; i < viewList.size(); i++) { for (ByteViewerComponent c : viewList) {
ByteViewerComponent c = viewList.get(i);
if (source == c) { if (source == c) {
continue; continue;
} }
@ -550,8 +533,7 @@ public class ByteViewerPanel extends JPanel implements LayoutModel, LayoutListen
void updateSelection(ByteViewerComponent source, ByteBlockSelection selection) { void updateSelection(ByteViewerComponent source, ByteBlockSelection selection) {
provider.updateSelection(selection); provider.updateSelection(selection);
for (int i = 0; i < viewList.size(); i++) { for (ByteViewerComponent c : viewList) {
ByteViewerComponent c = viewList.get(i);
if (source == c) { if (source == c) {
continue; continue;
} }
@ -559,6 +541,10 @@ public class ByteViewerPanel extends JPanel implements LayoutModel, LayoutListen
} }
} }
void updateLiveSelection(ByteViewerComponent source, ByteBlockSelection selection) {
provider.updateLiveSelection(selection);
}
FontMetrics getCurrentFontMetrics() { FontMetrics getCurrentFontMetrics() {
return fontMetrics; return fontMetrics;
} }
@ -589,8 +575,7 @@ public class ByteViewerPanel extends JPanel implements LayoutModel, LayoutListen
BigInteger offset = vp.getOffset(); BigInteger offset = vp.getOffset();
ViewerPosition vpos = vp.getViewerPosition(); ViewerPosition vpos = vp.getViewerPosition();
for (int i = 0; i < viewList.size(); i++) { for (ByteViewerComponent c : viewList) {
ByteViewerComponent c = viewList.get(i);
c.returnToView(block, offset, vpos); c.returnToView(block, offset, vpos);
} }
indexPanel.setViewerPosition(vpos.getIndex(), vpos.getXOffset(), vpos.getYOffset()); indexPanel.setViewerPosition(vpos.getIndex(), vpos.getXOffset(), vpos.getYOffset());
@ -625,8 +610,7 @@ public class ByteViewerPanel extends JPanel implements LayoutModel, LayoutListen
void setFontMetrics(FontMetrics fm) { void setFontMetrics(FontMetrics fm) {
this.fontMetrics = fm; this.fontMetrics = fm;
for (int i = 0; i < viewList.size(); i++) { for (ByteViewerComponent c : viewList) {
ByteViewerComponent c = viewList.get(i);
c.setFontMetrics(fm); c.setFontMetrics(fm);
} }
indexFactory = new IndexFieldFactory(fm); indexFactory = new IndexFieldFactory(fm);
@ -636,8 +620,7 @@ public class ByteViewerPanel extends JPanel implements LayoutModel, LayoutListen
void setEditColor(Color editColor) { void setEditColor(Color editColor) {
this.editColor = editColor; this.editColor = editColor;
for (int i = 0; i < viewList.size(); i++) { for (ByteViewerComponent c : viewList) {
ByteViewerComponent c = viewList.get(i);
c.setEditColor(editColor); c.setEditColor(editColor);
} }
} }
@ -761,8 +744,7 @@ public class ByteViewerPanel extends JPanel implements LayoutModel, LayoutListen
block = info.getBlock(); block = info.getBlock();
offset = info.getOffset(); offset = info.getOffset();
} }
for (int i = 0; i < viewList.size(); i++) { for (ByteViewerComponent c : viewList) {
ByteViewerComponent c = viewList.get(i);
c.setIndexMap(indexMap); c.setIndexMap(indexMap);
if (info != null) { if (info != null) {
c.setViewerCursorLocation(block, offset, info.getColumn()); c.setViewerCursorLocation(block, offset, info.getColumn());
@ -775,8 +757,7 @@ public class ByteViewerPanel extends JPanel implements LayoutModel, LayoutListen
* Clear the selection. * Clear the selection.
*/ */
private void clearSelection() { private void clearSelection() {
for (int i = 0; i < viewList.size(); i++) { for (ByteViewerComponent c : viewList) {
ByteViewerComponent c = viewList.get(i);
c.clearViewerSelection(); c.clearViewerSelection();
} }
} }

View file

@ -62,6 +62,7 @@ public class ProgramByteViewerComponentProvider extends ByteViewerComponentProvi
protected Program program; protected Program program;
protected ProgramSelection currentSelection; protected ProgramSelection currentSelection;
protected ProgramSelection liveSelection;
protected ProgramSelection currentHighlight; protected ProgramSelection currentHighlight;
protected ProgramLocation currentLocation; protected ProgramLocation currentLocation;
@ -179,7 +180,9 @@ public class ProgramByteViewerComponentProvider extends ByteViewerComponentProvi
} }
protected void setSelection(ProgramSelection selection, boolean notify) { protected void setSelection(ProgramSelection selection, boolean notify) {
liveSelection = null;
currentSelection = selection; currentSelection = selection;
updateTitle();
if (selection == null) { if (selection == null) {
return; return;
} }
@ -258,8 +261,26 @@ public class ProgramByteViewerComponentProvider extends ByteViewerComponentProvi
if (!isConnected()) { if (!isConnected()) {
title = "[" + title + "]"; title = "[" + title + "]";
} }
setTitle(title); setTitle(title);
updateSubTitle();
}
private void updateSubTitle() {
// Note: the Listing has similar code
ProgramSelection selection = liveSelection != null ? liveSelection : currentSelection;
String selectionInfo = null;
if (selection != null && !selection.isEmpty()) {
long n = selection.getNumAddresses();
String nString = Long.toString(n);
if (n == 1) {
selectionInfo = "(1 byte selected)";
}
else {
selectionInfo = '(' + nString + " bytes selected)";
}
}
setSubTitle(selectionInfo);
} }
//================================================================================================== //==================================================================================================
@ -583,12 +604,21 @@ public class ProgramByteViewerComponentProvider extends ByteViewerComponentProvi
@Override @Override
protected void updateSelection(ByteBlockSelection selection) { protected void updateSelection(ByteBlockSelection selection) {
ProgramSelectionPluginEvent event = blockSet.getPluginEvent(plugin.getName(), selection); ProgramSelectionPluginEvent event = blockSet.getPluginEvent(plugin.getName(), selection);
liveSelection = null;
currentSelection = event.getSelection(); currentSelection = event.getSelection();
plugin.updateSelection(this, event, program); plugin.updateSelection(this, event, program);
clipboardProvider.setSelection(currentSelection); clipboardProvider.setSelection(currentSelection);
updateTitle();
contextChanged(); contextChanged();
} }
@Override
protected void updateLiveSelection(ByteBlockSelection selection) {
ProgramSelectionPluginEvent event = blockSet.getPluginEvent(plugin.getName(), selection);
liveSelection = event.getSelection();
updateTitle();
}
@Override @Override
protected void updateLocation(ByteBlock block, BigInteger blockOffset, int column, protected void updateLocation(ByteBlock block, BigInteger blockOffset, int column,
boolean export) { boolean export) {

View file

@ -346,6 +346,13 @@ public class AddressSet implements AddressSetView {
buffy.append(range); buffy.append(range);
buffy.append(" "); buffy.append(" ");
} }
// remove the last space maintain symmetry
char lastChar = buffy.charAt(buffy.length() - 1);
if (lastChar == ' ') {
buffy.deleteCharAt(buffy.length() - 1);
}
buffy.append("]"); buffy.append("]");
return buffy.toString(); return buffy.toString();
} }