mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-02-07 19:20:14 +00: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
@ -484,9 +484,12 @@ public class DebuggerBreakpointMarkerPlugin extends Plugin
|
||||
private class ToggleBreakpointsMarkerClickedListener implements MarkerClickedListener {
|
||||
@Override
|
||||
public void markerDoubleClicked(MarkerLocation location) {
|
||||
doToggleBreakpointsAt(ToggleBreakpointAction.NAME,
|
||||
ProgramLocationActionContext context =
|
||||
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) {
|
||||
return Set.of();
|
||||
}
|
||||
ProgramLocation loc = getLocationFromContext(context); // must be static location
|
||||
if (loc == null) {
|
||||
ProgramLocation loc = getLocationFromContext(context);
|
||||
if (loc == null || loc.getProgram() instanceof TraceProgramView) {
|
||||
return Set.of();
|
||||
}
|
||||
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.utils.ProgramLocationUtils;
|
||||
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.DebuggerListingService.LocationTrackingSpecChangeListener;
|
||||
import ghidra.app.util.viewer.format.FormatManager;
|
||||
@ -266,6 +268,8 @@ public class DebuggerListingProvider extends CodeViewerProvider {
|
||||
protected final MultiBlendedListingBackgroundColorModel colorModel;
|
||||
protected final MarkerSetChangeListener markerChangeListener = new MarkerSetChangeListener();
|
||||
protected MarkerServiceBackgroundColorModel markerServiceColorModel;
|
||||
protected MarkerMarginProvider markerMarginProvider;
|
||||
protected MarkerOverviewProvider markerOverviewProvider;
|
||||
|
||||
private SuppressableCallback<ProgramLocation> cbGoTo = new SuppressableCallback<>();
|
||||
|
||||
@ -500,6 +504,10 @@ public class DebuggerListingProvider extends CodeViewerProvider {
|
||||
private void setMarkerService(MarkerService markerService) {
|
||||
if (this.markerService != null) {
|
||||
this.markerService.removeChangeListener(markerChangeListener);
|
||||
removeMarginProvider(markerMarginProvider);
|
||||
markerMarginProvider = null;
|
||||
removeOverviewProvider(markerOverviewProvider);
|
||||
markerOverviewProvider = null;
|
||||
}
|
||||
removeOldStaticTrackingMarker();
|
||||
this.markerService = markerService;
|
||||
@ -510,6 +518,12 @@ public class DebuggerListingProvider extends CodeViewerProvider {
|
||||
// NOTE: Connected provider marker listener is taken care of by CodeBrowserPlugin
|
||||
this.markerService.addChangeListener(markerChangeListener);
|
||||
}
|
||||
if (this.markerService != null) {
|
||||
markerMarginProvider = markerService.createMarginProvider();
|
||||
addMarginProvider(markerMarginProvider);
|
||||
markerOverviewProvider = markerService.createOverviewProvider();
|
||||
addOverviewProvider(markerOverviewProvider);
|
||||
}
|
||||
}
|
||||
|
||||
@AutoServiceConsumed
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -16,15 +15,15 @@
|
||||
*/
|
||||
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.KeyEvent;
|
||||
|
||||
import docking.ActionContext;
|
||||
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.
|
||||
@ -34,8 +33,8 @@ class AddBookmarkAction extends DockingAction {
|
||||
BookmarkPlugin plugin;
|
||||
|
||||
/**
|
||||
* Creates a new action with the given name and associated to the given
|
||||
* plugin.
|
||||
* Creates a new action with the given name and associated to the given plugin.
|
||||
*
|
||||
* @param name the name for this action.
|
||||
* @param plugin the plugin this action is associated with.
|
||||
*/
|
||||
@ -51,11 +50,12 @@ class AddBookmarkAction extends DockingAction {
|
||||
|
||||
/**
|
||||
* Method called when the action is invoked.
|
||||
*
|
||||
* @param ActionEvent details regarding the invocation of this action
|
||||
*/
|
||||
@Override
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
return getAddress(context) != null;
|
||||
return getAddress(context) != null && getProgram(context) == plugin.getCurrentProgram();
|
||||
}
|
||||
|
||||
private Address getAddress(ActionContext context) {
|
||||
@ -80,4 +80,15 @@ class AddBookmarkAction extends DockingAction {
|
||||
}
|
||||
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
|
||||
* before the plugin is destroyed.
|
||||
* Get rid of any resources this plugin is using before the plugin is destroyed.
|
||||
*/
|
||||
@Override
|
||||
public synchronized void dispose() {
|
||||
@ -276,6 +275,7 @@ public class BookmarkPlugin extends ProgramPlugin
|
||||
|
||||
/**
|
||||
* Get or create a bookmark navigator for the specified bookmark type
|
||||
*
|
||||
* @param type the bookmark type
|
||||
* @return bookmark navigator
|
||||
*/
|
||||
@ -432,9 +432,12 @@ public class BookmarkPlugin extends ProgramPlugin
|
||||
bookmarkMgr = program.getBookmarkManager();
|
||||
}
|
||||
|
||||
void showAddBookmarkDialog(Address location) {
|
||||
void showAddBookmarkDialog(Address address, Program program) {
|
||||
if (program != currentProgram) {
|
||||
return;
|
||||
}
|
||||
Listing listing = currentProgram.getListing();
|
||||
CodeUnit currCU = listing.getCodeUnitContaining(location);
|
||||
CodeUnit currCU = listing.getCodeUnitContaining(address);
|
||||
if (currCU == null) {
|
||||
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
|
||||
*
|
||||
* @param addr bookmark address. If null a Note bookmark will set at the
|
||||
* start address of each range in the current selection
|
||||
* @param addr bookmark address. If null a Note bookmark will set at the start address of each
|
||||
* range in the current selection
|
||||
* @param category bookmark category
|
||||
* @param comment comment text
|
||||
*/
|
||||
@ -494,6 +497,9 @@ public class BookmarkPlugin extends ProgramPlugin
|
||||
return null;
|
||||
}
|
||||
MarkerLocation loc = (MarkerLocation) contextObject;
|
||||
if (loc.getProgram() != currentProgram) {
|
||||
return null;
|
||||
}
|
||||
BookmarkManager mgr = currentProgram.getBookmarkManager();
|
||||
Address address = loc.getAddr();
|
||||
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
|
||||
* given 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.
|
||||
* @return a list of actions to delete bookmarks that are in the code unit surrounding the
|
||||
* given address.
|
||||
* Returns a list of actions to delete bookmarks that are in the code unit surrounding the given
|
||||
* 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.
|
||||
* @return a list of actions to delete bookmarks that are in the code unit surrounding the given
|
||||
* address.
|
||||
*/
|
||||
private List<DockingActionIf> getActionsForCodeUnit(Address primaryAddress,
|
||||
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
|
||||
* given address <b>for the given <i>type</i> of bookmark</b>.
|
||||
* Returns a list of actions to delete bookmarks that are in the code unit surrounding the given
|
||||
* address <b>for the given <i>type</i> of bookmark</b>.
|
||||
*
|
||||
* @param primaryAddress The address required to find the containing code unit.
|
||||
* @param type The bookmark type to retrieve.
|
||||
* @param navigator The BookmarkNavigator used to determine whether there are bookmarks
|
||||
* inside 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
|
||||
* given address <b>for the given <i>type</i> of bookmark</b>.
|
||||
* @param navigator The BookmarkNavigator used to determine whether there are bookmarks inside
|
||||
* 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 given
|
||||
* address <b>for the given <i>type</i> of bookmark</b>.
|
||||
*/
|
||||
private List<DockingActionIf> getActionsForCodeUnitAndType(Address primaryAddress, String type,
|
||||
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
|
||||
* <tt>actionList</tt> is less than the given {@link #MAX_DELETE_ACTIONS}.
|
||||
*
|
||||
* @param actionList The list to add to
|
||||
* @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,
|
||||
List<DockingActionIf> newActionList, int maxActionCount) {
|
||||
|
@ -16,8 +16,6 @@
|
||||
package ghidra.app.plugin.core.codebrowser;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -84,7 +82,6 @@ public abstract class AbstractCodeBrowserPlugin<P extends CodeViewerProvider> ex
|
||||
private MarkerSet currentHighlightMarkers;
|
||||
private MarkerSet currentCursorMarkers;
|
||||
private ChangeListener markerChangeListener;
|
||||
private FocusingMouseListener focusingMouseListener = new FocusingMouseListener();
|
||||
|
||||
private Color cursorHighlightColor;
|
||||
private boolean isHighlightCursorLine;
|
||||
@ -269,36 +266,22 @@ public abstract class AbstractCodeBrowserPlugin<P extends CodeViewerProvider> ex
|
||||
|
||||
@Override
|
||||
public void addOverviewProvider(OverviewProvider overviewProvider) {
|
||||
JComponent component = overviewProvider.getComponent();
|
||||
|
||||
// just in case we get repeated calls
|
||||
component.removeMouseListener(focusingMouseListener);
|
||||
component.addMouseListener(focusingMouseListener);
|
||||
connectedProvider.getListingPanel().addOverviewProvider(overviewProvider);
|
||||
connectedProvider.addOverviewProvider(overviewProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addMarginProvider(MarginProvider marginProvider) {
|
||||
JComponent component = marginProvider.getComponent();
|
||||
|
||||
// just in case we get repeated calls
|
||||
component.removeMouseListener(focusingMouseListener);
|
||||
component.addMouseListener(focusingMouseListener);
|
||||
connectedProvider.getListingPanel().addMarginProvider(marginProvider);
|
||||
connectedProvider.addMarginProvider(marginProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeOverviewProvider(OverviewProvider overviewProvider) {
|
||||
JComponent component = overviewProvider.getComponent();
|
||||
component.removeMouseListener(focusingMouseListener);
|
||||
connectedProvider.getListingPanel().removeOverviewProvider(overviewProvider);
|
||||
connectedProvider.removeOverviewProvider(overviewProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeMarginProvider(MarginProvider marginProvider) {
|
||||
JComponent component = marginProvider.getComponent();
|
||||
component.removeMouseListener(focusingMouseListener);
|
||||
connectedProvider.getListingPanel().removeMarginProvider(marginProvider);
|
||||
connectedProvider.removeMarginProvider(marginProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -927,12 +910,4 @@ public abstract class AbstractCodeBrowserPlugin<P extends CodeViewerProvider> ex
|
||||
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.Transferable;
|
||||
import java.awt.dnd.*;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.*;
|
||||
|
||||
@ -100,6 +101,8 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
|
||||
private FormatManager formatMgr;
|
||||
private FieldPanelCoordinator coordinator;
|
||||
|
||||
private FocusingMouseListener focusingMouseListener;
|
||||
|
||||
private CodeBrowserClipboardProvider codeViewerClipboardProvider;
|
||||
private ClipboardService clipboardService;
|
||||
|
||||
@ -1011,6 +1014,45 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
|
||||
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
|
||||
//==================================================================================================
|
||||
@ -1092,4 +1134,11 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
|
||||
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);
|
||||
Color color = null;
|
||||
if (addr != null) {
|
||||
if (program == null) {
|
||||
color = markerService.getBackgroundColor(addr);
|
||||
}
|
||||
else {
|
||||
if (program != null) {
|
||||
color = markerService.getBackgroundColor(program, addr);
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ import ghidra.app.plugin.PluginCategoryNames;
|
||||
import ghidra.app.services.CodeViewerService;
|
||||
import ghidra.app.util.viewer.listingpanel.*;
|
||||
import ghidra.app.util.viewer.options.OptionsGui;
|
||||
import ghidra.app.util.viewer.util.AddressIndexMap;
|
||||
import ghidra.framework.options.OptionsChangeListener;
|
||||
import ghidra.framework.options.ToolOptions;
|
||||
import ghidra.framework.plugintool.*;
|
||||
@ -138,7 +139,8 @@ public class FlowArrowPlugin extends Plugin implements MarginProvider, OptionsCh
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPixelMap(VerticalPixelAddressMap pixmap) {
|
||||
public void setProgram(Program program, AddressIndexMap addrMap,
|
||||
VerticalPixelAddressMap pixmap) {
|
||||
this.layoutToPixel = pixmap;
|
||||
validateState();
|
||||
updateFlowArrows();
|
||||
@ -334,9 +336,10 @@ public class FlowArrowPlugin extends Plugin implements MarginProvider, OptionsCh
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* 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) {
|
||||
|
||||
@ -430,8 +433,9 @@ public class FlowArrowPlugin extends Plugin implements MarginProvider, OptionsCh
|
||||
|
||||
List<FlowArrow> results = new ArrayList<>();
|
||||
ArrowCache arrowCache = new ArrowCache();
|
||||
CodeUnitIterator it = program.getListing().getCodeUnitIterator(
|
||||
CodeUnit.INSTRUCTION_PROPERTY, screenAddresses, true);
|
||||
CodeUnitIterator it = program.getListing()
|
||||
.getCodeUnitIterator(
|
||||
CodeUnit.INSTRUCTION_PROPERTY, screenAddresses, true);
|
||||
|
||||
while (it.hasNext()) {
|
||||
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.
|
||||
* Further, we rebuild arrows as the screen moves, causing the x coordinate
|
||||
* to change as arrows that are no longer on the screen are removed and
|
||||
* as new arrows are added. We want to make sure that we don't end up
|
||||
* with an arrow in the selected/active sets that are the same as the one
|
||||
* in the 'all' set, but with a different width. This causes both arrows
|
||||
* to become visible--basically, the selected arrows can become stale as
|
||||
* their width changes. This code is meant to address this out-of-sync
|
||||
* behavior.
|
||||
* Further, we rebuild arrows as the screen moves, causing the x coordinate to change as arrows
|
||||
* that are no longer on the screen are removed and as new arrows are added. We want to make
|
||||
* sure that we don't end up with an arrow in the selected/active sets that are the same as the
|
||||
* one in the 'all' set, but with a different width. This causes both arrows to become
|
||||
* visible--basically, the selected arrows can become stale as their width changes. This code is
|
||||
* meant to address this out-of-sync behavior.
|
||||
*
|
||||
* @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);
|
||||
if (bottomAddr != null) {
|
||||
AddressSpace testSpace = bottomAddr.getAddressSpace();
|
||||
validState = (program.getAddressFactory().getAddressSpace(
|
||||
validState = (program.getAddressFactory()
|
||||
.getAddressSpace(
|
||||
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.app.CorePluginPackage;
|
||||
import ghidra.app.events.ProgramActivatedPluginEvent;
|
||||
import ghidra.app.events.ProgramClosedPluginEvent;
|
||||
import ghidra.app.plugin.PluginCategoryNames;
|
||||
import ghidra.app.services.*;
|
||||
import ghidra.app.util.HelpTopics;
|
||||
import ghidra.framework.options.Options;
|
||||
import ghidra.framework.plugintool.*;
|
||||
import ghidra.framework.plugintool.util.PluginStatus;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.util.HelpLocation;
|
||||
|
||||
/**
|
||||
* Plugin to manage marker and navigation panels.
|
||||
*
|
||||
*
|
||||
*/
|
||||
//@formatter:off
|
||||
@PluginInfo(
|
||||
status = PluginStatus.RELEASED,
|
||||
packageName = CorePluginPackage.NAME,
|
||||
category = PluginCategoryNames.SUPPORT,
|
||||
shortDescription = "Provides the marker display",
|
||||
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 "
|
||||
+ "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 "
|
||||
+ "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 "
|
||||
+ "value such as selection. Point markers are used to represent individual addresses such "
|
||||
+ "as bookmarks.",
|
||||
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 " +
|
||||
"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 " +
|
||||
"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 " +
|
||||
"value such as selection. Point markers are used to represent individual addresses such " +
|
||||
"as bookmarks.",
|
||||
servicesRequired = { CodeViewerService.class, GoToService.class },
|
||||
servicesProvided = { MarkerService.class },
|
||||
eventsConsumed = { ProgramActivatedPluginEvent.class, ProgramClosedPluginEvent.class }
|
||||
)
|
||||
//@formatter:on
|
||||
eventsConsumed = {})
|
||||
public class MarkerManagerPlugin extends Plugin {
|
||||
|
||||
private CodeViewerService codeViewerService;
|
||||
private MarkerManager markerManager;
|
||||
private Program program;
|
||||
|
||||
/**
|
||||
* @param tool
|
||||
@ -87,23 +78,4 @@ public class MarkerManagerPlugin extends Plugin {
|
||||
codeViewerService.addMarginProvider(markerManager.getMarginProvider());
|
||||
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;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
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
|
||||
* of the scrolled field panel.
|
||||
* Panel to display markers. Normally placed to the left hand side of the scrolled
|
||||
* {@link FieldPanel}.
|
||||
*/
|
||||
public class MarkerPanel extends JPanel {
|
||||
|
||||
private MarkerManager manager;
|
||||
|
||||
private Program program;
|
||||
private AddressIndexMap addrMap;
|
||||
private VerticalPixelAddressMap pixmap;
|
||||
|
||||
MarkerPanel(MarkerManager manager) {
|
||||
super();
|
||||
this.manager = manager;
|
||||
|
||||
this.setPreferredSize(new Dimension(16, 1));
|
||||
ToolTipManager.sharedInstance().registerComponent(this);
|
||||
}
|
||||
|
||||
void setProgram(Program program, AddressIndexMap addrMap, VerticalPixelAddressMap pixmap) {
|
||||
this.program = program;
|
||||
this.addrMap = addrMap;
|
||||
this.pixmap = pixmap;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
|
||||
manager.paintMarkers(g);
|
||||
manager.paintMarkers(program, g, pixmap, addrMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
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 {
|
||||
|
||||
protected MarkerManager mgr;
|
||||
private Program program;
|
||||
protected Program program;
|
||||
|
||||
private String name;
|
||||
protected String description;
|
||||
@ -50,6 +50,8 @@ abstract class MarkerSetImpl implements MarkerSet {
|
||||
|
||||
protected AddressSetCollection markers;
|
||||
protected SortedRangeList overview = null;
|
||||
|
||||
protected VerticalPixelAddressMap activePixmap = null;
|
||||
protected List<Integer> activeLayouts = null;
|
||||
|
||||
protected Color markerColor;
|
||||
@ -98,6 +100,7 @@ abstract class MarkerSetImpl implements MarkerSet {
|
||||
|
||||
/**
|
||||
* Returns the Navigator Icon for this marker set
|
||||
*
|
||||
* @return the Navigator Icon for this marker set
|
||||
*/
|
||||
public abstract ImageIcon getNavIcon();
|
||||
@ -248,11 +251,10 @@ abstract class MarkerSetImpl implements MarkerSet {
|
||||
}
|
||||
}
|
||||
|
||||
public final void paintNavigation(Graphics g, int height, NavigationPanel panel,
|
||||
AddressIndexMap map) {
|
||||
public final void paintNavigation(Graphics g, int height, int width, AddressIndexMap map) {
|
||||
if (showNavigation) {
|
||||
SortedRangeList newOverview = computeNavigationIndexes(height, map);
|
||||
doPaintNavigation(g, height, panel.getWidth(), newOverview);
|
||||
SortedRangeList newOverview = computeNavigationIndices(height, map);
|
||||
doPaintNavigation(g, height, width, newOverview);
|
||||
}
|
||||
}
|
||||
|
||||
@ -293,7 +295,7 @@ abstract class MarkerSetImpl implements MarkerSet {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (activeLayouts != null) {
|
||||
if (activeLayouts != null && activePixmap == pixmap) {
|
||||
return activeLayouts; // use cache
|
||||
}
|
||||
|
||||
@ -311,19 +313,19 @@ abstract class MarkerSetImpl implements MarkerSet {
|
||||
}
|
||||
}
|
||||
|
||||
activePixmap = pixmap;
|
||||
activeLayouts = newLayouts;
|
||||
return newLayouts;
|
||||
}
|
||||
|
||||
private SortedRangeList computeNavigationIndexes(int height, AddressIndexMap map) {
|
||||
private SortedRangeList computeNavigationIndices(int height, AddressIndexMap map) {
|
||||
|
||||
lastHeight = height;
|
||||
double numIndexes = map.getIndexCount().doubleValue();
|
||||
if (markers.isEmpty() || height == 0 || numIndexes == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (overview != null) {
|
||||
if (overview != null && lastHeight == height) {
|
||||
return overview; // use cache
|
||||
}
|
||||
|
||||
@ -376,6 +378,7 @@ abstract class MarkerSetImpl implements MarkerSet {
|
||||
}
|
||||
}
|
||||
|
||||
lastHeight = height;
|
||||
overview = newOverview;
|
||||
return newOverview;
|
||||
}
|
||||
@ -391,7 +394,7 @@ abstract class MarkerSetImpl implements MarkerSet {
|
||||
*/
|
||||
public String getTooltip(Address addr, int x, int y) {
|
||||
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 null;
|
||||
@ -421,7 +424,10 @@ abstract class MarkerSetImpl implements MarkerSet {
|
||||
public ProgramLocation getProgramLocation(int y, int height, AddressIndexMap map, int x) {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -455,12 +461,12 @@ abstract class MarkerSetImpl implements MarkerSet {
|
||||
addr = set.getMinAddress();
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
if (loc == null) {
|
||||
loc = new ProgramLocation(mgr.getProgram(), addr);
|
||||
loc = new ProgramLocation(program, addr);
|
||||
}
|
||||
}
|
||||
return loc;
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -16,23 +15,35 @@
|
||||
*/
|
||||
package ghidra.app.plugin.core.marker;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.event.*;
|
||||
|
||||
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
|
||||
* FieldPanel.
|
||||
* Normally placed to the right of the scrolled panel.
|
||||
* Panel to display an overview of all markers placed within a scrolled {@link FieldPanel}. Normally
|
||||
* placed to the right of the scrolled panel.
|
||||
*/
|
||||
public class NavigationPanel extends JPanel {
|
||||
|
||||
private MarkerManager manager;
|
||||
|
||||
private Navigatable navigatable;
|
||||
private Program program;
|
||||
private AddressIndexMap addrMap;
|
||||
|
||||
NavigationPanel(MarkerManager manager) {
|
||||
super();
|
||||
this.manager = manager;
|
||||
|
||||
this.setPreferredSize(new Dimension(16, 1));
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
@ -41,12 +52,11 @@ public class NavigationPanel extends JPanel {
|
||||
addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
|
||||
if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0) {
|
||||
manager.navigateTo(e.getX(), e.getY());
|
||||
if ((e.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0) {
|
||||
manager.navigateTo(navigatable, program, e.getX(), e.getY(), getViewHeight(),
|
||||
addrMap);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@ -56,7 +66,23 @@ public class NavigationPanel extends JPanel {
|
||||
@Override
|
||||
protected void paintComponent(Graphics 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;
|
||||
|
||||
/**
|
||||
* @param navigationManager manager for these point markers
|
||||
* @param navigationManager manager for these point markers
|
||||
* @param name the name for 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 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 colorBackground colorBackground the color of marked areas in navigation bar
|
||||
* If color is null, no results are displayed in the associated marker bar.
|
||||
* @param showNavigation true indicates to show area navigation markers (on the right side of
|
||||
* the browser.)
|
||||
* @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 icon the icon used to represent the cursor in the marker margin
|
||||
* @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 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 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 colorBackground colorBackground the color of marked areas in navigation bar
|
||||
* If color is null, no results are displayed in the associated marker bar.
|
||||
* @param showNavigation true indicates to show area navigation markers (on the right side of
|
||||
* the browser.)
|
||||
* @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 icon the icon used to represent the cursor in the marker margin
|
||||
* @param program the program to which the markers apply
|
||||
@ -115,7 +117,6 @@ class PointMarkerSet extends MarkerSetImpl {
|
||||
}
|
||||
|
||||
Address address = pixmap.getLayoutAddress(i);
|
||||
Program program = mgr.getProgram();
|
||||
MarkerLocation loc = new MarkerLocation(this, program, address, 0, yStart);
|
||||
ImageIcon icon = markerDescriptor.getIcon(loc);
|
||||
if (icon != null) {
|
||||
|
@ -26,15 +26,17 @@ import javax.swing.*;
|
||||
|
||||
import docking.action.DockingActionIf;
|
||||
import docking.help.Help;
|
||||
import ghidra.app.nav.Navigatable;
|
||||
import ghidra.app.services.GoToService;
|
||||
import ghidra.app.util.viewer.listingpanel.OverviewProvider;
|
||||
import ghidra.app.util.viewer.util.AddressIndexMap;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.Program;
|
||||
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.
|
||||
*/
|
||||
public class OverviewColorComponent extends JPanel implements OverviewProvider {
|
||||
@ -44,6 +46,7 @@ public class OverviewColorComponent extends JPanel implements OverviewProvider {
|
||||
private final SwingUpdateManager refreshUpdater =
|
||||
new SwingUpdateManager(100, 15000, () -> doRefresh());
|
||||
private AddressIndexMap map;
|
||||
private Navigatable navigatable;
|
||||
private PluginTool tool;
|
||||
private List<DockingActionIf> actions;
|
||||
|
||||
@ -52,7 +55,7 @@ public class OverviewColorComponent extends JPanel implements OverviewProvider {
|
||||
*
|
||||
* @param tool the PluginTool
|
||||
* @param overviewColorService the {@link OverviewColorService} that provides colors for various
|
||||
* addresses.
|
||||
* addresses.
|
||||
*/
|
||||
public OverviewColorComponent(PluginTool tool, OverviewColorService overviewColorService) {
|
||||
this.tool = tool;
|
||||
@ -104,7 +107,7 @@ public class OverviewColorComponent extends JPanel implements OverviewProvider {
|
||||
protected void gotoAddress(Address address) {
|
||||
GoToService gotoService = tool.getService(GoToService.class);
|
||||
if (gotoService != null) {
|
||||
gotoService.goTo(address);
|
||||
gotoService.goTo(navigatable, address);
|
||||
}
|
||||
}
|
||||
|
||||
@ -194,12 +197,17 @@ public class OverviewColorComponent extends JPanel implements OverviewProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAddressIndexMap(AddressIndexMap map) {
|
||||
public void setProgram(Program program, AddressIndexMap map) {
|
||||
this.map = map;
|
||||
colors = new Color[getOverviewPixelCount()];
|
||||
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.
|
||||
*/
|
||||
@ -210,6 +218,7 @@ public class OverviewColorComponent extends JPanel implements OverviewProvider {
|
||||
|
||||
/**
|
||||
* Causes the component to refresh any colors for the given address range.
|
||||
*
|
||||
* @param start the start 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
|
||||
*
|
||||
* @return the PluginTool
|
||||
*/
|
||||
public PluginTool getTool() {
|
||||
|
@ -20,7 +20,7 @@ import java.awt.Color;
|
||||
import javax.swing.ImageIcon;
|
||||
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.framework.plugintool.ServiceInfo;
|
||||
import ghidra.program.model.address.Address;
|
||||
@ -28,8 +28,8 @@ import ghidra.program.model.listing.Program;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Service to manage navigation markers displayed around a scrollable window like the Listing.
|
||||
* The navigation bar displays the general location of markers for the entire view. The marker bar
|
||||
* Service to manage navigation markers displayed around a scrollable window like the Listing. The
|
||||
* 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.
|
||||
* </p>
|
||||
* <p>
|
||||
@ -39,16 +39,18 @@ import ghidra.program.model.listing.Program;
|
||||
* </p>
|
||||
* <a name="usage"></a> <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
|
||||
* service has been changed to associate created markers with individual programs. Thus, it is
|
||||
* up to the clients of this class perform lifecycle management of markers created by this
|
||||
* service. For example, a client that creates a marker from
|
||||
* {@link #createAreaMarker(String, String, Program, int, boolean, boolean, boolean, Color)} should
|
||||
* 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 up to
|
||||
* the clients of this class perform lifecycle management of markers created by this service. For
|
||||
* example, a client that creates a marker from
|
||||
* {@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
|
||||
* a program has become deactivated. In this example usage markers are added and removed as the
|
||||
* user tabs through open programs.
|
||||
* a program has become deactivated. In this example usage markers are added and removed as the user
|
||||
* 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 {
|
||||
|
||||
/**
|
||||
@ -104,7 +106,7 @@ public interface MarkerService {
|
||||
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 #removeMarkerForGroup(String, MarkerSet, Program)}
|
||||
*/
|
||||
@ -118,7 +120,8 @@ public interface MarkerService {
|
||||
* @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 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 color the color of marked areas.
|
||||
* @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 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 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 color the color of marked areas.
|
||||
* @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 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 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 color the color of marked areas in navigation 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 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 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 color the color of marked areas in navigation bar
|
||||
* @param icon icon to display in marker bar
|
||||
@ -200,9 +206,10 @@ public interface MarkerService {
|
||||
public MarkerSet getMarkerSet(String name, Program program);
|
||||
|
||||
/**
|
||||
* Sets a marker set for a given group name. Any previous marker set associated with the
|
||||
* given group name will be removed from this marker service. This method is used to ensure
|
||||
* that only one marker set is used at any time for a give group.
|
||||
* Sets a marker set for a given group name. Any previous marker set associated with the given
|
||||
* group name will be removed from this marker service. This method is used to ensure that only
|
||||
* one marker set is used at any time for a give group.
|
||||
*
|
||||
* @param groupName The name to associate the marker set with.
|
||||
* @param markerSet The marker set to add to this service
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* Removes a marker set for a given group name. If the given marker set is not the marker
|
||||
* set associated with the given group name, then no action will be taken.
|
||||
* Removes a marker set for a given group name. If the given marker set is not the marker set
|
||||
* associated with the given group name, then no action will be taken.
|
||||
*
|
||||
* @param groupName The name associated the marker set with.
|
||||
* @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
|
||||
* marker is
|
||||
* @param program The program with which the markers are associated. May be null if the marker
|
||||
* is
|
||||
* @see #setMarkerForGroup(String, MarkerSet, 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
|
||||
* that supports background coloring is checked in priority order to see if it wants to specify
|
||||
* 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 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
|
||||
@ -270,4 +266,21 @@ public interface MarkerService {
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @param owner the owner of this panel
|
||||
* @param tool the tool displaying this panel
|
||||
*/
|
||||
@ -208,9 +209,6 @@ public class ListingCodeComparisonPanel
|
||||
Color diffCodeUnitsBackgroundColor = comparisonOptions.getDiffCodeUnitsBackgroundColor();
|
||||
diffMarkers[LEFT].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
|
||||
@ -280,6 +278,7 @@ public class ListingCodeComparisonPanel
|
||||
/**
|
||||
* Sets the coordinator for the two listings within this code comparison panel. It coordinates
|
||||
* their scrolling and location synchronization.
|
||||
*
|
||||
* @param listingFieldPanelCoordinator the coordinator for the two listings
|
||||
*/
|
||||
@Override
|
||||
@ -303,6 +302,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Adds the indicated highlight providers for the left and right listing panels.
|
||||
*
|
||||
* @param leftHighlightProvider the highlight provider for the left 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.
|
||||
*
|
||||
* @param leftHighlightProvider the highlight provider for the left 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.
|
||||
*
|
||||
* @param programLocationListener the listener
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @param programLocationListener the listener
|
||||
*/
|
||||
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
|
||||
* the addresses in the limited set.
|
||||
* @param show if true, the entire program will be shown. Otherwise the listings will only
|
||||
* show the limited addresses.
|
||||
* Sets whether or not the entire programs are displayed in the listings or only the addresses
|
||||
* in the limited set.
|
||||
*
|
||||
* @param show if true, the entire program will be shown. Otherwise the listings will only show
|
||||
* the limited addresses.
|
||||
*/
|
||||
public void showEntireListing(boolean show) {
|
||||
try {
|
||||
@ -863,6 +867,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Determines if the listing's layout field header is currently showing.
|
||||
*
|
||||
* @return true if the header is showing.
|
||||
*/
|
||||
public boolean isHeaderShowing() {
|
||||
@ -871,6 +876,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Shows or hides the listing's layout field header.
|
||||
*
|
||||
* @param show true means show the field header. false means hide the header.
|
||||
*/
|
||||
public void setHeaderShowing(boolean show) {
|
||||
@ -889,6 +895,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public void showSideBySide(boolean sideBySide) {
|
||||
@ -932,6 +939,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Gets the function loaded in the left listing panel.
|
||||
*
|
||||
* @return the function or null
|
||||
*/
|
||||
@Override
|
||||
@ -941,6 +949,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Gets the function loaded in the right listing panel.
|
||||
*
|
||||
* @return the function or null
|
||||
*/
|
||||
@Override
|
||||
@ -989,8 +998,8 @@ public class ListingCodeComparisonPanel
|
||||
}
|
||||
|
||||
/**
|
||||
* Establishes the location and display of the arrow cursor. This method should be called
|
||||
* after the function comparison window is loaded with functions, data, etc.
|
||||
* Establishes the location and display of the arrow cursor. This method should be called after
|
||||
* the function comparison window is loaded with functions, data, etc.
|
||||
*/
|
||||
private void loadCursorArrow() {
|
||||
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
|
||||
* vice versa. The intent of this method is to translate a location from one side of the
|
||||
* dual listing to an equivalent location for the other side if possible.
|
||||
* vice versa. The intent of this method is to translate a location from one side of the dual
|
||||
* 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 programLocation the program location for the other side.
|
||||
* @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
|
||||
* as the <code>address</code> and <code>desiredAddress</code> that were matched.
|
||||
* Infers a desired byte address based on the specified <code>byteAddress</code> as well as the
|
||||
* <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 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 program the program for the <code>address</code> and <code>byteAddress</code>.
|
||||
* @param desiredProgram the program for the <code>desiredAddress</code> and
|
||||
* <code>desiredByteAddress</code>.
|
||||
* @param desiredProgram the program for the <code>desiredAddress</code> and
|
||||
* <code>desiredByteAddress</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,
|
||||
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
|
||||
* <code>codeUnitAddress</code> and <code>desiredCodeUnitAddress</code>.
|
||||
* The inferred address will be at an offset from the <code>desiredCodeUnitAddress</code>
|
||||
* that is the same distance the <code>byteAddress</code> is from the <code>codeUnitAddress</code>.
|
||||
* This infers the desired byte address within Data based on the code units at
|
||||
* <code>codeUnitAddress</code> and <code>desiredCodeUnitAddress</code>. The inferred address
|
||||
* will be at an offset from the <code>desiredCodeUnitAddress</code> that is the same distance
|
||||
* the <code>byteAddress</code> is from the <code>codeUnitAddress</code>.
|
||||
*
|
||||
* @param codeUnitAddress matches up with the <code>desiredCodeUnitAddress</code> from
|
||||
* the other data.
|
||||
* @param desiredCodeUnitAddress matches up with the <code>codeUnitAddress</code> from
|
||||
* the other data.
|
||||
* @param codeUnitAddress matches up with the <code>desiredCodeUnitAddress</code> from the other
|
||||
* data.
|
||||
* @param desiredCodeUnitAddress matches up with the <code>codeUnitAddress</code> from the other
|
||||
* data.
|
||||
* @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 desiredProgram the program for the <code>desiredCodeUnitAddress</code> and
|
||||
* <code>desiredByteAddress</code>.
|
||||
* @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.
|
||||
* @param desiredProgram the program for the <code>desiredCodeUnitAddress</code> and
|
||||
* <code>desiredByteAddress</code>.
|
||||
* @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.
|
||||
*/
|
||||
private Address inferDesiredDataAddress(Address codeUnitAddress, Address desiredCodeUnitAddress,
|
||||
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
|
||||
* <code>address</code> and <code>desiredAddress</code>.
|
||||
* If the inferred address would be beyond the last byte of the code unit then it
|
||||
* will get set to the last byte of the code unit at the <code>desiredAddress</code>.
|
||||
* This infers the desired byte address within a function based on the code units at
|
||||
* <code>address</code> and <code>desiredAddress</code>. If the inferred address would be beyond
|
||||
* the last byte of the code unit then it will get set to the last byte of the code unit at the
|
||||
* <code>desiredAddress</code>.
|
||||
*
|
||||
* @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 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 desiredProgram the program for the <code>desiredAddress</code> and
|
||||
* <code>desiredByteAddress</code>.
|
||||
* @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.
|
||||
* @param desiredProgram the program for the <code>desiredAddress</code> and
|
||||
* <code>desiredByteAddress</code>.
|
||||
* @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.
|
||||
*/
|
||||
private Address inferDesiredFunctionAddress(Address address, Address desiredAddress,
|
||||
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
|
||||
* 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.
|
||||
*
|
||||
* @param leftOrRight LEFT or RIGHT indicating which side's variable location is needed.
|
||||
* @param variableLocation the variable location for the other side.
|
||||
* @return a variable location for the desired side. Otherwise, null.
|
||||
@ -1549,7 +1561,6 @@ public class ListingCodeComparisonPanel
|
||||
listingPanels[LEFT].getFieldPanel()
|
||||
.setBackgroundColorModel(
|
||||
new MarkerServiceBackgroundColorModel(markerManagers[LEFT], indexMap));
|
||||
markerManagers[LEFT].setProgram(programs[LEFT]);
|
||||
unmatchedCodeMarkers[LEFT] =
|
||||
markerManagers[LEFT].createAreaMarker("Listing1 Unmatched Code",
|
||||
"Instructions that are not matched to an instruction in the other function.",
|
||||
@ -1565,7 +1576,6 @@ public class ListingCodeComparisonPanel
|
||||
.setBackgroundColorModel(
|
||||
new MarkerServiceBackgroundColorModel(markerManagers[RIGHT],
|
||||
rightIndexMap));
|
||||
markerManagers[RIGHT].setProgram(programs[RIGHT]);
|
||||
unmatchedCodeMarkers[RIGHT] =
|
||||
markerManagers[RIGHT].createAreaMarker("Listing2 Unmatched Code",
|
||||
"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]);
|
||||
markerManagers[LEFT].getOverviewProvider().setAddressIndexMap(indexMaps[LEFT]);
|
||||
markerManagers[LEFT].getOverviewProvider().setProgram(getLeftProgram(), indexMaps[LEFT]);
|
||||
listingPanels[LEFT].getFieldPanel()
|
||||
.setBackgroundColorModel(
|
||||
new MarkerServiceBackgroundColorModel(markerManagers[LEFT], indexMaps[LEFT]));
|
||||
@ -1680,7 +1690,7 @@ public class ListingCodeComparisonPanel
|
||||
}
|
||||
|
||||
indexMaps[RIGHT] = new AddressIndexMap(addressSets[RIGHT]);
|
||||
markerManagers[RIGHT].getOverviewProvider().setAddressIndexMap(indexMaps[RIGHT]);
|
||||
markerManagers[RIGHT].getOverviewProvider().setProgram(getRightProgram(), indexMaps[RIGHT]);
|
||||
listingPanels[RIGHT].getFieldPanel()
|
||||
.setBackgroundColorModel(
|
||||
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.
|
||||
*
|
||||
* @param leftFunction the function in the left 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.
|
||||
*
|
||||
* @param program the left side's program
|
||||
* @param location the location
|
||||
*/
|
||||
@ -1744,6 +1756,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Sets the cursor in the right side's listing to the specified location.
|
||||
*
|
||||
* @param program the right side's program
|
||||
* @param location the location
|
||||
*/
|
||||
@ -1863,6 +1876,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Sets the title for the left side's listing.
|
||||
*
|
||||
* @param leftTitle the title
|
||||
*/
|
||||
public void setLeftTitle(String leftTitle) {
|
||||
@ -1872,6 +1886,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Sets the title for the right side's listing.
|
||||
*
|
||||
* @param rightTitle the title
|
||||
*/
|
||||
public void setRightTitle(String rightTitle) {
|
||||
@ -1881,6 +1896,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Sets the component displayed in the top of this panel.
|
||||
*
|
||||
* @param comp the component.
|
||||
*/
|
||||
public void setTopComponent(JComponent comp) {
|
||||
@ -1899,6 +1915,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Sets the component displayed in the bottom of this panel.
|
||||
*
|
||||
* @param comp the component.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @return the program from the side of this panel with focus or null
|
||||
*/
|
||||
public Program getFocusedProgram() {
|
||||
@ -1926,6 +1944,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Gets the program in the left listing panel.
|
||||
*
|
||||
* @return the left program or null
|
||||
*/
|
||||
@Override
|
||||
@ -1935,6 +1954,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Gets the program in the right listing panel.
|
||||
*
|
||||
* @return the right program or null
|
||||
*/
|
||||
@Override
|
||||
@ -1944,6 +1964,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Gets the addresses in the left listing panel.
|
||||
*
|
||||
* @return the addresses
|
||||
*/
|
||||
@Override
|
||||
@ -1953,6 +1974,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Gets the addresses in the right listing panel.
|
||||
*
|
||||
* @return the addresses
|
||||
*/
|
||||
@Override
|
||||
@ -1962,6 +1984,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Get the left or right listing panel that has or last had focus.
|
||||
*
|
||||
* @return the listing panel with focus.
|
||||
*/
|
||||
public ListingPanel getFocusedListingPanel() {
|
||||
@ -1970,6 +1993,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Get the left side's listing panel.
|
||||
*
|
||||
* @return the left panel
|
||||
*/
|
||||
public ListingPanel getLeftPanel() {
|
||||
@ -1978,6 +2002,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Get the right side's listing panel.
|
||||
*
|
||||
* @return the right panel
|
||||
*/
|
||||
public ListingPanel getRightPanel() {
|
||||
@ -1986,6 +2011,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Go to the indicated address in the listing that last had focus.
|
||||
*
|
||||
* @param addr the cursor should go to this address
|
||||
* @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.
|
||||
*
|
||||
* @param loc the cursor should go to this location.
|
||||
* @param centerOnScreen true indicates that the location should be centered in the listing's
|
||||
* viewport.
|
||||
* viewport.
|
||||
* @return true if the location changed
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
* address.
|
||||
*
|
||||
* @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
|
||||
* 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
|
||||
* side's address that is specified. Otherwise, null.
|
||||
* side's address that is specified. Otherwise, null.
|
||||
*/
|
||||
private Address getAddress(int leftOrRight, Address otherSidesAddress) {
|
||||
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.
|
||||
*
|
||||
* @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
|
||||
* desired address.
|
||||
* @param otherSidesAddress address in the other program that is equivalent to the desired
|
||||
* address.
|
||||
* @return the matching address in the indicated program or null.
|
||||
*/
|
||||
private Address getFunctionAddress(int leftOrRight, Address otherSidesAddress) {
|
||||
@ -2196,6 +2228,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Is this panel currently comparing a function match?
|
||||
*
|
||||
* @return true if comparing functions.
|
||||
*/
|
||||
private boolean isFunctionCompare() {
|
||||
@ -2206,6 +2239,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Is this panel currently comparing a data match?
|
||||
*
|
||||
* @return true if comparing data.
|
||||
*/
|
||||
private boolean isDataCompare() {
|
||||
@ -2216,6 +2250,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Gets the left side address that is equivalent to the indicated right side address.
|
||||
*
|
||||
* @param rightByteAddress the right side address
|
||||
* @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.
|
||||
*
|
||||
* @param leftByteAddress the left side address
|
||||
* @return the right side address or null.
|
||||
*/
|
||||
@ -2240,6 +2276,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Gets the left side function's entry point address.
|
||||
*
|
||||
* @return the left side function's entry point address or null.
|
||||
*/
|
||||
private Address getLeftFunctionAddress() {
|
||||
@ -2251,6 +2288,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Gets the right side function's entry point address.
|
||||
*
|
||||
* @return the right side function's entry point address or null.
|
||||
*/
|
||||
private Address getRightFunctionAddress() {
|
||||
@ -2262,6 +2300,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Gets the left side data's minimum address.
|
||||
*
|
||||
* @return the left side data's minimum address or null.
|
||||
*/
|
||||
private Address getLeftDataAddress() {
|
||||
@ -2273,6 +2312,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Gets the right side data's minimum address.
|
||||
*
|
||||
* @return the right side data's minimum address or null.
|
||||
*/
|
||||
private Address getRightDataAddress() {
|
||||
@ -2381,6 +2421,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Gets the left or right listing panel that contains the indicated field panel.
|
||||
*
|
||||
* @param fieldPanel the field panel
|
||||
* @return the listing panel or null.
|
||||
*/
|
||||
@ -2401,6 +2442,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Disable mouse navigation from within this dual listing panel.
|
||||
*
|
||||
* @param enabled false disables navigation
|
||||
*/
|
||||
@Override
|
||||
@ -2448,6 +2490,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Gets the maximum offset based on the larger data that is passed to this method.
|
||||
*
|
||||
* @param leftData the left view's data
|
||||
* @param rightData the right view's data
|
||||
* @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
|
||||
* maxOffset number of bytes beyond the minAddress without leaving the memory block
|
||||
* that contains the minAddress. If the maxOffset is beyond the end of the block then
|
||||
* the end of the block is returned. For an externalAddress the minAddress is returned.
|
||||
* Gets the ending address to be displayed. It tries to get an ending address that is maxOffset
|
||||
* number of bytes beyond the minAddress without leaving the memory block that contains the
|
||||
* minAddress. If the maxOffset is beyond the end of the block then the end of the block is
|
||||
* returned. For an externalAddress the minAddress is returned.
|
||||
*
|
||||
* @param program the program containing the data
|
||||
* @param maxOffset the max offset
|
||||
* @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
|
||||
* field panel coordinator.
|
||||
* Clears the address correlation being used with the ListingDiff and the dual listing field
|
||||
* panel coordinator.
|
||||
*/
|
||||
private void clearCorrelation() {
|
||||
correlator = null;
|
||||
@ -2516,6 +2560,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Gets the data loaded in the left listing panel.
|
||||
*
|
||||
* @return the data or null
|
||||
*/
|
||||
@Override
|
||||
@ -2525,6 +2570,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Gets the data loaded in the right listing panel.
|
||||
*
|
||||
* @return the data or null
|
||||
*/
|
||||
@Override
|
||||
@ -2560,6 +2606,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Displays the indicated text int the tool's status area.
|
||||
*
|
||||
* @param text the message to display
|
||||
*/
|
||||
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.
|
||||
* @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
|
||||
*/
|
||||
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
|
||||
* of the GUI components for the indicated listing panel's marker margin (left edge of listing)
|
||||
* or overview margin (right edge of listing).
|
||||
* Gets a marker margin or overview margin context object if the mouse event occurred on one of
|
||||
* the GUI components for the indicated listing panel's marker margin (left edge of listing) or
|
||||
* overview margin (right edge of listing).
|
||||
*
|
||||
* @param lp The listing panel to check
|
||||
* @param event the mouse event
|
||||
* @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.
|
||||
*
|
||||
* @param prefix identifier to prepend to any save state names to make them unique.
|
||||
* @param saveState the configuration state to restore
|
||||
*/
|
||||
@ -2743,6 +2793,7 @@ public class ListingCodeComparisonPanel
|
||||
|
||||
/**
|
||||
* Saves the current configuration state of this panel.
|
||||
*
|
||||
* @param prefix identifier to prepend to any save state names to make them unique.
|
||||
* @param saveState the new configuration state
|
||||
*/
|
||||
|
@ -260,7 +260,7 @@ public class ListingPanel extends JPanel implements FieldMouseListener, FieldLoc
|
||||
private void updateProviders() {
|
||||
AddressIndexMap addressIndexMap = layoutModel.getAddressIndexMap();
|
||||
for (OverviewProvider element : overviewProviders) {
|
||||
element.setAddressIndexMap(addressIndexMap);
|
||||
element.setProgram(getProgram(), addressIndexMap);
|
||||
}
|
||||
for (ChangeListener indexMapChangeListener : indexMapChangeListeners) {
|
||||
indexMapChangeListener.stateChanged(null);
|
||||
@ -294,7 +294,7 @@ public class ListingPanel extends JPanel implements FieldMouseListener, FieldLoc
|
||||
else {
|
||||
marginProviders.add(provider);
|
||||
}
|
||||
provider.setPixelMap(pixmap);
|
||||
provider.setProgram(getProgram(), layoutModel.getAddressIndexMap(), pixmap);
|
||||
buildPanels();
|
||||
}
|
||||
|
||||
@ -408,7 +408,7 @@ public class ListingPanel extends JPanel implements FieldMouseListener, FieldLoc
|
||||
*/
|
||||
public void addOverviewProvider(OverviewProvider provider) {
|
||||
overviewProviders.add(provider);
|
||||
provider.setAddressIndexMap(layoutModel.getAddressIndexMap());
|
||||
provider.setProgram(getProgram(), layoutModel.getAddressIndexMap());
|
||||
buildPanels();
|
||||
}
|
||||
|
||||
@ -474,9 +474,10 @@ public class ListingPanel extends JPanel implements FieldMouseListener, FieldLoc
|
||||
|
||||
@Override
|
||||
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) {
|
||||
element.setPixelMap(pixmap);
|
||||
element.setProgram(getProgram(), addrMap, pixmap);
|
||||
}
|
||||
|
||||
for (AddressSetDisplayListener listener : displayListeners) {
|
||||
@ -1061,7 +1062,7 @@ public class ListingPanel extends JPanel implements FieldMouseListener, FieldLoc
|
||||
}
|
||||
|
||||
Layout layout2 = layoutModel.getLayout(loc2.getIndex());
|
||||
|
||||
|
||||
if (fieldNum1 >= 0 && layout2 != null) {
|
||||
BigInteger index2 = loc2.getIndex();
|
||||
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
|
||||
* a single field.
|
||||
* Returns the currently selected text. The value will only be non-null for selections within a
|
||||
* single field.
|
||||
*
|
||||
* @return the selected text or null
|
||||
*/
|
||||
public String getTextSelection() {
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -16,12 +15,14 @@
|
||||
*/
|
||||
package ghidra.app.util.viewer.listingpanel;
|
||||
|
||||
import ghidra.program.util.MarkerLocation;
|
||||
|
||||
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 {
|
||||
|
||||
@ -36,13 +37,18 @@ public interface MarginProvider {
|
||||
boolean isResizeable();
|
||||
|
||||
/**
|
||||
* Set the vertical pixel layout map.
|
||||
* @param pixmap the vertical pixel map to use.
|
||||
* Set the program and associated maps.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @param x the horizontal coordinate.
|
||||
* @param y the vertical coordinate.
|
||||
*/
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -16,25 +15,34 @@
|
||||
*/
|
||||
package ghidra.app.util.viewer.listingpanel;
|
||||
|
||||
import ghidra.app.util.viewer.util.AddressIndexMap;
|
||||
|
||||
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
|
||||
* of the listing.
|
||||
* Interface implemented by classes that provide overview components to the right side of the
|
||||
* listing.
|
||||
*/
|
||||
public interface OverviewProvider {
|
||||
/**
|
||||
* Returns the component to diplay in the right margin of the listing.
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* Plugin that shows the differences between two programs, and allows the
|
||||
* user to apply differences to the currently open program. This allows only one
|
||||
* tabbed program to display a second program (possibly with an active Diff).
|
||||
* It allows the active program to change without losing the current Diff or
|
||||
* second program that is opened. De-activation of the first program for the Diff
|
||||
* will result in termination of the Diff or the Diff can be closed directly by the user.
|
||||
* Plugin that shows the differences between two programs, and allows the user to apply differences
|
||||
* to the currently open program. This allows only one tabbed program to display a second program
|
||||
* (possibly with an active Diff). It allows the active program to change without losing the current
|
||||
* Diff or second program that is opened. De-activation of the first program for the Diff will
|
||||
* result in termination of the Diff or the Diff can be closed directly by the user.
|
||||
*/
|
||||
//@formatter:off
|
||||
@PluginInfo(
|
||||
@ -151,6 +150,7 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
||||
|
||||
/**
|
||||
* Creates the plugin for indicating program differences to the user.
|
||||
*
|
||||
* @param tool the tool that owns this plugin.
|
||||
*/
|
||||
public ProgramDiffPlugin(PluginTool tool) {
|
||||
@ -282,7 +282,7 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
||||
AddressSet p1AddressSetAsP2 =
|
||||
DiffUtility.getCompatibleAddressSet(p1AddressSet, secondaryDiffProgram);
|
||||
AddressIndexMap p2IndexMap = new AddressIndexMap(p1AddressSetAsP2);
|
||||
markerManager.getOverviewProvider().setAddressIndexMap(p2IndexMap);
|
||||
markerManager.getOverviewProvider().setProgram(secondaryDiffProgram, p2IndexMap);
|
||||
fp.setBackgroundColorModel(
|
||||
new MarkerServiceBackgroundColorModel(markerManager, p2IndexMap));
|
||||
|
||||
@ -479,8 +479,9 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a program gets closed.
|
||||
* If the closed program is the first program of the Diff then we need to close the second program.
|
||||
* Called when a program gets closed. If the closed program is the first program of the Diff
|
||||
* then we need to close the second program.
|
||||
*
|
||||
* @param program
|
||||
*/
|
||||
@Override
|
||||
@ -719,8 +720,8 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
||||
/**
|
||||
* 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
|
||||
* listing which displays P2.
|
||||
* Note: A P2 selection is handed to this method when a selection is made in the diff listing
|
||||
* which displays P2.
|
||||
*/
|
||||
@Override
|
||||
public void programSelectionChanged(ProgramSelection newP2Selection) {
|
||||
@ -838,8 +839,9 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the highlight based on the current program differences, but
|
||||
* do not set the highlight for set of addresses to be ignored.
|
||||
* Set the highlight based on the current program differences, but do not set the highlight for
|
||||
* set of addresses to be ignored.
|
||||
*
|
||||
* @param ignoreAddressSet the set of addresses to ignore.
|
||||
*/
|
||||
private void setDiffHighlight() {
|
||||
@ -849,7 +851,7 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
||||
|
||||
AddressSetView p1DiffSet = null;
|
||||
try {
|
||||
p1DiffSet = diffControl.getFilteredDifferences(TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
p1DiffSet = diffControl.getFilteredDifferences(TaskMonitor.DUMMY);
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
// 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
|
||||
* in the browser using the current Limiting set. It allows the user to specify the Diff settings to use.
|
||||
* Computes the differences between program1 and program2 that are displayed in the browser
|
||||
* using the current Limiting set. It allows the user to specify the Diff settings to use.
|
||||
*/
|
||||
void diff() {
|
||||
diff(createLimitingSet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the differences between program1 and program2 that are displayed
|
||||
* in the browser. It allows the user to specify the Diff settings to use.
|
||||
* Computes the differences between program1 and program2 that are displayed in the browser. It
|
||||
* allows the user to specify the Diff settings to use.
|
||||
*
|
||||
* @param p1LimitSet an address set to use to limit the extent of the Diff.
|
||||
*/
|
||||
void diff(AddressSetView p1LimitSet) {
|
||||
@ -1055,7 +1058,6 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
||||
setProgram2Selection(p2Selection);
|
||||
clearDiff();
|
||||
if (secondaryDiffProgram != null) {
|
||||
markerManager.setProgram(null);
|
||||
Iterator<BookmarkNavigator> iter = bookmarkMap.values().iterator();
|
||||
while (iter.hasNext()) {
|
||||
BookmarkNavigator nav = iter.next();
|
||||
@ -1171,10 +1173,11 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first program for the current Diff.
|
||||
* <br><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.
|
||||
* Get the first program for the current Diff. <br>
|
||||
* <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.
|
||||
*/
|
||||
Program getFirstProgram() {
|
||||
return primaryProgram;
|
||||
@ -1182,8 +1185,9 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
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
|
||||
* indicated address. An address set is returned since the indicated address may be in different
|
||||
* sized code units in each of the two programs.
|
||||
*
|
||||
* @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
|
||||
* compared to determine differences.
|
||||
* Otherwise null if a diff of two programs isn't being performed.
|
||||
* compared to determine differences. Otherwise null if a diff of two programs isn't
|
||||
* being performed.
|
||||
*/
|
||||
AddressSetView getDetailsAddressSet(Address p1Address) {
|
||||
if (diffDetails != null) {
|
||||
@ -1598,7 +1603,6 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
||||
finally {
|
||||
settingLocation = false;
|
||||
}
|
||||
markerManager.setProgram(secondaryDiffProgram);
|
||||
setupBookmarkNavigators();
|
||||
|
||||
sameProgramContext = ProgramMemoryComparator.sameProgramContextRegisterNames(primaryProgram,
|
||||
|
Loading…
Reference in New Issue
Block a user