mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 10:19:23 +02:00
GP-1433: Refactor Magin and Overview Providers. Add marker margin and overview to dynamic listings.
This commit is contained in:
parent
c0b644b8b9
commit
25dd729323
23 changed files with 1264 additions and 875 deletions
|
@ -484,9 +484,12 @@ public class DebuggerBreakpointMarkerPlugin extends Plugin
|
||||||
private class ToggleBreakpointsMarkerClickedListener implements MarkerClickedListener {
|
private class ToggleBreakpointsMarkerClickedListener implements MarkerClickedListener {
|
||||||
@Override
|
@Override
|
||||||
public void markerDoubleClicked(MarkerLocation location) {
|
public void markerDoubleClicked(MarkerLocation location) {
|
||||||
doToggleBreakpointsAt(ToggleBreakpointAction.NAME,
|
ProgramLocationActionContext context =
|
||||||
new ProgramLocationActionContext(null, location.getProgram(),
|
new ProgramLocationActionContext(null, location.getProgram(),
|
||||||
new ProgramLocation(location.getProgram(), location.getAddr()), null, null));
|
new ProgramLocation(location.getProgram(), location.getAddr()), null, null);
|
||||||
|
if (contextCanManipulateBreakpoints(context)) {
|
||||||
|
doToggleBreakpointsAt(ToggleBreakpointAction.NAME, context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -895,8 +898,8 @@ public class DebuggerBreakpointMarkerPlugin extends Plugin
|
||||||
if (mappingService == null || modelService == null) {
|
if (mappingService == null || modelService == null) {
|
||||||
return Set.of();
|
return Set.of();
|
||||||
}
|
}
|
||||||
ProgramLocation loc = getLocationFromContext(context); // must be static location
|
ProgramLocation loc = getLocationFromContext(context);
|
||||||
if (loc == null) {
|
if (loc == null || loc.getProgram() instanceof TraceProgramView) {
|
||||||
return Set.of();
|
return Set.of();
|
||||||
}
|
}
|
||||||
Set<TraceRecorder> result = new HashSet<>();
|
Set<TraceRecorder> result = new HashSet<>();
|
||||||
|
|
|
@ -52,6 +52,8 @@ import ghidra.app.plugin.core.debug.gui.action.*;
|
||||||
import ghidra.app.plugin.core.debug.gui.modules.DebuggerMissingModuleActionContext;
|
import ghidra.app.plugin.core.debug.gui.modules.DebuggerMissingModuleActionContext;
|
||||||
import ghidra.app.plugin.core.debug.utils.ProgramLocationUtils;
|
import ghidra.app.plugin.core.debug.utils.ProgramLocationUtils;
|
||||||
import ghidra.app.plugin.core.debug.utils.ProgramURLUtils;
|
import ghidra.app.plugin.core.debug.utils.ProgramURLUtils;
|
||||||
|
import ghidra.app.plugin.core.marker.MarkerMarginProvider;
|
||||||
|
import ghidra.app.plugin.core.marker.MarkerOverviewProvider;
|
||||||
import ghidra.app.services.*;
|
import ghidra.app.services.*;
|
||||||
import ghidra.app.services.DebuggerListingService.LocationTrackingSpecChangeListener;
|
import ghidra.app.services.DebuggerListingService.LocationTrackingSpecChangeListener;
|
||||||
import ghidra.app.util.viewer.format.FormatManager;
|
import ghidra.app.util.viewer.format.FormatManager;
|
||||||
|
@ -266,6 +268,8 @@ public class DebuggerListingProvider extends CodeViewerProvider {
|
||||||
protected final MultiBlendedListingBackgroundColorModel colorModel;
|
protected final MultiBlendedListingBackgroundColorModel colorModel;
|
||||||
protected final MarkerSetChangeListener markerChangeListener = new MarkerSetChangeListener();
|
protected final MarkerSetChangeListener markerChangeListener = new MarkerSetChangeListener();
|
||||||
protected MarkerServiceBackgroundColorModel markerServiceColorModel;
|
protected MarkerServiceBackgroundColorModel markerServiceColorModel;
|
||||||
|
protected MarkerMarginProvider markerMarginProvider;
|
||||||
|
protected MarkerOverviewProvider markerOverviewProvider;
|
||||||
|
|
||||||
private SuppressableCallback<ProgramLocation> cbGoTo = new SuppressableCallback<>();
|
private SuppressableCallback<ProgramLocation> cbGoTo = new SuppressableCallback<>();
|
||||||
|
|
||||||
|
@ -500,6 +504,10 @@ public class DebuggerListingProvider extends CodeViewerProvider {
|
||||||
private void setMarkerService(MarkerService markerService) {
|
private void setMarkerService(MarkerService markerService) {
|
||||||
if (this.markerService != null) {
|
if (this.markerService != null) {
|
||||||
this.markerService.removeChangeListener(markerChangeListener);
|
this.markerService.removeChangeListener(markerChangeListener);
|
||||||
|
removeMarginProvider(markerMarginProvider);
|
||||||
|
markerMarginProvider = null;
|
||||||
|
removeOverviewProvider(markerOverviewProvider);
|
||||||
|
markerOverviewProvider = null;
|
||||||
}
|
}
|
||||||
removeOldStaticTrackingMarker();
|
removeOldStaticTrackingMarker();
|
||||||
this.markerService = markerService;
|
this.markerService = markerService;
|
||||||
|
@ -510,6 +518,12 @@ public class DebuggerListingProvider extends CodeViewerProvider {
|
||||||
// NOTE: Connected provider marker listener is taken care of by CodeBrowserPlugin
|
// NOTE: Connected provider marker listener is taken care of by CodeBrowserPlugin
|
||||||
this.markerService.addChangeListener(markerChangeListener);
|
this.markerService.addChangeListener(markerChangeListener);
|
||||||
}
|
}
|
||||||
|
if (this.markerService != null) {
|
||||||
|
markerMarginProvider = markerService.createMarginProvider();
|
||||||
|
addMarginProvider(markerMarginProvider);
|
||||||
|
markerOverviewProvider = markerService.createOverviewProvider();
|
||||||
|
addOverviewProvider(markerOverviewProvider);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@AutoServiceConsumed
|
@AutoServiceConsumed
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,15 +15,15 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.bookmark;
|
package ghidra.app.plugin.core.bookmark;
|
||||||
|
|
||||||
import ghidra.app.context.ListingActionContext;
|
|
||||||
import ghidra.program.model.address.Address;
|
|
||||||
import ghidra.program.util.MarkerLocation;
|
|
||||||
|
|
||||||
import java.awt.event.InputEvent;
|
import java.awt.event.InputEvent;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
|
|
||||||
import docking.ActionContext;
|
import docking.ActionContext;
|
||||||
import docking.action.*;
|
import docking.action.*;
|
||||||
|
import ghidra.app.context.ListingActionContext;
|
||||||
|
import ghidra.program.model.address.Address;
|
||||||
|
import ghidra.program.model.listing.Program;
|
||||||
|
import ghidra.program.util.MarkerLocation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <CODE>AddBookmarkAction</CODE> allows the user to add a Note bookmark at the current location.
|
* <CODE>AddBookmarkAction</CODE> allows the user to add a Note bookmark at the current location.
|
||||||
|
@ -34,8 +33,8 @@ class AddBookmarkAction extends DockingAction {
|
||||||
BookmarkPlugin plugin;
|
BookmarkPlugin plugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new action with the given name and associated to the given
|
* Creates a new action with the given name and associated to the given plugin.
|
||||||
* plugin.
|
*
|
||||||
* @param name the name for this action.
|
* @param name the name for this action.
|
||||||
* @param plugin the plugin this action is associated with.
|
* @param plugin the plugin this action is associated with.
|
||||||
*/
|
*/
|
||||||
|
@ -51,11 +50,12 @@ class AddBookmarkAction extends DockingAction {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method called when the action is invoked.
|
* Method called when the action is invoked.
|
||||||
|
*
|
||||||
* @param ActionEvent details regarding the invocation of this action
|
* @param ActionEvent details regarding the invocation of this action
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionContext context) {
|
public void actionPerformed(ActionContext context) {
|
||||||
plugin.showAddBookmarkDialog(getAddress(context));
|
plugin.showAddBookmarkDialog(getAddress(context), getProgram(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -67,7 +67,7 @@ class AddBookmarkAction extends DockingAction {
|
||||||
if (context == null) {
|
if (context == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return getAddress(context) != null;
|
return getAddress(context) != null && getProgram(context) == plugin.getCurrentProgram();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Address getAddress(ActionContext context) {
|
private Address getAddress(ActionContext context) {
|
||||||
|
@ -80,4 +80,15 @@ class AddBookmarkAction extends DockingAction {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Program getProgram(ActionContext context) {
|
||||||
|
Object contextObject = context.getContextObject();
|
||||||
|
if (MarkerLocation.class.isAssignableFrom(contextObject.getClass())) {
|
||||||
|
return ((MarkerLocation) contextObject).getProgram();
|
||||||
|
}
|
||||||
|
else if (context instanceof ListingActionContext) {
|
||||||
|
return ((ListingActionContext) context).getProgram();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,8 +186,7 @@ public class BookmarkPlugin extends ProgramPlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get rid of any resources this plugin is using
|
* Get rid of any resources this plugin is using before the plugin is destroyed.
|
||||||
* before the plugin is destroyed.
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public synchronized void dispose() {
|
public synchronized void dispose() {
|
||||||
|
@ -276,6 +275,7 @@ public class BookmarkPlugin extends ProgramPlugin
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get or create a bookmark navigator for the specified bookmark type
|
* Get or create a bookmark navigator for the specified bookmark type
|
||||||
|
*
|
||||||
* @param type the bookmark type
|
* @param type the bookmark type
|
||||||
* @return bookmark navigator
|
* @return bookmark navigator
|
||||||
*/
|
*/
|
||||||
|
@ -432,9 +432,12 @@ public class BookmarkPlugin extends ProgramPlugin
|
||||||
bookmarkMgr = program.getBookmarkManager();
|
bookmarkMgr = program.getBookmarkManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
void showAddBookmarkDialog(Address location) {
|
void showAddBookmarkDialog(Address address, Program program) {
|
||||||
|
if (program != currentProgram) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Listing listing = currentProgram.getListing();
|
Listing listing = currentProgram.getListing();
|
||||||
CodeUnit currCU = listing.getCodeUnitContaining(location);
|
CodeUnit currCU = listing.getCodeUnitContaining(address);
|
||||||
if (currCU == null) {
|
if (currCU == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -446,8 +449,8 @@ public class BookmarkPlugin extends ProgramPlugin
|
||||||
/**
|
/**
|
||||||
* Called when a new bookmark is to be added; called from the add bookmark dialog
|
* Called when a new bookmark is to be added; called from the add bookmark dialog
|
||||||
*
|
*
|
||||||
* @param addr bookmark address. If null a Note bookmark will set at the
|
* @param addr bookmark address. If null a Note bookmark will set at the start address of each
|
||||||
* start address of each range in the current selection
|
* range in the current selection
|
||||||
* @param category bookmark category
|
* @param category bookmark category
|
||||||
* @param comment comment text
|
* @param comment comment text
|
||||||
*/
|
*/
|
||||||
|
@ -494,6 +497,9 @@ public class BookmarkPlugin extends ProgramPlugin
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
MarkerLocation loc = (MarkerLocation) contextObject;
|
MarkerLocation loc = (MarkerLocation) contextObject;
|
||||||
|
if (loc.getProgram() != currentProgram) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
BookmarkManager mgr = currentProgram.getBookmarkManager();
|
BookmarkManager mgr = currentProgram.getBookmarkManager();
|
||||||
Address address = loc.getAddr();
|
Address address = loc.getAddr();
|
||||||
Bookmark[] bookmarks = mgr.getBookmarks(address);
|
Bookmark[] bookmarks = mgr.getBookmarks(address);
|
||||||
|
@ -518,12 +524,13 @@ public class BookmarkPlugin extends ProgramPlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of actions to delete bookmarks that are in the code unit surrounding the
|
* Returns a list of actions to delete bookmarks that are in the code unit surrounding the given
|
||||||
* given address. The list of actions will not exceed <tt>maxActionsCount</tt>
|
* address. The list of actions will not exceed <tt>maxActionsCount</tt>
|
||||||
* @param primaryAddress The address required to find the containing code unit.
|
*
|
||||||
* @param maxActionsCount The maximum number of actions to include in the returned list.
|
* @param primaryAddress The address required to find the containing code unit.
|
||||||
* @return a list of actions to delete bookmarks that are in the code unit surrounding the
|
* @param maxActionsCount The maximum number of actions to include in the returned list.
|
||||||
* given address.
|
* @return a list of actions to delete bookmarks that are in the code unit surrounding the given
|
||||||
|
* address.
|
||||||
*/
|
*/
|
||||||
private List<DockingActionIf> getActionsForCodeUnit(Address primaryAddress,
|
private List<DockingActionIf> getActionsForCodeUnit(Address primaryAddress,
|
||||||
int maxActionsCount) {
|
int maxActionsCount) {
|
||||||
|
@ -543,14 +550,15 @@ public class BookmarkPlugin extends ProgramPlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of actions to delete bookmarks that are in the code unit surrounding the
|
* Returns a list of actions to delete bookmarks that are in the code unit surrounding the given
|
||||||
* given address <b>for the given <i>type</i> of bookmark</b>.
|
* address <b>for the given <i>type</i> of bookmark</b>.
|
||||||
|
*
|
||||||
* @param primaryAddress The address required to find the containing code unit.
|
* @param primaryAddress The address required to find the containing code unit.
|
||||||
* @param type The bookmark type to retrieve.
|
* @param type The bookmark type to retrieve.
|
||||||
* @param navigator The BookmarkNavigator used to determine whether there are bookmarks
|
* @param navigator The BookmarkNavigator used to determine whether there are bookmarks inside
|
||||||
* inside the code unit containing the given <tt>primaryAddress</tt>.
|
* the code unit containing the given <tt>primaryAddress</tt>.
|
||||||
* @return a list of actions to delete bookmarks that are in the code unit surrounding the
|
* @return a list of actions to delete bookmarks that are in the code unit surrounding the given
|
||||||
* given address <b>for the given <i>type</i> of bookmark</b>.
|
* address <b>for the given <i>type</i> of bookmark</b>.
|
||||||
*/
|
*/
|
||||||
private List<DockingActionIf> getActionsForCodeUnitAndType(Address primaryAddress, String type,
|
private List<DockingActionIf> getActionsForCodeUnitAndType(Address primaryAddress, String type,
|
||||||
BookmarkNavigator navigator) {
|
BookmarkNavigator navigator) {
|
||||||
|
@ -585,9 +593,10 @@ public class BookmarkPlugin extends ProgramPlugin
|
||||||
/**
|
/**
|
||||||
* Adds the actions in <tt>newActionList</tt> to <tt>actionList</tt> while the size of
|
* Adds the actions in <tt>newActionList</tt> to <tt>actionList</tt> while the size of
|
||||||
* <tt>actionList</tt> is less than the given {@link #MAX_DELETE_ACTIONS}.
|
* <tt>actionList</tt> is less than the given {@link #MAX_DELETE_ACTIONS}.
|
||||||
|
*
|
||||||
* @param actionList The list to add to
|
* @param actionList The list to add to
|
||||||
* @param newActionList The list containing items to add
|
* @param newActionList The list containing items to add
|
||||||
* @param maxActionCount the maximum number of items that the actionList can contain
|
* @param maxActionCount the maximum number of items that the actionList can contain
|
||||||
*/
|
*/
|
||||||
private void addActionsToList(List<DockingActionIf> actionList,
|
private void addActionsToList(List<DockingActionIf> actionList,
|
||||||
List<DockingActionIf> newActionList, int maxActionCount) {
|
List<DockingActionIf> newActionList, int maxActionCount) {
|
||||||
|
|
|
@ -16,8 +16,6 @@
|
||||||
package ghidra.app.plugin.core.codebrowser;
|
package ghidra.app.plugin.core.codebrowser;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.event.MouseAdapter;
|
|
||||||
import java.awt.event.MouseEvent;
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -84,7 +82,6 @@ public abstract class AbstractCodeBrowserPlugin<P extends CodeViewerProvider> ex
|
||||||
private MarkerSet currentHighlightMarkers;
|
private MarkerSet currentHighlightMarkers;
|
||||||
private MarkerSet currentCursorMarkers;
|
private MarkerSet currentCursorMarkers;
|
||||||
private ChangeListener markerChangeListener;
|
private ChangeListener markerChangeListener;
|
||||||
private FocusingMouseListener focusingMouseListener = new FocusingMouseListener();
|
|
||||||
|
|
||||||
private Color cursorHighlightColor;
|
private Color cursorHighlightColor;
|
||||||
private boolean isHighlightCursorLine;
|
private boolean isHighlightCursorLine;
|
||||||
|
@ -269,36 +266,22 @@ public abstract class AbstractCodeBrowserPlugin<P extends CodeViewerProvider> ex
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addOverviewProvider(OverviewProvider overviewProvider) {
|
public void addOverviewProvider(OverviewProvider overviewProvider) {
|
||||||
JComponent component = overviewProvider.getComponent();
|
connectedProvider.addOverviewProvider(overviewProvider);
|
||||||
|
|
||||||
// just in case we get repeated calls
|
|
||||||
component.removeMouseListener(focusingMouseListener);
|
|
||||||
component.addMouseListener(focusingMouseListener);
|
|
||||||
connectedProvider.getListingPanel().addOverviewProvider(overviewProvider);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addMarginProvider(MarginProvider marginProvider) {
|
public void addMarginProvider(MarginProvider marginProvider) {
|
||||||
JComponent component = marginProvider.getComponent();
|
connectedProvider.addMarginProvider(marginProvider);
|
||||||
|
|
||||||
// just in case we get repeated calls
|
|
||||||
component.removeMouseListener(focusingMouseListener);
|
|
||||||
component.addMouseListener(focusingMouseListener);
|
|
||||||
connectedProvider.getListingPanel().addMarginProvider(marginProvider);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeOverviewProvider(OverviewProvider overviewProvider) {
|
public void removeOverviewProvider(OverviewProvider overviewProvider) {
|
||||||
JComponent component = overviewProvider.getComponent();
|
connectedProvider.removeOverviewProvider(overviewProvider);
|
||||||
component.removeMouseListener(focusingMouseListener);
|
|
||||||
connectedProvider.getListingPanel().removeOverviewProvider(overviewProvider);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeMarginProvider(MarginProvider marginProvider) {
|
public void removeMarginProvider(MarginProvider marginProvider) {
|
||||||
JComponent component = marginProvider.getComponent();
|
connectedProvider.removeMarginProvider(marginProvider);
|
||||||
component.removeMouseListener(focusingMouseListener);
|
|
||||||
connectedProvider.getListingPanel().removeMarginProvider(marginProvider);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -927,12 +910,4 @@ public abstract class AbstractCodeBrowserPlugin<P extends CodeViewerProvider> ex
|
||||||
fieldPanel.repaint();
|
fieldPanel.repaint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class FocusingMouseListener extends MouseAdapter {
|
|
||||||
@Override
|
|
||||||
public void mousePressed(MouseEvent e) {
|
|
||||||
connectedProvider.getListingPanel().getFieldPanel().requestFocus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.awt.Point;
|
||||||
import java.awt.datatransfer.DataFlavor;
|
import java.awt.datatransfer.DataFlavor;
|
||||||
import java.awt.datatransfer.Transferable;
|
import java.awt.datatransfer.Transferable;
|
||||||
import java.awt.dnd.*;
|
import java.awt.dnd.*;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
@ -100,6 +101,8 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
|
||||||
private FormatManager formatMgr;
|
private FormatManager formatMgr;
|
||||||
private FieldPanelCoordinator coordinator;
|
private FieldPanelCoordinator coordinator;
|
||||||
|
|
||||||
|
private FocusingMouseListener focusingMouseListener;
|
||||||
|
|
||||||
private CodeBrowserClipboardProvider codeViewerClipboardProvider;
|
private CodeBrowserClipboardProvider codeViewerClipboardProvider;
|
||||||
private ClipboardService clipboardService;
|
private ClipboardService clipboardService;
|
||||||
|
|
||||||
|
@ -1011,6 +1014,45 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
|
||||||
listingPanel.removeDisplayListener(listener);
|
listingPanel.removeDisplayListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private synchronized void createFocusingMouseListener() {
|
||||||
|
if (focusingMouseListener == null) {
|
||||||
|
focusingMouseListener = new FocusingMouseListener();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addOverviewProvider(OverviewProvider overviewProvider) {
|
||||||
|
createFocusingMouseListener();
|
||||||
|
JComponent component = overviewProvider.getComponent();
|
||||||
|
|
||||||
|
// just in case we get repeated calls
|
||||||
|
component.removeMouseListener(focusingMouseListener);
|
||||||
|
component.addMouseListener(focusingMouseListener);
|
||||||
|
overviewProvider.setNavigatable(this);
|
||||||
|
getListingPanel().addOverviewProvider(overviewProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMarginProvider(MarginProvider marginProvider) {
|
||||||
|
createFocusingMouseListener();
|
||||||
|
JComponent component = marginProvider.getComponent();
|
||||||
|
|
||||||
|
// just in case we get repeated calls
|
||||||
|
component.removeMouseListener(focusingMouseListener);
|
||||||
|
component.addMouseListener(focusingMouseListener);
|
||||||
|
getListingPanel().addMarginProvider(marginProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeOverviewProvider(OverviewProvider overviewProvider) {
|
||||||
|
JComponent component = overviewProvider.getComponent();
|
||||||
|
component.removeMouseListener(focusingMouseListener);
|
||||||
|
getListingPanel().removeOverviewProvider(overviewProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeMarginProvider(MarginProvider marginProvider) {
|
||||||
|
JComponent component = marginProvider.getComponent();
|
||||||
|
component.removeMouseListener(focusingMouseListener);
|
||||||
|
getListingPanel().removeMarginProvider(marginProvider);
|
||||||
|
}
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
// Inner Classes
|
// Inner Classes
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
|
@ -1092,4 +1134,11 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
|
||||||
return list.toArray(new Highlight[list.size()]);
|
return list.toArray(new Highlight[list.size()]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class FocusingMouseListener extends MouseAdapter {
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
getListingPanel().getFieldPanel().requestFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,10 +52,7 @@ public class MarkerServiceBackgroundColorModel implements ListingBackgroundColor
|
||||||
Address addr = indexMap.getAddress(index);
|
Address addr = indexMap.getAddress(index);
|
||||||
Color color = null;
|
Color color = null;
|
||||||
if (addr != null) {
|
if (addr != null) {
|
||||||
if (program == null) {
|
if (program != null) {
|
||||||
color = markerService.getBackgroundColor(addr);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
color = markerService.getBackgroundColor(program, addr);
|
color = markerService.getBackgroundColor(program, addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ import ghidra.app.plugin.PluginCategoryNames;
|
||||||
import ghidra.app.services.CodeViewerService;
|
import ghidra.app.services.CodeViewerService;
|
||||||
import ghidra.app.util.viewer.listingpanel.*;
|
import ghidra.app.util.viewer.listingpanel.*;
|
||||||
import ghidra.app.util.viewer.options.OptionsGui;
|
import ghidra.app.util.viewer.options.OptionsGui;
|
||||||
|
import ghidra.app.util.viewer.util.AddressIndexMap;
|
||||||
import ghidra.framework.options.OptionsChangeListener;
|
import ghidra.framework.options.OptionsChangeListener;
|
||||||
import ghidra.framework.options.ToolOptions;
|
import ghidra.framework.options.ToolOptions;
|
||||||
import ghidra.framework.plugintool.*;
|
import ghidra.framework.plugintool.*;
|
||||||
|
@ -138,7 +139,8 @@ public class FlowArrowPlugin extends Plugin implements MarginProvider, OptionsCh
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setPixelMap(VerticalPixelAddressMap pixmap) {
|
public void setProgram(Program program, AddressIndexMap addrMap,
|
||||||
|
VerticalPixelAddressMap pixmap) {
|
||||||
this.layoutToPixel = pixmap;
|
this.layoutToPixel = pixmap;
|
||||||
validateState();
|
validateState();
|
||||||
updateFlowArrows();
|
updateFlowArrows();
|
||||||
|
@ -334,9 +336,10 @@ public class FlowArrowPlugin extends Plugin implements MarginProvider, OptionsCh
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Iterate over each other FlowArrow object to check overlaps
|
* Iterate over each other FlowArrow object to check overlaps
|
||||||
* @return FlowArrow objects that have a start/end address in common
|
*
|
||||||
|
* @return FlowArrow objects that have a start/end address in common
|
||||||
*/
|
*/
|
||||||
private List<FlowArrow> getArrowsAtSameDepth(FlowArrow jump, List<FlowArrow> allArrows) {
|
private List<FlowArrow> getArrowsAtSameDepth(FlowArrow jump, List<FlowArrow> allArrows) {
|
||||||
|
|
||||||
|
@ -430,8 +433,9 @@ public class FlowArrowPlugin extends Plugin implements MarginProvider, OptionsCh
|
||||||
|
|
||||||
List<FlowArrow> results = new ArrayList<>();
|
List<FlowArrow> results = new ArrayList<>();
|
||||||
ArrowCache arrowCache = new ArrowCache();
|
ArrowCache arrowCache = new ArrowCache();
|
||||||
CodeUnitIterator it = program.getListing().getCodeUnitIterator(
|
CodeUnitIterator it = program.getListing()
|
||||||
CodeUnit.INSTRUCTION_PROPERTY, screenAddresses, true);
|
.getCodeUnitIterator(
|
||||||
|
CodeUnit.INSTRUCTION_PROPERTY, screenAddresses, true);
|
||||||
|
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
CodeUnit cu = it.next();
|
CodeUnit cu = it.next();
|
||||||
|
@ -479,14 +483,12 @@ public class FlowArrowPlugin extends Plugin implements MarginProvider, OptionsCh
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unusual Code: We keep arrows in 3 sets: all arrows, selected arrows, and active arrows.
|
* Unusual Code: We keep arrows in 3 sets: all arrows, selected arrows, and active arrows.
|
||||||
* Further, we rebuild arrows as the screen moves, causing the x coordinate
|
* Further, we rebuild arrows as the screen moves, causing the x coordinate to change as arrows
|
||||||
* to change as arrows that are no longer on the screen are removed and
|
* that are no longer on the screen are removed and as new arrows are added. We want to make
|
||||||
* as new arrows are added. We want to make sure that we don't end up
|
* sure that we don't end up with an arrow in the selected/active sets that are the same as the
|
||||||
* with an arrow in the selected/active sets that are the same as the one
|
* one in the 'all' set, but with a different width. This causes both arrows to become
|
||||||
* in the 'all' set, but with a different width. This causes both arrows
|
* visible--basically, the selected arrows can become stale as their width changes. This code is
|
||||||
* to become visible--basically, the selected arrows can become stale as
|
* meant to address this out-of-sync behavior.
|
||||||
* their width changes. This code is meant to address this out-of-sync
|
|
||||||
* behavior.
|
|
||||||
*
|
*
|
||||||
* @param arrow the updated form of the arrow
|
* @param arrow the updated form of the arrow
|
||||||
*/
|
*/
|
||||||
|
@ -543,7 +545,8 @@ public class FlowArrowPlugin extends Plugin implements MarginProvider, OptionsCh
|
||||||
Address bottomAddr = layoutToPixel.getLayoutAddress(n - 1);
|
Address bottomAddr = layoutToPixel.getLayoutAddress(n - 1);
|
||||||
if (bottomAddr != null) {
|
if (bottomAddr != null) {
|
||||||
AddressSpace testSpace = bottomAddr.getAddressSpace();
|
AddressSpace testSpace = bottomAddr.getAddressSpace();
|
||||||
validState = (program.getAddressFactory().getAddressSpace(
|
validState = (program.getAddressFactory()
|
||||||
|
.getAddressSpace(
|
||||||
testSpace.getSpaceID()) == testSpace);
|
testSpace.getSpaceID()) == testSpace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -17,46 +17,37 @@ package ghidra.app.plugin.core.marker;
|
||||||
|
|
||||||
import ghidra.GhidraOptions;
|
import ghidra.GhidraOptions;
|
||||||
import ghidra.app.CorePluginPackage;
|
import ghidra.app.CorePluginPackage;
|
||||||
import ghidra.app.events.ProgramActivatedPluginEvent;
|
|
||||||
import ghidra.app.events.ProgramClosedPluginEvent;
|
|
||||||
import ghidra.app.plugin.PluginCategoryNames;
|
import ghidra.app.plugin.PluginCategoryNames;
|
||||||
import ghidra.app.services.*;
|
import ghidra.app.services.*;
|
||||||
import ghidra.app.util.HelpTopics;
|
import ghidra.app.util.HelpTopics;
|
||||||
import ghidra.framework.options.Options;
|
import ghidra.framework.options.Options;
|
||||||
import ghidra.framework.plugintool.*;
|
import ghidra.framework.plugintool.*;
|
||||||
import ghidra.framework.plugintool.util.PluginStatus;
|
import ghidra.framework.plugintool.util.PluginStatus;
|
||||||
import ghidra.program.model.listing.Program;
|
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plugin to manage marker and navigation panels.
|
* Plugin to manage marker and navigation panels.
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
//@formatter:off
|
|
||||||
@PluginInfo(
|
@PluginInfo(
|
||||||
status = PluginStatus.RELEASED,
|
status = PluginStatus.RELEASED,
|
||||||
packageName = CorePluginPackage.NAME,
|
packageName = CorePluginPackage.NAME,
|
||||||
category = PluginCategoryNames.SUPPORT,
|
category = PluginCategoryNames.SUPPORT,
|
||||||
shortDescription = "Provides the marker display",
|
shortDescription = "Provides the marker display",
|
||||||
description = "This plugin extends the code browser to include left and right marker"
|
description = "This plugin extends the code browser to include left and right marker" +
|
||||||
+ "components. The left margin shows marks related to the address being shown at "
|
"components. The left margin shows marks related to the address being shown at " +
|
||||||
+ "that location. The right margin shows marks at a position that is relative to "
|
"that location. The right margin shows marks at a position that is relative to " +
|
||||||
+ "an addresses within the overall program (Overview). This plugin also provides "
|
"an addresses within the overall program (Overview). This plugin also provides " +
|
||||||
+ "a service that other plugins can use to display markers. Two types of markers are "
|
"a service that other plugins can use to display markers. Two types of markers are " +
|
||||||
+ "supported; point markers and area markers. Area markers are used to indicate a range "
|
"supported; point markers and area markers. Area markers are used to indicate a range " +
|
||||||
+ "value such as selection. Point markers are used to represent individual addresses such "
|
"value such as selection. Point markers are used to represent individual addresses such " +
|
||||||
+ "as bookmarks.",
|
"as bookmarks.",
|
||||||
servicesRequired = { CodeViewerService.class, GoToService.class },
|
servicesRequired = { CodeViewerService.class, GoToService.class },
|
||||||
servicesProvided = { MarkerService.class },
|
servicesProvided = { MarkerService.class },
|
||||||
eventsConsumed = { ProgramActivatedPluginEvent.class, ProgramClosedPluginEvent.class }
|
eventsConsumed = {})
|
||||||
)
|
|
||||||
//@formatter:on
|
|
||||||
public class MarkerManagerPlugin extends Plugin {
|
public class MarkerManagerPlugin extends Plugin {
|
||||||
|
|
||||||
private CodeViewerService codeViewerService;
|
private CodeViewerService codeViewerService;
|
||||||
private MarkerManager markerManager;
|
private MarkerManager markerManager;
|
||||||
private Program program;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param tool
|
* @param tool
|
||||||
|
@ -87,23 +78,4 @@ public class MarkerManagerPlugin extends Plugin {
|
||||||
codeViewerService.addMarginProvider(markerManager.getMarginProvider());
|
codeViewerService.addMarginProvider(markerManager.getMarginProvider());
|
||||||
codeViewerService.addOverviewProvider(markerManager.getOverviewProvider());
|
codeViewerService.addOverviewProvider(markerManager.getOverviewProvider());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void processEvent(PluginEvent event) {
|
|
||||||
if (event instanceof ProgramActivatedPluginEvent) {
|
|
||||||
ProgramActivatedPluginEvent ev = (ProgramActivatedPluginEvent) event;
|
|
||||||
Program oldProgram = program;
|
|
||||||
program = ev.getActiveProgram();
|
|
||||||
if (oldProgram != null) {
|
|
||||||
markerManager.setProgram(null);
|
|
||||||
}
|
|
||||||
if (program != null) {
|
|
||||||
markerManager.setProgram(program);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (event instanceof ProgramClosedPluginEvent) {
|
|
||||||
markerManager.programClosed(((ProgramClosedPluginEvent) event).getProgram());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package ghidra.app.plugin.core.marker;
|
||||||
|
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
|
||||||
|
import docking.widgets.fieldpanel.FieldPanel;
|
||||||
|
import ghidra.app.services.MarkerService;
|
||||||
|
import ghidra.app.services.MarkerSet;
|
||||||
|
import ghidra.app.util.viewer.listingpanel.*;
|
||||||
|
import ghidra.app.util.viewer.util.AddressIndexMap;
|
||||||
|
import ghidra.program.model.address.Address;
|
||||||
|
import ghidra.program.model.listing.Program;
|
||||||
|
import ghidra.program.util.MarkerLocation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The provider which renders the marker margin, usually placed to the left of listing
|
||||||
|
* {@link FieldPanel}s.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* These are managed by a {@link MarkerManager}. Obtain one via
|
||||||
|
* {@link MarkerService#createMarginProvider()}.
|
||||||
|
*/
|
||||||
|
public class MarkerMarginProvider implements MarginProvider {
|
||||||
|
private final MarkerManager markerManager;
|
||||||
|
private final MarkerPanel markerPanel;
|
||||||
|
|
||||||
|
private Program program;
|
||||||
|
private VerticalPixelAddressMap pixmap;
|
||||||
|
|
||||||
|
MarkerMarginProvider(MarkerManager markerManager) {
|
||||||
|
this.markerManager = markerManager;
|
||||||
|
this.markerPanel = new MarkerPanel(markerManager);
|
||||||
|
|
||||||
|
this.markerPanel.addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mouseClicked(MouseEvent e) {
|
||||||
|
MarkerClickedListener markerClickedListener =
|
||||||
|
markerManager.getMarkerClickedListener();
|
||||||
|
if (e.getClickCount() != 2 || markerClickedListener == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MarkerLocation location = getMarkerLocation(e.getX(), e.getY());
|
||||||
|
markerClickedListener.markerDoubleClicked(location);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void repaintPanel() {
|
||||||
|
markerPanel.repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JComponent getComponent() {
|
||||||
|
return markerPanel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Address getAddress(int y) {
|
||||||
|
if (pixmap == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int i = pixmap.findLayoutAt(y);
|
||||||
|
return pixmap.getLayoutAddress(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MarkerLocation getMarkerLocation(int x, int y) {
|
||||||
|
Address addr = getAddress(y);
|
||||||
|
if (addr == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
MarkerSet marker = markerManager.getMarkerSet(program, addr);
|
||||||
|
return new MarkerLocation(marker, program, addr, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isResizeable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProgram(Program program, AddressIndexMap addrMap,
|
||||||
|
VerticalPixelAddressMap pixmap) {
|
||||||
|
this.program = program;
|
||||||
|
this.pixmap = pixmap;
|
||||||
|
|
||||||
|
this.markerPanel.setProgram(program, addrMap, pixmap);
|
||||||
|
|
||||||
|
markerManager.updateMarkerSets(program, true, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*testing*/ String generateToolTip(MouseEvent event) {
|
||||||
|
return markerPanel.generateToolTip(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,346 @@
|
||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package ghidra.app.plugin.core.marker;
|
||||||
|
|
||||||
|
import java.awt.event.ComponentAdapter;
|
||||||
|
import java.awt.event.ComponentEvent;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
|
||||||
|
import docking.ActionContext;
|
||||||
|
import docking.action.*;
|
||||||
|
import docking.widgets.fieldpanel.FieldPanel;
|
||||||
|
import ghidra.GhidraOptions;
|
||||||
|
import ghidra.app.nav.Navigatable;
|
||||||
|
import ghidra.app.services.MarkerService;
|
||||||
|
import ghidra.app.util.HelpTopics;
|
||||||
|
import ghidra.app.util.viewer.listingpanel.OverviewProvider;
|
||||||
|
import ghidra.app.util.viewer.util.AddressIndexMap;
|
||||||
|
import ghidra.framework.options.*;
|
||||||
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
|
import ghidra.program.model.listing.Program;
|
||||||
|
import ghidra.util.HelpLocation;
|
||||||
|
import ghidra.util.Swing;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The provider which renders the overview margin, usually placed outside the scrollbar to the right
|
||||||
|
* of lisitng {@link FieldPanel}s.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* These are managed by a {@link MarkerManager}. Obtain one via
|
||||||
|
* {@link MarkerService#createOverviewProvider()}.
|
||||||
|
*/
|
||||||
|
public class MarkerOverviewProvider implements OverviewProvider {
|
||||||
|
private final PluginTool tool;
|
||||||
|
private final String owner;
|
||||||
|
|
||||||
|
private final MarkerManager markerManager;
|
||||||
|
private final NavigationPanel navigationPanel;
|
||||||
|
|
||||||
|
private final MarkerActionList actionList;
|
||||||
|
|
||||||
|
private Program program;
|
||||||
|
|
||||||
|
MarkerOverviewProvider(String owner, PluginTool tool, MarkerManager markerManager) {
|
||||||
|
this.tool = tool;
|
||||||
|
this.owner = owner;
|
||||||
|
|
||||||
|
this.markerManager = markerManager;
|
||||||
|
this.navigationPanel = new NavigationPanel(markerManager);
|
||||||
|
|
||||||
|
this.navigationPanel.addComponentListener(new ComponentAdapter() {
|
||||||
|
@Override
|
||||||
|
public void componentResized(ComponentEvent e) {
|
||||||
|
markerManager.updateMarkerSets(program, false, true, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
actionList = new MarkerActionList();
|
||||||
|
}
|
||||||
|
|
||||||
|
void dispose() {
|
||||||
|
actionList.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void repaintPanel() {
|
||||||
|
navigationPanel.repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JComponent getComponent() {
|
||||||
|
return navigationPanel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProgram(Program program, AddressIndexMap map) {
|
||||||
|
this.program = program;
|
||||||
|
|
||||||
|
navigationPanel.setProgram(program, map);
|
||||||
|
markerManager.updateMarkerSets(program, true, true, false);
|
||||||
|
actionList.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNavigatable(Navigatable navigatable) {
|
||||||
|
navigationPanel.setNavigatable(navigatable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void refreshActionList(Program p) {
|
||||||
|
if (this.program != p) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
actionList.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================================================
|
||||||
|
// Inner Classes
|
||||||
|
//==================================================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marker Option Menu - controls the visibility of the various markers.
|
||||||
|
*/
|
||||||
|
private class MarkerActionList implements OptionsChangeListener {
|
||||||
|
|
||||||
|
private final List<DockingAction> actions = new ArrayList<>();
|
||||||
|
private ToolOptions listOptions;
|
||||||
|
|
||||||
|
MarkerActionList() {
|
||||||
|
initOptions();
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initOptions() {
|
||||||
|
listOptions = tool.getOptions(GhidraOptions.CATEGORY_BROWSER_NAVIGATION_MARKERS);
|
||||||
|
listOptions.removeOptionsChangeListener(this);
|
||||||
|
listOptions.addOptionsChangeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void optionsChanged(ToolOptions options, String name, Object oldValue,
|
||||||
|
Object newValue) {
|
||||||
|
for (DockingAction action : actions) {
|
||||||
|
if (action instanceof ActivateMarkerAction) {
|
||||||
|
((ActivateMarkerAction) action).optionsChanged();
|
||||||
|
}
|
||||||
|
if (action instanceof ActivateMarkerGroupAction) {
|
||||||
|
((ActivateMarkerGroupAction) action).optionsChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void refresh() {
|
||||||
|
Swing.runLater(this::doRefresh);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doRefresh() {
|
||||||
|
if (program == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (DockingAction action : actions) {
|
||||||
|
tool.removeAction(action);
|
||||||
|
}
|
||||||
|
actions.clear();
|
||||||
|
|
||||||
|
List<MarkerSetImpl> list = markerManager.copyMarkerSets(program);
|
||||||
|
|
||||||
|
// separate the marker sets into grouped and non-grouped
|
||||||
|
List<List<MarkerSetImpl>> groupsList = extractManagerGroups(list);
|
||||||
|
Collections.sort(groupsList,
|
||||||
|
(ms1, ms2) -> ms1.get(0).getName().compareTo(ms2.get(0).getName()));
|
||||||
|
for (List<MarkerSetImpl> group : groupsList) {
|
||||||
|
ActivateMarkerGroupAction action =
|
||||||
|
new ActivateMarkerGroupAction(owner, group, navigationPanel, listOptions);
|
||||||
|
actions.add(action);
|
||||||
|
tool.addAction(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
Collections.sort(list, (ms1, ms2) -> ms1.getName().compareTo(ms2.getName()));
|
||||||
|
for (MarkerSetImpl mgr : list) {
|
||||||
|
ActivateMarkerAction action =
|
||||||
|
new ActivateMarkerAction(owner, mgr, navigationPanel, listOptions);
|
||||||
|
actions.add(action);
|
||||||
|
tool.addAction(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
navigationPanel.repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a list of elements that are in the same logical group and removes those elements
|
||||||
|
* from the given list.
|
||||||
|
*/
|
||||||
|
private List<List<MarkerSetImpl>> extractManagerGroups(List<MarkerSetImpl> fromList) {
|
||||||
|
// empty the original list for grouping...
|
||||||
|
Map<String, List<MarkerSetImpl>> nameToManagerMap = new HashMap<>();
|
||||||
|
for (Iterator<MarkerSetImpl> iterator = fromList.iterator(); iterator.hasNext();) {
|
||||||
|
MarkerSetImpl markerSetImpl = iterator.next();
|
||||||
|
String name = markerSetImpl.getName();
|
||||||
|
List<MarkerSetImpl> subList = nameToManagerMap.get(name);
|
||||||
|
if (subList == null) {
|
||||||
|
subList = new ArrayList<>();
|
||||||
|
nameToManagerMap.put(name, subList);
|
||||||
|
}
|
||||||
|
subList.add(markerSetImpl);
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...now repopulate the original list with all non-group managers and put the groups
|
||||||
|
// in their own list
|
||||||
|
List<List<MarkerSetImpl>> groupList = new ArrayList<>(fromList.size());
|
||||||
|
Set<Entry<String, List<MarkerSetImpl>>> entrySet = nameToManagerMap.entrySet();
|
||||||
|
for (Entry<String, List<MarkerSetImpl>> entry : entrySet) {
|
||||||
|
List<MarkerSetImpl> listValue = entry.getValue();
|
||||||
|
|
||||||
|
// non-group list
|
||||||
|
if (listValue.size() == 1) {
|
||||||
|
fromList.add(listValue.get(0));
|
||||||
|
}
|
||||||
|
// group list
|
||||||
|
else {
|
||||||
|
groupList.add(listValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return groupList;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dispose() {
|
||||||
|
listOptions.removeOptionsChangeListener(this);
|
||||||
|
|
||||||
|
actions.forEach(a -> tool.removeAction(a));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ActivateMarkerAction extends ToggleDockingAction {
|
||||||
|
|
||||||
|
private MarkerSetImpl markers;
|
||||||
|
private NavigationPanel panel;
|
||||||
|
private Options options;
|
||||||
|
|
||||||
|
ActivateMarkerAction(String owner, MarkerSetImpl markers, NavigationPanel panel,
|
||||||
|
Options options) {
|
||||||
|
super(markers.getName(), owner);
|
||||||
|
this.markers = markers;
|
||||||
|
this.panel = panel;
|
||||||
|
this.options = options;
|
||||||
|
HelpLocation helpLocation = new HelpLocation(HelpTopics.CODE_BROWSER, "Markers");
|
||||||
|
options.registerOption(markers.getName(), true, helpLocation,
|
||||||
|
"This options enables/disables the display of " + markers.getName() +
|
||||||
|
" marker types.");
|
||||||
|
|
||||||
|
setEnabled(true);
|
||||||
|
setSelected(markers.active);
|
||||||
|
setPopupMenuData(
|
||||||
|
new MenuData(new String[] { markers.getName() }, markers.getNavIcon(), null));
|
||||||
|
|
||||||
|
boolean isEnabled = isOptionEnabled();
|
||||||
|
setSelected(isEnabled);
|
||||||
|
markers.setActive(isEnabled);
|
||||||
|
HelpLocation location = new HelpLocation(HelpTopics.CODE_BROWSER, "Markers");
|
||||||
|
setHelpLocation(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabledForContext(ActionContext context) {
|
||||||
|
Object contextObject = context.getContextObject();
|
||||||
|
return contextObject == panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void optionsChanged() {
|
||||||
|
boolean selected = isOptionEnabled();
|
||||||
|
if (selected != isSelected()) {
|
||||||
|
setSelected(selected);
|
||||||
|
markers.setActive(selected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isOptionEnabled() {
|
||||||
|
return options.getBoolean(markers.getName(), true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionContext context) {
|
||||||
|
options.setBoolean(markers.getName(), isSelected());
|
||||||
|
markers.setActive(isSelected());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ActivateMarkerGroupAction extends ToggleDockingAction {
|
||||||
|
private List<MarkerSetImpl> markerSets;
|
||||||
|
private NavigationPanel panel;
|
||||||
|
private Options options;
|
||||||
|
|
||||||
|
ActivateMarkerGroupAction(String owner, List<MarkerSetImpl> managerList,
|
||||||
|
NavigationPanel panel, Options options) {
|
||||||
|
super(managerList.get(0).getName(), owner);
|
||||||
|
this.markerSets = managerList;
|
||||||
|
this.panel = panel;
|
||||||
|
this.options = options;
|
||||||
|
HelpLocation helpLocation = new HelpLocation(HelpTopics.CODE_BROWSER, "Markers");
|
||||||
|
options.registerOption(getName(), true, helpLocation,
|
||||||
|
"This options enables/disables the display of " + getName() + " marker types.");
|
||||||
|
|
||||||
|
setEnabled(true);
|
||||||
|
setSelected(isActive());
|
||||||
|
ImageIcon icon = managerList.get(0).getNavIcon();
|
||||||
|
setPopupMenuData(new MenuData(new String[] { getName() }, icon));
|
||||||
|
boolean isEnabled = isOptionEnabled();
|
||||||
|
setSelected(isEnabled);
|
||||||
|
setActive(isEnabled);
|
||||||
|
setHelpLocation(helpLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setActive(boolean active) {
|
||||||
|
for (MarkerSetImpl manager : markerSets) {
|
||||||
|
manager.setActive(active);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isActive() {
|
||||||
|
return markerSets.stream().anyMatch(markers -> markers.isActive());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabledForContext(ActionContext context) {
|
||||||
|
Object contextObject = context.getContextObject();
|
||||||
|
return contextObject == panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void optionsChanged() {
|
||||||
|
boolean selected = isOptionEnabled();
|
||||||
|
if (selected != isSelected()) {
|
||||||
|
setSelected(selected);
|
||||||
|
setActive(selected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isOptionEnabled() {
|
||||||
|
return options.getBoolean(getName(), true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionContext context) {
|
||||||
|
options.setBoolean(getName(), isSelected());
|
||||||
|
setActive(isSelected());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,36 +15,91 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.marker;
|
package ghidra.app.plugin.core.marker;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.ToolTipManager;
|
import javax.swing.ToolTipManager;
|
||||||
|
|
||||||
|
import docking.widgets.fieldpanel.FieldPanel;
|
||||||
|
import ghidra.app.util.viewer.listingpanel.VerticalPixelAddressMap;
|
||||||
|
import ghidra.app.util.viewer.util.AddressIndexMap;
|
||||||
|
import ghidra.program.model.address.Address;
|
||||||
|
import ghidra.program.model.listing.Program;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Panel to display markers. Normally placed to the left hand side
|
* Panel to display markers. Normally placed to the left hand side of the scrolled
|
||||||
* of the scrolled field panel.
|
* {@link FieldPanel}.
|
||||||
*/
|
*/
|
||||||
public class MarkerPanel extends JPanel {
|
public class MarkerPanel extends JPanel {
|
||||||
|
|
||||||
private MarkerManager manager;
|
private MarkerManager manager;
|
||||||
|
|
||||||
|
private Program program;
|
||||||
|
private AddressIndexMap addrMap;
|
||||||
|
private VerticalPixelAddressMap pixmap;
|
||||||
|
|
||||||
MarkerPanel(MarkerManager manager) {
|
MarkerPanel(MarkerManager manager) {
|
||||||
super();
|
super();
|
||||||
this.manager = manager;
|
this.manager = manager;
|
||||||
|
|
||||||
|
this.setPreferredSize(new Dimension(16, 1));
|
||||||
ToolTipManager.sharedInstance().registerComponent(this);
|
ToolTipManager.sharedInstance().registerComponent(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setProgram(Program program, AddressIndexMap addrMap, VerticalPixelAddressMap pixmap) {
|
||||||
|
this.program = program;
|
||||||
|
this.addrMap = addrMap;
|
||||||
|
this.pixmap = pixmap;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintComponent(Graphics g) {
|
protected void paintComponent(Graphics g) {
|
||||||
super.paintComponent(g);
|
super.paintComponent(g);
|
||||||
|
manager.paintMarkers(program, g, pixmap, addrMap);
|
||||||
manager.paintMarkers(g);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getToolTipText(MouseEvent event) {
|
public String getToolTipText(MouseEvent event) {
|
||||||
return manager.getTooltip(event);
|
String tip = generateToolTip(event);
|
||||||
|
manager.showToolTipPopup(event, tip);
|
||||||
|
return null; // signal not to show a Java tooltip
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String toHTML(List<String> lines) {
|
||||||
|
if (lines.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder buffy = new StringBuilder("<html><font size=\"" + 4 + "\">");
|
||||||
|
for (String string : lines) {
|
||||||
|
buffy.append(string).append("<BR>");
|
||||||
|
}
|
||||||
|
return buffy.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
String generateToolTip(MouseEvent event) {
|
||||||
|
if (pixmap == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int y = event.getY();
|
||||||
|
int x = event.getX();
|
||||||
|
int layoutIndex = pixmap.findLayoutAt(y);
|
||||||
|
Address layoutAddress = pixmap.getLayoutAddress(layoutIndex);
|
||||||
|
if (layoutAddress == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> lines = getMarkerTooltipLines(y, x, layoutIndex, layoutAddress);
|
||||||
|
return toHTML(lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> getMarkerTooltipLines(int y, int x, int layoutIndex,
|
||||||
|
Address layoutAddress) {
|
||||||
|
Address endAddr = pixmap.getLayoutEndAddress(layoutIndex);
|
||||||
|
return manager.getMarkerTooltipLines(program, y, layoutIndex, layoutAddress, endAddr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ import ghidra.util.datastruct.SortedRangeList;
|
||||||
abstract class MarkerSetImpl implements MarkerSet {
|
abstract class MarkerSetImpl implements MarkerSet {
|
||||||
|
|
||||||
protected MarkerManager mgr;
|
protected MarkerManager mgr;
|
||||||
private Program program;
|
protected Program program;
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
protected String description;
|
protected String description;
|
||||||
|
@ -50,6 +50,8 @@ abstract class MarkerSetImpl implements MarkerSet {
|
||||||
|
|
||||||
protected AddressSetCollection markers;
|
protected AddressSetCollection markers;
|
||||||
protected SortedRangeList overview = null;
|
protected SortedRangeList overview = null;
|
||||||
|
|
||||||
|
protected VerticalPixelAddressMap activePixmap = null;
|
||||||
protected List<Integer> activeLayouts = null;
|
protected List<Integer> activeLayouts = null;
|
||||||
|
|
||||||
protected Color markerColor;
|
protected Color markerColor;
|
||||||
|
@ -98,6 +100,7 @@ abstract class MarkerSetImpl implements MarkerSet {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the Navigator Icon for this marker set
|
* Returns the Navigator Icon for this marker set
|
||||||
|
*
|
||||||
* @return the Navigator Icon for this marker set
|
* @return the Navigator Icon for this marker set
|
||||||
*/
|
*/
|
||||||
public abstract ImageIcon getNavIcon();
|
public abstract ImageIcon getNavIcon();
|
||||||
|
@ -248,11 +251,10 @@ abstract class MarkerSetImpl implements MarkerSet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void paintNavigation(Graphics g, int height, NavigationPanel panel,
|
public final void paintNavigation(Graphics g, int height, int width, AddressIndexMap map) {
|
||||||
AddressIndexMap map) {
|
|
||||||
if (showNavigation) {
|
if (showNavigation) {
|
||||||
SortedRangeList newOverview = computeNavigationIndexes(height, map);
|
SortedRangeList newOverview = computeNavigationIndices(height, map);
|
||||||
doPaintNavigation(g, height, panel.getWidth(), newOverview);
|
doPaintNavigation(g, height, width, newOverview);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,7 +295,7 @@ abstract class MarkerSetImpl implements MarkerSet {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeLayouts != null) {
|
if (activeLayouts != null && activePixmap == pixmap) {
|
||||||
return activeLayouts; // use cache
|
return activeLayouts; // use cache
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,19 +313,19 @@ abstract class MarkerSetImpl implements MarkerSet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activePixmap = pixmap;
|
||||||
activeLayouts = newLayouts;
|
activeLayouts = newLayouts;
|
||||||
return newLayouts;
|
return newLayouts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private SortedRangeList computeNavigationIndexes(int height, AddressIndexMap map) {
|
private SortedRangeList computeNavigationIndices(int height, AddressIndexMap map) {
|
||||||
|
|
||||||
lastHeight = height;
|
|
||||||
double numIndexes = map.getIndexCount().doubleValue();
|
double numIndexes = map.getIndexCount().doubleValue();
|
||||||
if (markers.isEmpty() || height == 0 || numIndexes == 0) {
|
if (markers.isEmpty() || height == 0 || numIndexes == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (overview != null) {
|
if (overview != null && lastHeight == height) {
|
||||||
return overview; // use cache
|
return overview; // use cache
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,6 +378,7 @@ abstract class MarkerSetImpl implements MarkerSet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lastHeight = height;
|
||||||
overview = newOverview;
|
overview = newOverview;
|
||||||
return newOverview;
|
return newOverview;
|
||||||
}
|
}
|
||||||
|
@ -391,7 +394,7 @@ abstract class MarkerSetImpl implements MarkerSet {
|
||||||
*/
|
*/
|
||||||
public String getTooltip(Address addr, int x, int y) {
|
public String getTooltip(Address addr, int x, int y) {
|
||||||
if (markerDescriptor != null) {
|
if (markerDescriptor != null) {
|
||||||
MarkerLocation loc = new MarkerLocation(this, mgr.getProgram(), addr, x, y);
|
MarkerLocation loc = new MarkerLocation(this, program, addr, x, y);
|
||||||
return markerDescriptor.getTooltip(loc);
|
return markerDescriptor.getTooltip(loc);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -421,7 +424,10 @@ abstract class MarkerSetImpl implements MarkerSet {
|
||||||
public ProgramLocation getProgramLocation(int y, int height, AddressIndexMap map, int x) {
|
public ProgramLocation getProgramLocation(int y, int height, AddressIndexMap map, int x) {
|
||||||
|
|
||||||
assertSwing();
|
assertSwing();
|
||||||
if (overview == null) {
|
// Many overview panels can be rendering this marker set, each having its own height.
|
||||||
|
// If the height does not match that from the last-computed indices, we need to recompute.
|
||||||
|
computeNavigationIndices(height, map);
|
||||||
|
if (overview == null || lastHeight != height) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,12 +461,12 @@ abstract class MarkerSetImpl implements MarkerSet {
|
||||||
addr = set.getMinAddress();
|
addr = set.getMinAddress();
|
||||||
}
|
}
|
||||||
if (markerDescriptor != null) {
|
if (markerDescriptor != null) {
|
||||||
MarkerLocation ml = new MarkerLocation(this, mgr.getProgram(), addr, x, y);
|
MarkerLocation ml = new MarkerLocation(this, program, addr, x, y);
|
||||||
loc = markerDescriptor.getProgramLocation(ml);
|
loc = markerDescriptor.getProgramLocation(ml);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loc == null) {
|
if (loc == null) {
|
||||||
loc = new ProgramLocation(mgr.getProgram(), addr);
|
loc = new ProgramLocation(program, addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return loc;
|
return loc;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,23 +15,35 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.marker;
|
package ghidra.app.plugin.core.marker;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.event.*;
|
import java.awt.event.*;
|
||||||
|
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
import docking.widgets.fieldpanel.FieldPanel;
|
||||||
|
import ghidra.app.nav.Navigatable;
|
||||||
|
import ghidra.app.util.viewer.util.AddressIndexMap;
|
||||||
|
import ghidra.program.model.listing.Program;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Panel to display an overview of all markers placed within a scrolled
|
* Panel to display an overview of all markers placed within a scrolled {@link FieldPanel}. Normally
|
||||||
* FieldPanel.
|
* placed to the right of the scrolled panel.
|
||||||
* Normally placed to the right of the scrolled panel.
|
|
||||||
*/
|
*/
|
||||||
public class NavigationPanel extends JPanel {
|
public class NavigationPanel extends JPanel {
|
||||||
|
|
||||||
private MarkerManager manager;
|
private MarkerManager manager;
|
||||||
|
|
||||||
|
private Navigatable navigatable;
|
||||||
|
private Program program;
|
||||||
|
private AddressIndexMap addrMap;
|
||||||
|
|
||||||
NavigationPanel(MarkerManager manager) {
|
NavigationPanel(MarkerManager manager) {
|
||||||
super();
|
super();
|
||||||
this.manager = manager;
|
this.manager = manager;
|
||||||
|
|
||||||
|
this.setPreferredSize(new Dimension(16, 1));
|
||||||
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,12 +52,11 @@ public class NavigationPanel extends JPanel {
|
||||||
addMouseListener(new MouseAdapter() {
|
addMouseListener(new MouseAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void mousePressed(MouseEvent e) {
|
public void mousePressed(MouseEvent e) {
|
||||||
|
if ((e.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0) {
|
||||||
if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0) {
|
manager.navigateTo(navigatable, program, e.getX(), e.getY(), getViewHeight(),
|
||||||
manager.navigateTo(e.getX(), e.getY());
|
addrMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +66,23 @@ public class NavigationPanel extends JPanel {
|
||||||
@Override
|
@Override
|
||||||
protected void paintComponent(Graphics g) {
|
protected void paintComponent(Graphics g) {
|
||||||
super.paintComponent(g);
|
super.paintComponent(g);
|
||||||
manager.paintNavigation(g, this);
|
paintNavigation(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void paintNavigation(Graphics g) {
|
||||||
|
manager.paintNavigation(program, g, this, addrMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setNavigatable(Navigatable navigatable) {
|
||||||
|
this.navigatable = navigatable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setProgram(Program program, AddressIndexMap map) {
|
||||||
|
this.program = program;
|
||||||
|
this.addrMap = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getViewHeight() {
|
||||||
|
return getHeight() - MarkerSetImpl.MARKER_HEIGHT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,14 +39,15 @@ class PointMarkerSet extends MarkerSetImpl {
|
||||||
private Color fillColor;
|
private Color fillColor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param navigationManager manager for these point markers
|
* @param navigationManager manager for these point markers
|
||||||
* @param name the name for this point marker
|
* @param name the name for this point marker
|
||||||
* @param desc the description associated with this point marker
|
* @param desc the description associated with this point marker
|
||||||
* @param priority to sort out what displays on top, higher is more likely to be on top
|
* @param priority to sort out what displays on top, higher is more likely to be on top
|
||||||
* @param showMarkers true indicates to show area markers (on the left side of the browser.)
|
* @param showMarkers true indicates to show area markers (on the left side of the browser.)
|
||||||
* @param showNavigation true indicates to show area navigation markers (on the right side of the browser.)
|
* @param showNavigation true indicates to show area navigation markers (on the right side of
|
||||||
* @param colorBackground colorBackground the color of marked areas in navigation bar
|
* the browser.)
|
||||||
* If color is null, no results are displayed in the associated marker bar.
|
* @param colorBackground colorBackground the color of marked areas in navigation bar If color
|
||||||
|
* is null, no results are displayed in the associated marker bar.
|
||||||
* @param markerColor the color of the marker
|
* @param markerColor the color of the marker
|
||||||
* @param icon the icon used to represent the cursor in the marker margin
|
* @param icon the icon used to represent the cursor in the marker margin
|
||||||
* @param isPreferred true indicates higher priority than all non-preferred MarkerSets
|
* @param isPreferred true indicates higher priority than all non-preferred MarkerSets
|
||||||
|
@ -70,14 +71,15 @@ class PointMarkerSet extends MarkerSetImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param navigationManager manager for these point markers
|
* @param navigationManager manager for these point markers
|
||||||
* @param name the name for this point marker
|
* @param name the name for this point marker
|
||||||
* @param desc the description associated with this point marker
|
* @param desc the description associated with this point marker
|
||||||
* @param priority to sort out what displays on top, higher is more likely to be on top
|
* @param priority to sort out what displays on top, higher is more likely to be on top
|
||||||
* @param showMarkers true indicates to show area markers (on the left side of the browser.)
|
* @param showMarkers true indicates to show area markers (on the left side of the browser.)
|
||||||
* @param showNavigation true indicates to show area navigation markers (on the right side of the browser.)
|
* @param showNavigation true indicates to show area navigation markers (on the right side of
|
||||||
* @param colorBackground colorBackground the color of marked areas in navigation bar
|
* the browser.)
|
||||||
* If color is null, no results are displayed in the associated marker bar.
|
* @param colorBackground colorBackground the color of marked areas in navigation bar If color
|
||||||
|
* is null, no results are displayed in the associated marker bar.
|
||||||
* @param markerColor the color of the marker
|
* @param markerColor the color of the marker
|
||||||
* @param icon the icon used to represent the cursor in the marker margin
|
* @param icon the icon used to represent the cursor in the marker margin
|
||||||
* @param program the program to which the markers apply
|
* @param program the program to which the markers apply
|
||||||
|
@ -115,7 +117,6 @@ class PointMarkerSet extends MarkerSetImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
Address address = pixmap.getLayoutAddress(i);
|
Address address = pixmap.getLayoutAddress(i);
|
||||||
Program program = mgr.getProgram();
|
|
||||||
MarkerLocation loc = new MarkerLocation(this, program, address, 0, yStart);
|
MarkerLocation loc = new MarkerLocation(this, program, address, 0, yStart);
|
||||||
ImageIcon icon = markerDescriptor.getIcon(loc);
|
ImageIcon icon = markerDescriptor.getIcon(loc);
|
||||||
if (icon != null) {
|
if (icon != null) {
|
||||||
|
|
|
@ -26,15 +26,17 @@ import javax.swing.*;
|
||||||
|
|
||||||
import docking.action.DockingActionIf;
|
import docking.action.DockingActionIf;
|
||||||
import docking.help.Help;
|
import docking.help.Help;
|
||||||
|
import ghidra.app.nav.Navigatable;
|
||||||
import ghidra.app.services.GoToService;
|
import ghidra.app.services.GoToService;
|
||||||
import ghidra.app.util.viewer.listingpanel.OverviewProvider;
|
import ghidra.app.util.viewer.listingpanel.OverviewProvider;
|
||||||
import ghidra.app.util.viewer.util.AddressIndexMap;
|
import ghidra.app.util.viewer.util.AddressIndexMap;
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.util.task.SwingUpdateManager;
|
import ghidra.util.task.SwingUpdateManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overview bar component. Uses color to indicate various address based properties for a program.
|
* Overview bar component. Uses color to indicate various address based properties for a program.
|
||||||
* Uses an {@link OverviewColorService} to get the appropriate color for an address.
|
* Uses an {@link OverviewColorService} to get the appropriate color for an address.
|
||||||
*/
|
*/
|
||||||
public class OverviewColorComponent extends JPanel implements OverviewProvider {
|
public class OverviewColorComponent extends JPanel implements OverviewProvider {
|
||||||
|
@ -44,6 +46,7 @@ public class OverviewColorComponent extends JPanel implements OverviewProvider {
|
||||||
private final SwingUpdateManager refreshUpdater =
|
private final SwingUpdateManager refreshUpdater =
|
||||||
new SwingUpdateManager(100, 15000, () -> doRefresh());
|
new SwingUpdateManager(100, 15000, () -> doRefresh());
|
||||||
private AddressIndexMap map;
|
private AddressIndexMap map;
|
||||||
|
private Navigatable navigatable;
|
||||||
private PluginTool tool;
|
private PluginTool tool;
|
||||||
private List<DockingActionIf> actions;
|
private List<DockingActionIf> actions;
|
||||||
|
|
||||||
|
@ -52,7 +55,7 @@ public class OverviewColorComponent extends JPanel implements OverviewProvider {
|
||||||
*
|
*
|
||||||
* @param tool the PluginTool
|
* @param tool the PluginTool
|
||||||
* @param overviewColorService the {@link OverviewColorService} that provides colors for various
|
* @param overviewColorService the {@link OverviewColorService} that provides colors for various
|
||||||
* addresses.
|
* addresses.
|
||||||
*/
|
*/
|
||||||
public OverviewColorComponent(PluginTool tool, OverviewColorService overviewColorService) {
|
public OverviewColorComponent(PluginTool tool, OverviewColorService overviewColorService) {
|
||||||
this.tool = tool;
|
this.tool = tool;
|
||||||
|
@ -104,7 +107,7 @@ public class OverviewColorComponent extends JPanel implements OverviewProvider {
|
||||||
protected void gotoAddress(Address address) {
|
protected void gotoAddress(Address address) {
|
||||||
GoToService gotoService = tool.getService(GoToService.class);
|
GoToService gotoService = tool.getService(GoToService.class);
|
||||||
if (gotoService != null) {
|
if (gotoService != null) {
|
||||||
gotoService.goTo(address);
|
gotoService.goTo(navigatable, address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,12 +197,17 @@ public class OverviewColorComponent extends JPanel implements OverviewProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAddressIndexMap(AddressIndexMap map) {
|
public void setProgram(Program program, AddressIndexMap map) {
|
||||||
this.map = map;
|
this.map = map;
|
||||||
colors = new Color[getOverviewPixelCount()];
|
colors = new Color[getOverviewPixelCount()];
|
||||||
refreshUpdater.updateLater();
|
refreshUpdater.updateLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNavigatable(Navigatable n) {
|
||||||
|
this.navigatable = n;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Causes this component to completely compute the colors used to paint the overview bar.
|
* Causes this component to completely compute the colors used to paint the overview bar.
|
||||||
*/
|
*/
|
||||||
|
@ -210,6 +218,7 @@ public class OverviewColorComponent extends JPanel implements OverviewProvider {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Causes the component to refresh any colors for the given address range.
|
* Causes the component to refresh any colors for the given address range.
|
||||||
|
*
|
||||||
* @param start the start of the address range to refresh.
|
* @param start the start of the address range to refresh.
|
||||||
* @param end the end of the address range to refresh.
|
* @param end the end of the address range to refresh.
|
||||||
*/
|
*/
|
||||||
|
@ -232,6 +241,7 @@ public class OverviewColorComponent extends JPanel implements OverviewProvider {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the PluginTool
|
* Returns the PluginTool
|
||||||
|
*
|
||||||
* @return the PluginTool
|
* @return the PluginTool
|
||||||
*/
|
*/
|
||||||
public PluginTool getTool() {
|
public PluginTool getTool() {
|
||||||
|
|
|
@ -20,7 +20,7 @@ import java.awt.Color;
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
import javax.swing.event.ChangeListener;
|
import javax.swing.event.ChangeListener;
|
||||||
|
|
||||||
import ghidra.app.plugin.core.marker.MarkerManagerPlugin;
|
import ghidra.app.plugin.core.marker.*;
|
||||||
import ghidra.app.util.viewer.listingpanel.MarkerClickedListener;
|
import ghidra.app.util.viewer.listingpanel.MarkerClickedListener;
|
||||||
import ghidra.framework.plugintool.ServiceInfo;
|
import ghidra.framework.plugintool.ServiceInfo;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
|
@ -28,8 +28,8 @@ import ghidra.program.model.listing.Program;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* Service to manage navigation markers displayed around a scrollable window like the Listing.
|
* Service to manage navigation markers displayed around a scrollable window like the Listing. The
|
||||||
* The navigation bar displays the general location of markers for the entire view. The marker bar
|
* navigation bar displays the general location of markers for the entire view. The marker bar
|
||||||
* displays a marker at each marked address visible within the view.
|
* displays a marker at each marked address visible within the view.
|
||||||
* </p>
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -39,16 +39,18 @@ import ghidra.program.model.listing.Program;
|
||||||
* </p>
|
* </p>
|
||||||
* <a name="usage"></a> <u>Recommended Usage</u><br>
|
* <a name="usage"></a> <u>Recommended Usage</u><br>
|
||||||
* <u>Recommended Usage</u><br>
|
* <u>Recommended Usage</u><br>
|
||||||
* The service used to work independently of {@link Program}s. In order to work effectively this
|
* The service used to work independently of {@link Program}s. In order to work effectively this
|
||||||
* service has been changed to associate created markers with individual programs. Thus, it is
|
* service has been changed to associate created markers with individual programs. Thus, it is up to
|
||||||
* up to the clients of this class perform lifecycle management of markers created by this
|
* the clients of this class perform lifecycle management of markers created by this service. For
|
||||||
* service. For example, a client that creates a marker from
|
* example, a client that creates a marker from
|
||||||
* {@link #createAreaMarker(String, String, Program, int, boolean, boolean, boolean, Color)} should
|
* {@link #createAreaMarker(String, String, Program, int, boolean, boolean, boolean, Color)} should
|
||||||
* call {@link #removeMarker(MarkerSet, Program)} when the markers are no longer used, such as when
|
* call {@link #removeMarker(MarkerSet, Program)} when the markers are no longer used, such as when
|
||||||
* a program has become deactivated. In this example usage markers are added and removed as the
|
* a program has become deactivated. In this example usage markers are added and removed as the user
|
||||||
* user tabs through open programs.
|
* tabs through open programs.
|
||||||
*/
|
*/
|
||||||
@ServiceInfo(defaultProvider = MarkerManagerPlugin.class, description = "Service to manage navigation markers displayed around a scrollable window.")
|
@ServiceInfo(
|
||||||
|
defaultProvider = MarkerManagerPlugin.class,
|
||||||
|
description = "Service to manage navigation markers displayed around a scrollable window.")
|
||||||
public interface MarkerService {
|
public interface MarkerService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -104,7 +106,7 @@ public interface MarkerService {
|
||||||
public final static int REFERENCE_PRIORITY = -10;
|
public final static int REFERENCE_PRIORITY = -10;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A group name for highlights. This is intended to be used with
|
* A group name for highlights. This is intended to be used with
|
||||||
* {@link #setMarkerForGroup(String, MarkerSet, Program)} and
|
* {@link #setMarkerForGroup(String, MarkerSet, Program)} and
|
||||||
* {@link #removeMarkerForGroup(String, MarkerSet, Program)}
|
* {@link #removeMarkerForGroup(String, MarkerSet, Program)}
|
||||||
*/
|
*/
|
||||||
|
@ -118,7 +120,8 @@ public interface MarkerService {
|
||||||
* @param program The program with which the created markers will be associated.
|
* @param program The program with which the created markers will be associated.
|
||||||
* @param priority to sort out what displays on top, higher is more likely to be on top
|
* @param priority to sort out what displays on top, higher is more likely to be on top
|
||||||
* @param showMarkers true indicates to show area markers (on the left side of the browser.)
|
* @param showMarkers true indicates to show area markers (on the left side of the browser.)
|
||||||
* @param showNavigation true indicates to show area navigation markers (on the right side of the browser.)
|
* @param showNavigation true indicates to show area navigation markers (on the right side of
|
||||||
|
* the browser.)
|
||||||
* @param colorBackground if true, then the browser's background color will reflect the marker.
|
* @param colorBackground if true, then the browser's background color will reflect the marker.
|
||||||
* @param color the color of marked areas.
|
* @param color the color of marked areas.
|
||||||
* @return set of navigation markers
|
* @return set of navigation markers
|
||||||
|
@ -135,7 +138,8 @@ public interface MarkerService {
|
||||||
* @param program The program with which the created markers will be associated.
|
* @param program The program with which the created markers will be associated.
|
||||||
* @param priority to sort out what displays on top, higher is more likely to be on top
|
* @param priority to sort out what displays on top, higher is more likely to be on top
|
||||||
* @param showMarkers true indicates to show area markers (on the left side of the browser.)
|
* @param showMarkers true indicates to show area markers (on the left side of the browser.)
|
||||||
* @param showNavigation true indicates to show area navigation markers (on the right side of the browser.)
|
* @param showNavigation true indicates to show area navigation markers (on the right side of
|
||||||
|
* the browser.)
|
||||||
* @param colorBackground if true, then the browser's background color will reflect the marker.
|
* @param colorBackground if true, then the browser's background color will reflect the marker.
|
||||||
* @param color the color of marked areas.
|
* @param color the color of marked areas.
|
||||||
* @param isPreferred true indicates higher priority than all non-preferred MarkerSets
|
* @param isPreferred true indicates higher priority than all non-preferred MarkerSets
|
||||||
|
@ -153,7 +157,8 @@ public interface MarkerService {
|
||||||
* @param program The program with which the created markers will be associated.
|
* @param program The program with which the created markers will be associated.
|
||||||
* @param priority to sort out what displays on top, higher is more likely to be on top
|
* @param priority to sort out what displays on top, higher is more likely to be on top
|
||||||
* @param showMarkers true indicates to show area markers (on the left side of the browser.)
|
* @param showMarkers true indicates to show area markers (on the left side of the browser.)
|
||||||
* @param showNavigation true indicates to show area navigation markers (on the right side of the browser.)
|
* @param showNavigation true indicates to show area navigation markers (on the right side of
|
||||||
|
* the browser.)
|
||||||
* @param colorBackground if true, then the browser's background color will reflect the marker.
|
* @param colorBackground if true, then the browser's background color will reflect the marker.
|
||||||
* @param color the color of marked areas in navigation bar
|
* @param color the color of marked areas in navigation bar
|
||||||
* @param icon icon to display in marker bar
|
* @param icon icon to display in marker bar
|
||||||
|
@ -171,7 +176,8 @@ public interface MarkerService {
|
||||||
* @param program The program with which the created markers will be associated.
|
* @param program The program with which the created markers will be associated.
|
||||||
* @param priority to sort out what displays on top, higher is more likely to be on top
|
* @param priority to sort out what displays on top, higher is more likely to be on top
|
||||||
* @param showMarkers true indicates to show area markers (on the left side of the browser.)
|
* @param showMarkers true indicates to show area markers (on the left side of the browser.)
|
||||||
* @param showNavigation true indicates to show area navigation markers (on the right side of the browser.)
|
* @param showNavigation true indicates to show area navigation markers (on the right side of
|
||||||
|
* the browser.)
|
||||||
* @param colorBackground if true, then the browser's background color will reflect the marker.
|
* @param colorBackground if true, then the browser's background color will reflect the marker.
|
||||||
* @param color the color of marked areas in navigation bar
|
* @param color the color of marked areas in navigation bar
|
||||||
* @param icon icon to display in marker bar
|
* @param icon icon to display in marker bar
|
||||||
|
@ -200,9 +206,10 @@ public interface MarkerService {
|
||||||
public MarkerSet getMarkerSet(String name, Program program);
|
public MarkerSet getMarkerSet(String name, Program program);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a marker set for a given group name. Any previous marker set associated with the
|
* Sets a marker set for a given group name. Any previous marker set associated with the given
|
||||||
* given group name will be removed from this marker service. This method is used to ensure
|
* group name will be removed from this marker service. This method is used to ensure that only
|
||||||
* that only one marker set is used at any time for a give group.
|
* one marker set is used at any time for a give group.
|
||||||
|
*
|
||||||
* @param groupName The name to associate the marker set with.
|
* @param groupName The name to associate the marker set with.
|
||||||
* @param markerSet The marker set to add to this service
|
* @param markerSet The marker set to add to this service
|
||||||
* @param program The program with which the markers are associated.
|
* @param program The program with which the markers are associated.
|
||||||
|
@ -211,33 +218,22 @@ public interface MarkerService {
|
||||||
public void setMarkerForGroup(String groupName, MarkerSet markerSet, Program program);
|
public void setMarkerForGroup(String groupName, MarkerSet markerSet, Program program);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a marker set for a given group name. If the given marker set is not the marker
|
* Removes a marker set for a given group name. If the given marker set is not the marker set
|
||||||
* set associated with the given group name, then no action will be taken.
|
* associated with the given group name, then no action will be taken.
|
||||||
|
*
|
||||||
* @param groupName The name associated the marker set with.
|
* @param groupName The name associated the marker set with.
|
||||||
* @param markerSet The marker set to add to this service
|
* @param markerSet The marker set to add to this service
|
||||||
* @param program The program with which the markers are associated. May be null if the
|
* @param program The program with which the markers are associated. May be null if the marker
|
||||||
* marker is
|
* is
|
||||||
* @see #setMarkerForGroup(String, MarkerSet, Program)
|
* @see #setMarkerForGroup(String, MarkerSet, Program)
|
||||||
*/
|
*/
|
||||||
public void removeMarkerForGroup(String groupName, MarkerSet markerSet, Program program);
|
public void removeMarkerForGroup(String groupName, MarkerSet markerSet, Program program);
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the background color associated with the given address. Each markerSet that supports
|
|
||||||
* background coloring is checked in priority order to see if it wants to specify a background
|
|
||||||
* color for the given address.
|
|
||||||
* @param address the address to check for a background color.
|
|
||||||
* @return the background color to use for that address or null if no markers contain that address.
|
|
||||||
*/
|
|
||||||
public Color getBackgroundColor(Address address);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the background color associated with the given program and address. Each markerSet
|
* Returns the background color associated with the given program and address. Each markerSet
|
||||||
* that supports background coloring is checked in priority order to see if it wants to specify
|
* that supports background coloring is checked in priority order to see if it wants to specify
|
||||||
* a background color for the given address.
|
* a background color for the given address.
|
||||||
*
|
*
|
||||||
* If {@code program} is the current program, this is equivalent to
|
|
||||||
* {@link #getBackgroundColor(Address)}.
|
|
||||||
*
|
|
||||||
* @param program the program to check for a background color.
|
* @param program the program to check for a background color.
|
||||||
* @param address the address to check for a background color.
|
* @param address the address to check for a background color.
|
||||||
* @return the background color to use for that address or null if no markers contain that
|
* @return the background color to use for that address or null if no markers contain that
|
||||||
|
@ -270,4 +266,21 @@ public interface MarkerService {
|
||||||
*/
|
*/
|
||||||
public void setMarkerClickedListener(MarkerClickedListener listener);
|
public void setMarkerClickedListener(MarkerClickedListener listener);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new marker margin provider. The newly created provider is not added to the UI;
|
||||||
|
* clients must install the newly created provider themselves. Note that you must keep a strong
|
||||||
|
* reference to the provider, or it may not receive updates from the service.
|
||||||
|
*
|
||||||
|
* @return the new provider
|
||||||
|
*/
|
||||||
|
public MarkerMarginProvider createMarginProvider();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new marker overview provider. The newly created provider is not added to the UI;
|
||||||
|
* clients must install the newly created provider themselves. Note that you must keep a strong
|
||||||
|
* reference to the provider, or it may not receive updates from the service.
|
||||||
|
*
|
||||||
|
* @return the new provider
|
||||||
|
*/
|
||||||
|
public MarkerOverviewProvider createOverviewProvider();
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,6 +154,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a comparison panel with two listings.
|
* Creates a comparison panel with two listings.
|
||||||
|
*
|
||||||
* @param owner the owner of this panel
|
* @param owner the owner of this panel
|
||||||
* @param tool the tool displaying this panel
|
* @param tool the tool displaying this panel
|
||||||
*/
|
*/
|
||||||
|
@ -208,9 +209,6 @@ public class ListingCodeComparisonPanel
|
||||||
Color diffCodeUnitsBackgroundColor = comparisonOptions.getDiffCodeUnitsBackgroundColor();
|
Color diffCodeUnitsBackgroundColor = comparisonOptions.getDiffCodeUnitsBackgroundColor();
|
||||||
diffMarkers[LEFT].setMarkerColor(diffCodeUnitsBackgroundColor);
|
diffMarkers[LEFT].setMarkerColor(diffCodeUnitsBackgroundColor);
|
||||||
diffMarkers[RIGHT].setMarkerColor(diffCodeUnitsBackgroundColor);
|
diffMarkers[RIGHT].setMarkerColor(diffCodeUnitsBackgroundColor);
|
||||||
// Force a refresh by setting the program. This updates the colors in the navigation popup.
|
|
||||||
markerManagers[LEFT].setProgram(getLeftProgram());
|
|
||||||
markerManagers[RIGHT].setProgram(getRightProgram());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -280,6 +278,7 @@ public class ListingCodeComparisonPanel
|
||||||
/**
|
/**
|
||||||
* Sets the coordinator for the two listings within this code comparison panel. It coordinates
|
* Sets the coordinator for the two listings within this code comparison panel. It coordinates
|
||||||
* their scrolling and location synchronization.
|
* their scrolling and location synchronization.
|
||||||
|
*
|
||||||
* @param listingFieldPanelCoordinator the coordinator for the two listings
|
* @param listingFieldPanelCoordinator the coordinator for the two listings
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -303,6 +302,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the indicated highlight providers for the left and right listing panels.
|
* Adds the indicated highlight providers for the left and right listing panels.
|
||||||
|
*
|
||||||
* @param leftHighlightProvider the highlight provider for the left side's listing.
|
* @param leftHighlightProvider the highlight provider for the left side's listing.
|
||||||
* @param rightHighlightProvider the highlight provider for the right side's listing.
|
* @param rightHighlightProvider the highlight provider for the right side's listing.
|
||||||
*/
|
*/
|
||||||
|
@ -322,6 +322,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the indicated highlight providers from the left and right listing panels.
|
* Removes the indicated highlight providers from the left and right listing panels.
|
||||||
|
*
|
||||||
* @param leftHighlightProvider the highlight provider for the left side's listing.
|
* @param leftHighlightProvider the highlight provider for the left side's listing.
|
||||||
* @param rightHighlightProvider the highlight provider for the right side's listing.
|
* @param rightHighlightProvider the highlight provider for the right side's listing.
|
||||||
*/
|
*/
|
||||||
|
@ -425,6 +426,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a listener for program location changes for the left side's listing panel.
|
* Sets a listener for program location changes for the left side's listing panel.
|
||||||
|
*
|
||||||
* @param programLocationListener the listener
|
* @param programLocationListener the listener
|
||||||
*/
|
*/
|
||||||
public void setLeftProgramLocationListener(ProgramLocationListener programLocationListener) {
|
public void setLeftProgramLocationListener(ProgramLocationListener programLocationListener) {
|
||||||
|
@ -433,6 +435,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a listener for program location changes for the right side's listing panel.
|
* Sets a listener for program location changes for the right side's listing panel.
|
||||||
|
*
|
||||||
* @param programLocationListener the listener
|
* @param programLocationListener the listener
|
||||||
*/
|
*/
|
||||||
public void setRightProgramLocationListener(ProgramLocationListener programLocationListener) {
|
public void setRightProgramLocationListener(ProgramLocationListener programLocationListener) {
|
||||||
|
@ -830,10 +833,11 @@ public class ListingCodeComparisonPanel
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether or not the entire programs are displayed in the listings or only
|
* Sets whether or not the entire programs are displayed in the listings or only the addresses
|
||||||
* the addresses in the limited set.
|
* in the limited set.
|
||||||
* @param show if true, the entire program will be shown. Otherwise the listings will only
|
*
|
||||||
* show the limited addresses.
|
* @param show if true, the entire program will be shown. Otherwise the listings will only show
|
||||||
|
* the limited addresses.
|
||||||
*/
|
*/
|
||||||
public void showEntireListing(boolean show) {
|
public void showEntireListing(boolean show) {
|
||||||
try {
|
try {
|
||||||
|
@ -863,6 +867,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if the listing's layout field header is currently showing.
|
* Determines if the listing's layout field header is currently showing.
|
||||||
|
*
|
||||||
* @return true if the header is showing.
|
* @return true if the header is showing.
|
||||||
*/
|
*/
|
||||||
public boolean isHeaderShowing() {
|
public boolean isHeaderShowing() {
|
||||||
|
@ -871,6 +876,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows or hides the listing's layout field header.
|
* Shows or hides the listing's layout field header.
|
||||||
|
*
|
||||||
* @param show true means show the field header. false means hide the header.
|
* @param show true means show the field header. false means hide the header.
|
||||||
*/
|
*/
|
||||||
public void setHeaderShowing(boolean show) {
|
public void setHeaderShowing(boolean show) {
|
||||||
|
@ -889,6 +895,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether or not the listings are displayed side by side.
|
* Sets whether or not the listings are displayed side by side.
|
||||||
|
*
|
||||||
* @param sideBySide if true, the listings are side by side, otherwise one is above the other.
|
* @param sideBySide if true, the listings are side by side, otherwise one is above the other.
|
||||||
*/
|
*/
|
||||||
public void showSideBySide(boolean sideBySide) {
|
public void showSideBySide(boolean sideBySide) {
|
||||||
|
@ -932,6 +939,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the function loaded in the left listing panel.
|
* Gets the function loaded in the left listing panel.
|
||||||
|
*
|
||||||
* @return the function or null
|
* @return the function or null
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -941,6 +949,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the function loaded in the right listing panel.
|
* Gets the function loaded in the right listing panel.
|
||||||
|
*
|
||||||
* @return the function or null
|
* @return the function or null
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -989,8 +998,8 @@ public class ListingCodeComparisonPanel
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Establishes the location and display of the arrow cursor. This method should be called
|
* Establishes the location and display of the arrow cursor. This method should be called after
|
||||||
* after the function comparison window is loaded with functions, data, etc.
|
* the function comparison window is loaded with functions, data, etc.
|
||||||
*/
|
*/
|
||||||
private void loadCursorArrow() {
|
private void loadCursorArrow() {
|
||||||
int focusedSide = currProgramIndex;
|
int focusedSide = currProgramIndex;
|
||||||
|
@ -1022,8 +1031,9 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets an equivalent left side program location when given a right side program location or
|
* Gets an equivalent left side program location when given a right side program location or
|
||||||
* vice versa. The intent of this method is to translate a location from one side of the
|
* vice versa. The intent of this method is to translate a location from one side of the dual
|
||||||
* dual listing to an equivalent location for the other side if possible.
|
* listing to an equivalent location for the other side if possible.
|
||||||
|
*
|
||||||
* @param leftOrRight LEFT or RIGHT indicating which side's program location is needed.
|
* @param leftOrRight LEFT or RIGHT indicating which side's program location is needed.
|
||||||
* @param programLocation the program location for the other side.
|
* @param programLocation the program location for the other side.
|
||||||
* @return a program location for the desired side. Otherwise, null.
|
* @return a program location for the desired side. Otherwise, null.
|
||||||
|
@ -1158,16 +1168,17 @@ public class ListingCodeComparisonPanel
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Infers a desired byte address based on the specified <code>byteAddress</code> as well
|
* Infers a desired byte address based on the specified <code>byteAddress</code> as well as the
|
||||||
* as the <code>address</code> and <code>desiredAddress</code> that were matched.
|
* <code>address</code> and <code>desiredAddress</code> that were matched.
|
||||||
|
*
|
||||||
* @param address matches up with the <code>desiredAddress</code> from the other function/data.
|
* @param address matches up with the <code>desiredAddress</code> from the other function/data.
|
||||||
* @param desiredAddress matches up with the <code>address</code> from the other function/data.
|
* @param desiredAddress matches up with the <code>address</code> from the other function/data.
|
||||||
* @param byteAddress the byte address that is associated with <code>address</code>
|
* @param byteAddress the byte address that is associated with <code>address</code>
|
||||||
* @param program the program for the <code>address</code> and <code>byteAddress</code>.
|
* @param program the program for the <code>address</code> and <code>byteAddress</code>.
|
||||||
* @param desiredProgram the program for the <code>desiredAddress</code> and
|
* @param desiredProgram the program for the <code>desiredAddress</code> and
|
||||||
* <code>desiredByteAddress</code>.
|
* <code>desiredByteAddress</code>.
|
||||||
* @return the desired byte address that matches up with the indicated <code>byteAddress</code>
|
* @return the desired byte address that matches up with the indicated <code>byteAddress</code>
|
||||||
* or null if it can't be determined.
|
* or null if it can't be determined.
|
||||||
*/
|
*/
|
||||||
private Address inferDesiredByteAddress(Address address, Address desiredAddress,
|
private Address inferDesiredByteAddress(Address address, Address desiredAddress,
|
||||||
Address byteAddress, Program program, Program desiredProgram) {
|
Address byteAddress, Program program, Program desiredProgram) {
|
||||||
|
@ -1187,21 +1198,21 @@ public class ListingCodeComparisonPanel
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This infers the desired byte address within Data based on the code units at
|
* This infers the desired byte address within Data based on the code units at
|
||||||
* <code>codeUnitAddress</code> and <code>desiredCodeUnitAddress</code>.
|
* <code>codeUnitAddress</code> and <code>desiredCodeUnitAddress</code>. The inferred address
|
||||||
* The inferred address will be at an offset from the <code>desiredCodeUnitAddress</code>
|
* will be at an offset from the <code>desiredCodeUnitAddress</code> that is the same distance
|
||||||
* that is the same distance the <code>byteAddress</code> is from the <code>codeUnitAddress</code>.
|
* the <code>byteAddress</code> is from the <code>codeUnitAddress</code>.
|
||||||
*
|
*
|
||||||
* @param codeUnitAddress matches up with the <code>desiredCodeUnitAddress</code> from
|
* @param codeUnitAddress matches up with the <code>desiredCodeUnitAddress</code> from the other
|
||||||
* the other data.
|
* data.
|
||||||
* @param desiredCodeUnitAddress matches up with the <code>codeUnitAddress</code> from
|
* @param desiredCodeUnitAddress matches up with the <code>codeUnitAddress</code> from the other
|
||||||
* the other data.
|
* data.
|
||||||
* @param byteAddress the byte address that is associated with <code>codeUnitAddress</code>
|
* @param byteAddress the byte address that is associated with <code>codeUnitAddress</code>
|
||||||
* @param program the program for the <code>codeUnitAddress</code> and <code>byteAddress</code>.
|
* @param program the program for the <code>codeUnitAddress</code> and <code>byteAddress</code>.
|
||||||
* @param desiredProgram the program for the <code>desiredCodeUnitAddress</code> and
|
* @param desiredProgram the program for the <code>desiredCodeUnitAddress</code> and
|
||||||
* <code>desiredByteAddress</code>.
|
* <code>desiredByteAddress</code>.
|
||||||
* @return the desired byte address within the data that matches up with the indicated
|
* @return the desired byte address within the data that matches up with the indicated
|
||||||
* <code>byteAddress</code> or null if it can't be determined.
|
* <code>byteAddress</code> or null if it can't be determined.
|
||||||
*/
|
*/
|
||||||
private Address inferDesiredDataAddress(Address codeUnitAddress, Address desiredCodeUnitAddress,
|
private Address inferDesiredDataAddress(Address codeUnitAddress, Address desiredCodeUnitAddress,
|
||||||
Address byteAddress, Program program, Program desiredProgram) {
|
Address byteAddress, Program program, Program desiredProgram) {
|
||||||
|
@ -1227,19 +1238,19 @@ public class ListingCodeComparisonPanel
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This infers the desired byte address within a function based on the code units at
|
* This infers the desired byte address within a function based on the code units at
|
||||||
* <code>address</code> and <code>desiredAddress</code>.
|
* <code>address</code> and <code>desiredAddress</code>. If the inferred address would be beyond
|
||||||
* If the inferred address would be beyond the last byte of the code unit then it
|
* the last byte of the code unit then it will get set to the last byte of the code unit at the
|
||||||
* will get set to the last byte of the code unit at the <code>desiredAddress</code>.
|
* <code>desiredAddress</code>.
|
||||||
*
|
*
|
||||||
* @param address matches up with the <code>desiredAddress</code> from the other function.
|
* @param address matches up with the <code>desiredAddress</code> from the other function.
|
||||||
* @param desiredAddress matches up with the <code>address</code> from the other function.
|
* @param desiredAddress matches up with the <code>address</code> from the other function.
|
||||||
* @param byteAddress the byte address that is associated with <code>address</code>
|
* @param byteAddress the byte address that is associated with <code>address</code>
|
||||||
* @param program the program for the <code>address</code> and <code>byteAddress</code>.
|
* @param program the program for the <code>address</code> and <code>byteAddress</code>.
|
||||||
* @param desiredProgram the program for the <code>desiredAddress</code> and
|
* @param desiredProgram the program for the <code>desiredAddress</code> and
|
||||||
* <code>desiredByteAddress</code>.
|
* <code>desiredByteAddress</code>.
|
||||||
* @return the desired byte address within the data that matches up with the indicated
|
* @return the desired byte address within the data that matches up with the indicated
|
||||||
* <code>byteAddress</code> or null if it can't be determined.
|
* <code>byteAddress</code> or null if it can't be determined.
|
||||||
*/
|
*/
|
||||||
private Address inferDesiredFunctionAddress(Address address, Address desiredAddress,
|
private Address inferDesiredFunctionAddress(Address address, Address desiredAddress,
|
||||||
Address byteAddress, Program program, Program desiredProgram) {
|
Address byteAddress, Program program, Program desiredProgram) {
|
||||||
|
@ -1268,6 +1279,7 @@ public class ListingCodeComparisonPanel
|
||||||
* Gets an equivalent left side variable location when given a right side variable location or
|
* Gets an equivalent left side variable location when given a right side variable location or
|
||||||
* vice versa. The intent of this method is to translate a variable location from one side of
|
* vice versa. The intent of this method is to translate a variable location from one side of
|
||||||
* the dual listing to an equivalent variable location for the other side if possible.
|
* the dual listing to an equivalent variable location for the other side if possible.
|
||||||
|
*
|
||||||
* @param leftOrRight LEFT or RIGHT indicating which side's variable location is needed.
|
* @param leftOrRight LEFT or RIGHT indicating which side's variable location is needed.
|
||||||
* @param variableLocation the variable location for the other side.
|
* @param variableLocation the variable location for the other side.
|
||||||
* @return a variable location for the desired side. Otherwise, null.
|
* @return a variable location for the desired side. Otherwise, null.
|
||||||
|
@ -1549,7 +1561,6 @@ public class ListingCodeComparisonPanel
|
||||||
listingPanels[LEFT].getFieldPanel()
|
listingPanels[LEFT].getFieldPanel()
|
||||||
.setBackgroundColorModel(
|
.setBackgroundColorModel(
|
||||||
new MarkerServiceBackgroundColorModel(markerManagers[LEFT], indexMap));
|
new MarkerServiceBackgroundColorModel(markerManagers[LEFT], indexMap));
|
||||||
markerManagers[LEFT].setProgram(programs[LEFT]);
|
|
||||||
unmatchedCodeMarkers[LEFT] =
|
unmatchedCodeMarkers[LEFT] =
|
||||||
markerManagers[LEFT].createAreaMarker("Listing1 Unmatched Code",
|
markerManagers[LEFT].createAreaMarker("Listing1 Unmatched Code",
|
||||||
"Instructions that are not matched to an instruction in the other function.",
|
"Instructions that are not matched to an instruction in the other function.",
|
||||||
|
@ -1565,7 +1576,6 @@ public class ListingCodeComparisonPanel
|
||||||
.setBackgroundColorModel(
|
.setBackgroundColorModel(
|
||||||
new MarkerServiceBackgroundColorModel(markerManagers[RIGHT],
|
new MarkerServiceBackgroundColorModel(markerManagers[RIGHT],
|
||||||
rightIndexMap));
|
rightIndexMap));
|
||||||
markerManagers[RIGHT].setProgram(programs[RIGHT]);
|
|
||||||
unmatchedCodeMarkers[RIGHT] =
|
unmatchedCodeMarkers[RIGHT] =
|
||||||
markerManagers[RIGHT].createAreaMarker("Listing2 Unmatched Code",
|
markerManagers[RIGHT].createAreaMarker("Listing2 Unmatched Code",
|
||||||
"Instructions that are not matched to an instruction in the other function.",
|
"Instructions that are not matched to an instruction in the other function.",
|
||||||
|
@ -1663,7 +1673,7 @@ public class ListingCodeComparisonPanel
|
||||||
}
|
}
|
||||||
|
|
||||||
indexMaps[LEFT] = new AddressIndexMap(addressSets[LEFT]);
|
indexMaps[LEFT] = new AddressIndexMap(addressSets[LEFT]);
|
||||||
markerManagers[LEFT].getOverviewProvider().setAddressIndexMap(indexMaps[LEFT]);
|
markerManagers[LEFT].getOverviewProvider().setProgram(getLeftProgram(), indexMaps[LEFT]);
|
||||||
listingPanels[LEFT].getFieldPanel()
|
listingPanels[LEFT].getFieldPanel()
|
||||||
.setBackgroundColorModel(
|
.setBackgroundColorModel(
|
||||||
new MarkerServiceBackgroundColorModel(markerManagers[LEFT], indexMaps[LEFT]));
|
new MarkerServiceBackgroundColorModel(markerManagers[LEFT], indexMaps[LEFT]));
|
||||||
|
@ -1680,7 +1690,7 @@ public class ListingCodeComparisonPanel
|
||||||
}
|
}
|
||||||
|
|
||||||
indexMaps[RIGHT] = new AddressIndexMap(addressSets[RIGHT]);
|
indexMaps[RIGHT] = new AddressIndexMap(addressSets[RIGHT]);
|
||||||
markerManagers[RIGHT].getOverviewProvider().setAddressIndexMap(indexMaps[RIGHT]);
|
markerManagers[RIGHT].getOverviewProvider().setProgram(getRightProgram(), indexMaps[RIGHT]);
|
||||||
listingPanels[RIGHT].getFieldPanel()
|
listingPanels[RIGHT].getFieldPanel()
|
||||||
.setBackgroundColorModel(
|
.setBackgroundColorModel(
|
||||||
new MarkerServiceBackgroundColorModel(markerManagers[RIGHT], indexMaps[RIGHT]));
|
new MarkerServiceBackgroundColorModel(markerManagers[RIGHT], indexMaps[RIGHT]));
|
||||||
|
@ -1723,6 +1733,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the cursor location in the left and right listing at the specified functions.
|
* Sets the cursor location in the left and right listing at the specified functions.
|
||||||
|
*
|
||||||
* @param leftFunction the function in the left listing panel.
|
* @param leftFunction the function in the left listing panel.
|
||||||
* @param rightFunction the function in the right listing panel.
|
* @param rightFunction the function in the right listing panel.
|
||||||
*/
|
*/
|
||||||
|
@ -1733,6 +1744,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the cursor in the left side's listing to the specified location.
|
* Sets the cursor in the left side's listing to the specified location.
|
||||||
|
*
|
||||||
* @param program the left side's program
|
* @param program the left side's program
|
||||||
* @param location the location
|
* @param location the location
|
||||||
*/
|
*/
|
||||||
|
@ -1744,6 +1756,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the cursor in the right side's listing to the specified location.
|
* Sets the cursor in the right side's listing to the specified location.
|
||||||
|
*
|
||||||
* @param program the right side's program
|
* @param program the right side's program
|
||||||
* @param location the location
|
* @param location the location
|
||||||
*/
|
*/
|
||||||
|
@ -1863,6 +1876,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the title for the left side's listing.
|
* Sets the title for the left side's listing.
|
||||||
|
*
|
||||||
* @param leftTitle the title
|
* @param leftTitle the title
|
||||||
*/
|
*/
|
||||||
public void setLeftTitle(String leftTitle) {
|
public void setLeftTitle(String leftTitle) {
|
||||||
|
@ -1872,6 +1886,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the title for the right side's listing.
|
* Sets the title for the right side's listing.
|
||||||
|
*
|
||||||
* @param rightTitle the title
|
* @param rightTitle the title
|
||||||
*/
|
*/
|
||||||
public void setRightTitle(String rightTitle) {
|
public void setRightTitle(String rightTitle) {
|
||||||
|
@ -1881,6 +1896,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the component displayed in the top of this panel.
|
* Sets the component displayed in the top of this panel.
|
||||||
|
*
|
||||||
* @param comp the component.
|
* @param comp the component.
|
||||||
*/
|
*/
|
||||||
public void setTopComponent(JComponent comp) {
|
public void setTopComponent(JComponent comp) {
|
||||||
|
@ -1899,6 +1915,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the component displayed in the bottom of this panel.
|
* Sets the component displayed in the bottom of this panel.
|
||||||
|
*
|
||||||
* @param comp the component.
|
* @param comp the component.
|
||||||
*/
|
*/
|
||||||
public void setBottomComponent(JComponent comp) {
|
public void setBottomComponent(JComponent comp) {
|
||||||
|
@ -1918,6 +1935,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the program from the left or right side that has or last had focus.
|
* Gets the program from the left or right side that has or last had focus.
|
||||||
|
*
|
||||||
* @return the program from the side of this panel with focus or null
|
* @return the program from the side of this panel with focus or null
|
||||||
*/
|
*/
|
||||||
public Program getFocusedProgram() {
|
public Program getFocusedProgram() {
|
||||||
|
@ -1926,6 +1944,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the program in the left listing panel.
|
* Gets the program in the left listing panel.
|
||||||
|
*
|
||||||
* @return the left program or null
|
* @return the left program or null
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -1935,6 +1954,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the program in the right listing panel.
|
* Gets the program in the right listing panel.
|
||||||
|
*
|
||||||
* @return the right program or null
|
* @return the right program or null
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -1944,6 +1964,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the addresses in the left listing panel.
|
* Gets the addresses in the left listing panel.
|
||||||
|
*
|
||||||
* @return the addresses
|
* @return the addresses
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -1953,6 +1974,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the addresses in the right listing panel.
|
* Gets the addresses in the right listing panel.
|
||||||
|
*
|
||||||
* @return the addresses
|
* @return the addresses
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -1962,6 +1984,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the left or right listing panel that has or last had focus.
|
* Get the left or right listing panel that has or last had focus.
|
||||||
|
*
|
||||||
* @return the listing panel with focus.
|
* @return the listing panel with focus.
|
||||||
*/
|
*/
|
||||||
public ListingPanel getFocusedListingPanel() {
|
public ListingPanel getFocusedListingPanel() {
|
||||||
|
@ -1970,6 +1993,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the left side's listing panel.
|
* Get the left side's listing panel.
|
||||||
|
*
|
||||||
* @return the left panel
|
* @return the left panel
|
||||||
*/
|
*/
|
||||||
public ListingPanel getLeftPanel() {
|
public ListingPanel getLeftPanel() {
|
||||||
|
@ -1978,6 +2002,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the right side's listing panel.
|
* Get the right side's listing panel.
|
||||||
|
*
|
||||||
* @return the right panel
|
* @return the right panel
|
||||||
*/
|
*/
|
||||||
public ListingPanel getRightPanel() {
|
public ListingPanel getRightPanel() {
|
||||||
|
@ -1986,6 +2011,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Go to the indicated address in the listing that last had focus.
|
* Go to the indicated address in the listing that last had focus.
|
||||||
|
*
|
||||||
* @param addr the cursor should go to this address
|
* @param addr the cursor should go to this address
|
||||||
* @return true if the location changed
|
* @return true if the location changed
|
||||||
*/
|
*/
|
||||||
|
@ -1995,9 +2021,10 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Go to the indicated location in the listing that last had focus.
|
* Go to the indicated location in the listing that last had focus.
|
||||||
|
*
|
||||||
* @param loc the cursor should go to this location.
|
* @param loc the cursor should go to this location.
|
||||||
* @param centerOnScreen true indicates that the location should be centered in the listing's
|
* @param centerOnScreen true indicates that the location should be centered in the listing's
|
||||||
* viewport.
|
* viewport.
|
||||||
* @return true if the location changed
|
* @return true if the location changed
|
||||||
*/
|
*/
|
||||||
public boolean goTo(ProgramLocation loc, boolean centerOnScreen) {
|
public boolean goTo(ProgramLocation loc, boolean centerOnScreen) {
|
||||||
|
@ -2104,7 +2131,9 @@ public class ListingCodeComparisonPanel
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the indicated button press listener to both listing panels in this code comparison panel.
|
* Adds the indicated button press listener to both listing panels in this code comparison
|
||||||
|
* panel.
|
||||||
|
*
|
||||||
* @param listener the listener
|
* @param listener the listener
|
||||||
*/
|
*/
|
||||||
public void addButtonPressedListener(ButtonPressedListener listener) {
|
public void addButtonPressedListener(ButtonPressedListener listener) {
|
||||||
|
@ -2127,11 +2156,13 @@ public class ListingCodeComparisonPanel
|
||||||
/**
|
/**
|
||||||
* Gets the indicated (LEFT or RIGHT) side's address that is equivalent to the other side's
|
* Gets the indicated (LEFT or RIGHT) side's address that is equivalent to the other side's
|
||||||
* address.
|
* address.
|
||||||
|
*
|
||||||
* @param leftOrRight LEFT or RIGHT indicating which side's address is needed.
|
* @param leftOrRight LEFT or RIGHT indicating which side's address is needed.
|
||||||
* @param otherSidesAddress the address for the other side. If leftOrRight = LEFT, then this
|
* @param otherSidesAddress the address for the other side. If leftOrRight = LEFT, then this
|
||||||
* should be a right side address. If leftOrRight = RIGHT, then this should be a left side address.
|
* should be a right side address. If leftOrRight = RIGHT, then this should be a left
|
||||||
|
* side address.
|
||||||
* @return an address for the indicated side (LEFT or RIGHT) that is equivalent to the other
|
* @return an address for the indicated side (LEFT or RIGHT) that is equivalent to the other
|
||||||
* side's address that is specified. Otherwise, null.
|
* side's address that is specified. Otherwise, null.
|
||||||
*/
|
*/
|
||||||
private Address getAddress(int leftOrRight, Address otherSidesAddress) {
|
private Address getAddress(int leftOrRight, Address otherSidesAddress) {
|
||||||
if (isFunctionCompare()) {
|
if (isFunctionCompare()) {
|
||||||
|
@ -2144,11 +2175,12 @@ public class ListingCodeComparisonPanel
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets an address in the program indicated by <code>leftOrRight</code> that matches the
|
* Gets an address in the program indicated by <code>leftOrRight</code> that matches the
|
||||||
* <code>otherSidesAddress</code> that is an address in a function in the other program.
|
* <code>otherSidesAddress</code> that is an address in a function in the other program.
|
||||||
|
*
|
||||||
* @param leftOrRight indicates whether to get the address from the LEFT or RIGHT program.
|
* @param leftOrRight indicates whether to get the address from the LEFT or RIGHT program.
|
||||||
* @param otherSidesAddress address in the other program that is equivalent to the
|
* @param otherSidesAddress address in the other program that is equivalent to the desired
|
||||||
* desired address.
|
* address.
|
||||||
* @return the matching address in the indicated program or null.
|
* @return the matching address in the indicated program or null.
|
||||||
*/
|
*/
|
||||||
private Address getFunctionAddress(int leftOrRight, Address otherSidesAddress) {
|
private Address getFunctionAddress(int leftOrRight, Address otherSidesAddress) {
|
||||||
|
@ -2196,6 +2228,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is this panel currently comparing a function match?
|
* Is this panel currently comparing a function match?
|
||||||
|
*
|
||||||
* @return true if comparing functions.
|
* @return true if comparing functions.
|
||||||
*/
|
*/
|
||||||
private boolean isFunctionCompare() {
|
private boolean isFunctionCompare() {
|
||||||
|
@ -2206,6 +2239,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is this panel currently comparing a data match?
|
* Is this panel currently comparing a data match?
|
||||||
|
*
|
||||||
* @return true if comparing data.
|
* @return true if comparing data.
|
||||||
*/
|
*/
|
||||||
private boolean isDataCompare() {
|
private boolean isDataCompare() {
|
||||||
|
@ -2216,6 +2250,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the left side address that is equivalent to the indicated right side address.
|
* Gets the left side address that is equivalent to the indicated right side address.
|
||||||
|
*
|
||||||
* @param rightByteAddress the right side address
|
* @param rightByteAddress the right side address
|
||||||
* @return the left side address or null.
|
* @return the left side address or null.
|
||||||
*/
|
*/
|
||||||
|
@ -2228,6 +2263,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the right side address that is equivalent to the indicated left side address.
|
* Gets the right side address that is equivalent to the indicated left side address.
|
||||||
|
*
|
||||||
* @param leftByteAddress the left side address
|
* @param leftByteAddress the left side address
|
||||||
* @return the right side address or null.
|
* @return the right side address or null.
|
||||||
*/
|
*/
|
||||||
|
@ -2240,6 +2276,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the left side function's entry point address.
|
* Gets the left side function's entry point address.
|
||||||
|
*
|
||||||
* @return the left side function's entry point address or null.
|
* @return the left side function's entry point address or null.
|
||||||
*/
|
*/
|
||||||
private Address getLeftFunctionAddress() {
|
private Address getLeftFunctionAddress() {
|
||||||
|
@ -2251,6 +2288,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the right side function's entry point address.
|
* Gets the right side function's entry point address.
|
||||||
|
*
|
||||||
* @return the right side function's entry point address or null.
|
* @return the right side function's entry point address or null.
|
||||||
*/
|
*/
|
||||||
private Address getRightFunctionAddress() {
|
private Address getRightFunctionAddress() {
|
||||||
|
@ -2262,6 +2300,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the left side data's minimum address.
|
* Gets the left side data's minimum address.
|
||||||
|
*
|
||||||
* @return the left side data's minimum address or null.
|
* @return the left side data's minimum address or null.
|
||||||
*/
|
*/
|
||||||
private Address getLeftDataAddress() {
|
private Address getLeftDataAddress() {
|
||||||
|
@ -2273,6 +2312,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the right side data's minimum address.
|
* Gets the right side data's minimum address.
|
||||||
|
*
|
||||||
* @return the right side data's minimum address or null.
|
* @return the right side data's minimum address or null.
|
||||||
*/
|
*/
|
||||||
private Address getRightDataAddress() {
|
private Address getRightDataAddress() {
|
||||||
|
@ -2381,6 +2421,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the left or right listing panel that contains the indicated field panel.
|
* Gets the left or right listing panel that contains the indicated field panel.
|
||||||
|
*
|
||||||
* @param fieldPanel the field panel
|
* @param fieldPanel the field panel
|
||||||
* @return the listing panel or null.
|
* @return the listing panel or null.
|
||||||
*/
|
*/
|
||||||
|
@ -2401,6 +2442,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disable mouse navigation from within this dual listing panel.
|
* Disable mouse navigation from within this dual listing panel.
|
||||||
|
*
|
||||||
* @param enabled false disables navigation
|
* @param enabled false disables navigation
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -2448,6 +2490,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the maximum offset based on the larger data that is passed to this method.
|
* Gets the maximum offset based on the larger data that is passed to this method.
|
||||||
|
*
|
||||||
* @param leftData the left view's data
|
* @param leftData the left view's data
|
||||||
* @param rightData the right view's data
|
* @param rightData the right view's data
|
||||||
* @return the maximum offset (one less than the larger data item's size).
|
* @return the maximum offset (one less than the larger data item's size).
|
||||||
|
@ -2466,10 +2509,11 @@ public class ListingCodeComparisonPanel
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the ending address to be displayed. It tries to get an ending address that is
|
* Gets the ending address to be displayed. It tries to get an ending address that is maxOffset
|
||||||
* maxOffset number of bytes beyond the minAddress without leaving the memory block
|
* number of bytes beyond the minAddress without leaving the memory block that contains the
|
||||||
* that contains the minAddress. If the maxOffset is beyond the end of the block then
|
* minAddress. If the maxOffset is beyond the end of the block then the end of the block is
|
||||||
* the end of the block is returned. For an externalAddress the minAddress is returned.
|
* returned. For an externalAddress the minAddress is returned.
|
||||||
|
*
|
||||||
* @param program the program containing the data
|
* @param program the program containing the data
|
||||||
* @param maxOffset the max offset
|
* @param maxOffset the max offset
|
||||||
* @param minAddress the minimum address of the data
|
* @param minAddress the minimum address of the data
|
||||||
|
@ -2495,8 +2539,8 @@ public class ListingCodeComparisonPanel
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the address correlation being used with the ListingDiff and the dual listing
|
* Clears the address correlation being used with the ListingDiff and the dual listing field
|
||||||
* field panel coordinator.
|
* panel coordinator.
|
||||||
*/
|
*/
|
||||||
private void clearCorrelation() {
|
private void clearCorrelation() {
|
||||||
correlator = null;
|
correlator = null;
|
||||||
|
@ -2516,6 +2560,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the data loaded in the left listing panel.
|
* Gets the data loaded in the left listing panel.
|
||||||
|
*
|
||||||
* @return the data or null
|
* @return the data or null
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -2525,6 +2570,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the data loaded in the right listing panel.
|
* Gets the data loaded in the right listing panel.
|
||||||
|
*
|
||||||
* @return the data or null
|
* @return the data or null
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -2560,6 +2606,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays the indicated text int the tool's status area.
|
* Displays the indicated text int the tool's status area.
|
||||||
|
*
|
||||||
* @param text the message to display
|
* @param text the message to display
|
||||||
*/
|
*/
|
||||||
void setStatusInfo(String text) {
|
void setStatusInfo(String text) {
|
||||||
|
@ -2621,8 +2668,9 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the GoToService that is used for either the left listing or the right listing.
|
* Gets the GoToService that is used for either the left listing or the right listing.
|
||||||
* @param isLeftSide true means get the GoToService for the left side listing.
|
*
|
||||||
* false means get it for the right side listing.
|
* @param isLeftSide true means get the GoToService for the left side listing. false means get
|
||||||
|
* it for the right side listing.
|
||||||
* @return the goToService
|
* @return the goToService
|
||||||
*/
|
*/
|
||||||
GoToService getGoToService(boolean isLeftSide) {
|
GoToService getGoToService(boolean isLeftSide) {
|
||||||
|
@ -2661,9 +2709,10 @@ public class ListingCodeComparisonPanel
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a marker margin or overview margin context object if the mouse event occurred on one
|
* Gets a marker margin or overview margin context object if the mouse event occurred on one of
|
||||||
* of the GUI components for the indicated listing panel's marker margin (left edge of listing)
|
* the GUI components for the indicated listing panel's marker margin (left edge of listing) or
|
||||||
* or overview margin (right edge of listing).
|
* overview margin (right edge of listing).
|
||||||
|
*
|
||||||
* @param lp The listing panel to check
|
* @param lp The listing panel to check
|
||||||
* @param event the mouse event
|
* @param event the mouse event
|
||||||
* @return a marker margin context object if the event was on a margin.
|
* @return a marker margin context object if the event was on a margin.
|
||||||
|
@ -2733,6 +2782,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restores this panel to the indicated saved configuration state.
|
* Restores this panel to the indicated saved configuration state.
|
||||||
|
*
|
||||||
* @param prefix identifier to prepend to any save state names to make them unique.
|
* @param prefix identifier to prepend to any save state names to make them unique.
|
||||||
* @param saveState the configuration state to restore
|
* @param saveState the configuration state to restore
|
||||||
*/
|
*/
|
||||||
|
@ -2743,6 +2793,7 @@ public class ListingCodeComparisonPanel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves the current configuration state of this panel.
|
* Saves the current configuration state of this panel.
|
||||||
|
*
|
||||||
* @param prefix identifier to prepend to any save state names to make them unique.
|
* @param prefix identifier to prepend to any save state names to make them unique.
|
||||||
* @param saveState the new configuration state
|
* @param saveState the new configuration state
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -260,7 +260,7 @@ public class ListingPanel extends JPanel implements FieldMouseListener, FieldLoc
|
||||||
private void updateProviders() {
|
private void updateProviders() {
|
||||||
AddressIndexMap addressIndexMap = layoutModel.getAddressIndexMap();
|
AddressIndexMap addressIndexMap = layoutModel.getAddressIndexMap();
|
||||||
for (OverviewProvider element : overviewProviders) {
|
for (OverviewProvider element : overviewProviders) {
|
||||||
element.setAddressIndexMap(addressIndexMap);
|
element.setProgram(getProgram(), addressIndexMap);
|
||||||
}
|
}
|
||||||
for (ChangeListener indexMapChangeListener : indexMapChangeListeners) {
|
for (ChangeListener indexMapChangeListener : indexMapChangeListeners) {
|
||||||
indexMapChangeListener.stateChanged(null);
|
indexMapChangeListener.stateChanged(null);
|
||||||
|
@ -294,7 +294,7 @@ public class ListingPanel extends JPanel implements FieldMouseListener, FieldLoc
|
||||||
else {
|
else {
|
||||||
marginProviders.add(provider);
|
marginProviders.add(provider);
|
||||||
}
|
}
|
||||||
provider.setPixelMap(pixmap);
|
provider.setProgram(getProgram(), layoutModel.getAddressIndexMap(), pixmap);
|
||||||
buildPanels();
|
buildPanels();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,7 +408,7 @@ public class ListingPanel extends JPanel implements FieldMouseListener, FieldLoc
|
||||||
*/
|
*/
|
||||||
public void addOverviewProvider(OverviewProvider provider) {
|
public void addOverviewProvider(OverviewProvider provider) {
|
||||||
overviewProviders.add(provider);
|
overviewProviders.add(provider);
|
||||||
provider.setAddressIndexMap(layoutModel.getAddressIndexMap());
|
provider.setProgram(getProgram(), layoutModel.getAddressIndexMap());
|
||||||
buildPanels();
|
buildPanels();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,9 +474,10 @@ public class ListingPanel extends JPanel implements FieldMouseListener, FieldLoc
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void layoutsChanged(List<AnchoredLayout> layouts) {
|
public void layoutsChanged(List<AnchoredLayout> layouts) {
|
||||||
this.pixmap = new VerticalPixelAddressMapImpl(layouts, layoutModel.getAddressIndexMap());
|
AddressIndexMap addrMap = layoutModel.getAddressIndexMap();
|
||||||
|
this.pixmap = new VerticalPixelAddressMapImpl(layouts, addrMap);
|
||||||
for (MarginProvider element : marginProviders) {
|
for (MarginProvider element : marginProviders) {
|
||||||
element.setPixelMap(pixmap);
|
element.setProgram(getProgram(), addrMap, pixmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (AddressSetDisplayListener listener : displayListeners) {
|
for (AddressSetDisplayListener listener : displayListeners) {
|
||||||
|
@ -1061,7 +1062,7 @@ public class ListingPanel extends JPanel implements FieldMouseListener, FieldLoc
|
||||||
}
|
}
|
||||||
|
|
||||||
Layout layout2 = layoutModel.getLayout(loc2.getIndex());
|
Layout layout2 = layoutModel.getLayout(loc2.getIndex());
|
||||||
|
|
||||||
if (fieldNum1 >= 0 && layout2 != null) {
|
if (fieldNum1 >= 0 && layout2 != null) {
|
||||||
BigInteger index2 = loc2.getIndex();
|
BigInteger index2 = loc2.getIndex();
|
||||||
int fieldNum2 = layout.getEndRowFieldNum(loc2.getFieldNum());
|
int fieldNum2 = layout.getEndRowFieldNum(loc2.getFieldNum());
|
||||||
|
@ -1122,8 +1123,9 @@ public class ListingPanel extends JPanel implements FieldMouseListener, FieldLoc
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the currently selected text. The value will only be non-null for selections within
|
* Returns the currently selected text. The value will only be non-null for selections within a
|
||||||
* a single field.
|
* single field.
|
||||||
|
*
|
||||||
* @return the selected text or null
|
* @return the selected text or null
|
||||||
*/
|
*/
|
||||||
public String getTextSelection() {
|
public String getTextSelection() {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,12 +15,14 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.util.viewer.listingpanel;
|
package ghidra.app.util.viewer.listingpanel;
|
||||||
|
|
||||||
import ghidra.program.util.MarkerLocation;
|
|
||||||
|
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
|
||||||
|
import ghidra.app.util.viewer.util.AddressIndexMap;
|
||||||
|
import ghidra.program.model.listing.Program;
|
||||||
|
import ghidra.program.util.MarkerLocation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for objects that want to add a component to the listings left margin.
|
* Interface for objects that want to add a component to the listing's left margin.
|
||||||
*/
|
*/
|
||||||
public interface MarginProvider {
|
public interface MarginProvider {
|
||||||
|
|
||||||
|
@ -36,13 +37,18 @@ public interface MarginProvider {
|
||||||
boolean isResizeable();
|
boolean isResizeable();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the vertical pixel layout map.
|
* Set the program and associated maps.
|
||||||
* @param pixmap the vertical pixel map to use.
|
*
|
||||||
|
* @param program the program to use.
|
||||||
|
* @param addressIndexMap the address-index map to use.
|
||||||
|
* @param pixelMap the vertical pixel map to use.
|
||||||
*/
|
*/
|
||||||
void setPixelMap(VerticalPixelAddressMap pixmap);
|
void setProgram(Program program, AddressIndexMap addressIndexMap,
|
||||||
|
VerticalPixelAddressMap pixelMap);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the marker location for the given x, y point.
|
* Get the marker location for the given x, y point.
|
||||||
|
*
|
||||||
* @param x the horizontal coordinate.
|
* @param x the horizontal coordinate.
|
||||||
* @param y the vertical coordinate.
|
* @param y the vertical coordinate.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,25 +15,34 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.util.viewer.listingpanel;
|
package ghidra.app.util.viewer.listingpanel;
|
||||||
|
|
||||||
import ghidra.app.util.viewer.util.AddressIndexMap;
|
|
||||||
|
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
|
||||||
|
import ghidra.app.nav.Navigatable;
|
||||||
|
import ghidra.app.util.viewer.util.AddressIndexMap;
|
||||||
|
import ghidra.program.model.listing.Program;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface implemented by classes that provide overview components to the right side
|
* Interface implemented by classes that provide overview components to the right side of the
|
||||||
* of the listing.
|
* listing.
|
||||||
*/
|
*/
|
||||||
public interface OverviewProvider {
|
public interface OverviewProvider {
|
||||||
/**
|
/**
|
||||||
* Returns the component to diplay in the right margin of the listing.
|
* Returns the component to diplay in the right margin of the listing.
|
||||||
*/
|
*/
|
||||||
JComponent getComponent();
|
JComponent getComponent();
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the AddressIndexMap whenever it changes so that the overview provider has
|
|
||||||
* an current map.
|
|
||||||
* @param map the current AddressIndexMap of the ListingPanel
|
|
||||||
*/
|
|
||||||
void setAddressIndexMap(AddressIndexMap map);
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current program and associated address-index map
|
||||||
|
*
|
||||||
|
* @param program the program to use.
|
||||||
|
* @param addressIndexMap the address-index map to use.
|
||||||
|
*/
|
||||||
|
void setProgram(Program program, AddressIndexMap map);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the component provider that this overview navigates
|
||||||
|
*
|
||||||
|
* @param navigatable the navigatable provider
|
||||||
|
*/
|
||||||
|
void setNavigatable(Navigatable navigatable);
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,12 +65,11 @@ import ghidra.util.task.*;
|
||||||
import resources.ResourceManager;
|
import resources.ResourceManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plugin that shows the differences between two programs, and allows the
|
* Plugin that shows the differences between two programs, and allows the user to apply differences
|
||||||
* user to apply differences to the currently open program. This allows only one
|
* to the currently open program. This allows only one tabbed program to display a second program
|
||||||
* tabbed program to display a second program (possibly with an active Diff).
|
* (possibly with an active Diff). It allows the active program to change without losing the current
|
||||||
* It allows the active program to change without losing the current Diff or
|
* Diff or second program that is opened. De-activation of the first program for the Diff will
|
||||||
* second program that is opened. De-activation of the first program for the Diff
|
* result in termination of the Diff or the Diff can be closed directly by the user.
|
||||||
* will result in termination of the Diff or the Diff can be closed directly by the user.
|
|
||||||
*/
|
*/
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
@PluginInfo(
|
@PluginInfo(
|
||||||
|
@ -151,6 +150,7 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the plugin for indicating program differences to the user.
|
* Creates the plugin for indicating program differences to the user.
|
||||||
|
*
|
||||||
* @param tool the tool that owns this plugin.
|
* @param tool the tool that owns this plugin.
|
||||||
*/
|
*/
|
||||||
public ProgramDiffPlugin(PluginTool tool) {
|
public ProgramDiffPlugin(PluginTool tool) {
|
||||||
|
@ -282,7 +282,7 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
||||||
AddressSet p1AddressSetAsP2 =
|
AddressSet p1AddressSetAsP2 =
|
||||||
DiffUtility.getCompatibleAddressSet(p1AddressSet, secondaryDiffProgram);
|
DiffUtility.getCompatibleAddressSet(p1AddressSet, secondaryDiffProgram);
|
||||||
AddressIndexMap p2IndexMap = new AddressIndexMap(p1AddressSetAsP2);
|
AddressIndexMap p2IndexMap = new AddressIndexMap(p1AddressSetAsP2);
|
||||||
markerManager.getOverviewProvider().setAddressIndexMap(p2IndexMap);
|
markerManager.getOverviewProvider().setProgram(secondaryDiffProgram, p2IndexMap);
|
||||||
fp.setBackgroundColorModel(
|
fp.setBackgroundColorModel(
|
||||||
new MarkerServiceBackgroundColorModel(markerManager, p2IndexMap));
|
new MarkerServiceBackgroundColorModel(markerManager, p2IndexMap));
|
||||||
|
|
||||||
|
@ -479,8 +479,9 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a program gets closed.
|
* Called when a program gets closed. If the closed program is the first program of the Diff
|
||||||
* If the closed program is the first program of the Diff then we need to close the second program.
|
* then we need to close the second program.
|
||||||
|
*
|
||||||
* @param program
|
* @param program
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -719,8 +720,8 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
||||||
/**
|
/**
|
||||||
* Callback when user changes selection in the program2 diff panel.
|
* Callback when user changes selection in the program2 diff panel.
|
||||||
*
|
*
|
||||||
* Note: A P2 selection is handed to this method when a selection is made in the diff
|
* Note: A P2 selection is handed to this method when a selection is made in the diff listing
|
||||||
* listing which displays P2.
|
* which displays P2.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void programSelectionChanged(ProgramSelection newP2Selection) {
|
public void programSelectionChanged(ProgramSelection newP2Selection) {
|
||||||
|
@ -838,8 +839,9 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the highlight based on the current program differences, but
|
* Set the highlight based on the current program differences, but do not set the highlight for
|
||||||
* do not set the highlight for set of addresses to be ignored.
|
* set of addresses to be ignored.
|
||||||
|
*
|
||||||
* @param ignoreAddressSet the set of addresses to ignore.
|
* @param ignoreAddressSet the set of addresses to ignore.
|
||||||
*/
|
*/
|
||||||
private void setDiffHighlight() {
|
private void setDiffHighlight() {
|
||||||
|
@ -849,7 +851,7 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
||||||
|
|
||||||
AddressSetView p1DiffSet = null;
|
AddressSetView p1DiffSet = null;
|
||||||
try {
|
try {
|
||||||
p1DiffSet = diffControl.getFilteredDifferences(TaskMonitorAdapter.DUMMY_MONITOR);
|
p1DiffSet = diffControl.getFilteredDifferences(TaskMonitor.DUMMY);
|
||||||
}
|
}
|
||||||
catch (CancelledException e) {
|
catch (CancelledException e) {
|
||||||
// Shouldn't get this, since using a DUMMY_MONITOR.
|
// Shouldn't get this, since using a DUMMY_MONITOR.
|
||||||
|
@ -940,16 +942,17 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the differences between program1 and program2 that are displayed
|
* Computes the differences between program1 and program2 that are displayed in the browser
|
||||||
* in the browser using the current Limiting set. It allows the user to specify the Diff settings to use.
|
* using the current Limiting set. It allows the user to specify the Diff settings to use.
|
||||||
*/
|
*/
|
||||||
void diff() {
|
void diff() {
|
||||||
diff(createLimitingSet());
|
diff(createLimitingSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the differences between program1 and program2 that are displayed
|
* Computes the differences between program1 and program2 that are displayed in the browser. It
|
||||||
* in the browser. It allows the user to specify the Diff settings to use.
|
* allows the user to specify the Diff settings to use.
|
||||||
|
*
|
||||||
* @param p1LimitSet an address set to use to limit the extent of the Diff.
|
* @param p1LimitSet an address set to use to limit the extent of the Diff.
|
||||||
*/
|
*/
|
||||||
void diff(AddressSetView p1LimitSet) {
|
void diff(AddressSetView p1LimitSet) {
|
||||||
|
@ -1055,7 +1058,6 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
||||||
setProgram2Selection(p2Selection);
|
setProgram2Selection(p2Selection);
|
||||||
clearDiff();
|
clearDiff();
|
||||||
if (secondaryDiffProgram != null) {
|
if (secondaryDiffProgram != null) {
|
||||||
markerManager.setProgram(null);
|
|
||||||
Iterator<BookmarkNavigator> iter = bookmarkMap.values().iterator();
|
Iterator<BookmarkNavigator> iter = bookmarkMap.values().iterator();
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
BookmarkNavigator nav = iter.next();
|
BookmarkNavigator nav = iter.next();
|
||||||
|
@ -1171,10 +1173,11 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the first program for the current Diff.
|
* Get the first program for the current Diff. <br>
|
||||||
* <br><b>Note</b>: This may not be the currently active program.
|
* <b>Note</b>: This may not be the currently active program.
|
||||||
* @return the Diff's first program or null if don't currently have a
|
*
|
||||||
* second program associated for a Diff.
|
* @return the Diff's first program or null if don't currently have a second program associated
|
||||||
|
* for a Diff.
|
||||||
*/
|
*/
|
||||||
Program getFirstProgram() {
|
Program getFirstProgram() {
|
||||||
return primaryProgram;
|
return primaryProgram;
|
||||||
|
@ -1182,8 +1185,9 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the second program for the current Diff.
|
* Get the second program for the current Diff.
|
||||||
* @return the Diff's second program or null if don't currently have a
|
*
|
||||||
* second program associated for a Diff.
|
* @return the Diff's second program or null if don't currently have a second program associated
|
||||||
|
* for a Diff.
|
||||||
*/
|
*/
|
||||||
Program getSecondProgram() {
|
Program getSecondProgram() {
|
||||||
return secondaryDiffProgram;
|
return secondaryDiffProgram;
|
||||||
|
@ -1238,10 +1242,11 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
||||||
* Gets the address set where detailed differences will be determined for details at the
|
* Gets the address set where detailed differences will be determined for details at the
|
||||||
* indicated address. An address set is returned since the indicated address may be in different
|
* indicated address. An address set is returned since the indicated address may be in different
|
||||||
* sized code units in each of the two programs.
|
* sized code units in each of the two programs.
|
||||||
|
*
|
||||||
* @param p1Address the current address from program1 where details are desired.
|
* @param p1Address the current address from program1 where details are desired.
|
||||||
* @return the address set for code units containing that address within the programs being
|
* @return the address set for code units containing that address within the programs being
|
||||||
* compared to determine differences.
|
* compared to determine differences. Otherwise null if a diff of two programs isn't
|
||||||
* Otherwise null if a diff of two programs isn't being performed.
|
* being performed.
|
||||||
*/
|
*/
|
||||||
AddressSetView getDetailsAddressSet(Address p1Address) {
|
AddressSetView getDetailsAddressSet(Address p1Address) {
|
||||||
if (diffDetails != null) {
|
if (diffDetails != null) {
|
||||||
|
@ -1598,7 +1603,6 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
||||||
finally {
|
finally {
|
||||||
settingLocation = false;
|
settingLocation = false;
|
||||||
}
|
}
|
||||||
markerManager.setProgram(secondaryDiffProgram);
|
|
||||||
setupBookmarkNavigators();
|
setupBookmarkNavigators();
|
||||||
|
|
||||||
sameProgramContext = ProgramMemoryComparator.sameProgramContextRegisterNames(primaryProgram,
|
sameProgramContext = ProgramMemoryComparator.sameProgramContextRegisterNames(primaryProgram,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue