mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
Merge remote-tracking branch 'origin/GT-2925-dragonmacher-window-menu-key-bindings'
This commit is contained in:
commit
10372c2e13
200 changed files with 3955 additions and 3195 deletions
|
@ -73,14 +73,15 @@ public class SampleProgramTreePlugin extends ProgramPlugin {
|
||||||
public void actionPerformed(ActionContext context) {
|
public void actionPerformed(ActionContext context) {
|
||||||
modularize();
|
modularize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabledForContext(ActionContext context) {
|
||||||
|
return currentProgram != null;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
action.setMenuBarData(
|
action.setMenuBarData(
|
||||||
new MenuData(new String[] { "Misc", "Create Sample Tree" }, null, null));
|
new MenuData(new String[] { "Misc", "Create Sample Tree" }, null, null));
|
||||||
|
|
||||||
action.setEnabled(false);
|
|
||||||
|
|
||||||
action.setDescription("Plugin to create a program tree and modularize accordingly");
|
action.setDescription("Plugin to create a program tree and modularize accordingly");
|
||||||
enableOnProgram(action);
|
|
||||||
tool.addAction(action);
|
tool.addAction(action);
|
||||||
|
|
||||||
}// end of createActions()
|
}// end of createActions()
|
||||||
|
|
|
@ -32,7 +32,6 @@ import ghidra.program.util.ProgramChangeRecord;
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sample plugin for dealing with Programs. The base class handles
|
* Sample plugin for dealing with Programs. The base class handles
|
||||||
* the event processing and enabling/disabling of actions. This
|
* the event processing and enabling/disabling of actions. This
|
||||||
|
@ -51,107 +50,98 @@ import ghidra.util.Msg;
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
public class TemplateProgramPlugin extends ProgramPlugin implements DomainObjectListener {
|
public class TemplateProgramPlugin extends ProgramPlugin implements DomainObjectListener {
|
||||||
|
|
||||||
private DockingAction action;
|
private DockingAction action;
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
*
|
*
|
||||||
* Standard Plugin Constructor
|
* Standard Plugin Constructor
|
||||||
*
|
*
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
public TemplateProgramPlugin(PluginTool tool) {
|
public TemplateProgramPlugin(PluginTool tool) {
|
||||||
|
|
||||||
super(tool,
|
super(tool, true, // true means this plugin consumes ProgramLocation events
|
||||||
true, // true means this plugin consumes ProgramLocation events
|
false); // false means this plugin does not consume
|
||||||
false); // false means this plugin does not consume
|
// ProgramSelection events
|
||||||
// ProgramSelection events
|
// the base class ProgramPlugin handles all the event registering
|
||||||
// the base class ProgramPlugin handles all the event registering
|
|
||||||
|
|
||||||
// set up list of actions.
|
// set up list of actions.
|
||||||
setupActions();
|
setupActions();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This is the callback method for DomainObjectChangedEvents.
|
|
||||||
*/
|
|
||||||
public void domainObjectChanged(DomainObjectChangedEvent ev) {
|
|
||||||
for (int i=0; i< ev.numRecords(); i++) {
|
|
||||||
DomainObjectChangeRecord record = ev.getChangeRecord(i);
|
|
||||||
if (record instanceof ProgramChangeRecord) {
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
ProgramChangeRecord r = (ProgramChangeRecord)record;
|
|
||||||
// code for processing the record...
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the program is opened.
|
* This is the callback method for DomainObjectChangedEvents.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void programActivated(Program program) {
|
public void domainObjectChanged(DomainObjectChangedEvent ev) {
|
||||||
program.addListener(this);
|
for (int i = 0; i < ev.numRecords(); i++) {
|
||||||
}
|
DomainObjectChangeRecord record = ev.getChangeRecord(i);
|
||||||
/**
|
if (record instanceof ProgramChangeRecord) {
|
||||||
* Called when the program is closed.
|
@SuppressWarnings("unused")
|
||||||
*/
|
ProgramChangeRecord r = (ProgramChangeRecord) record;
|
||||||
@Override
|
// code for processing the record...
|
||||||
protected void programDeactivated(Program program) {
|
// ...
|
||||||
program.removeListener(this);
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************
|
/**
|
||||||
********************************************************************
|
* Called when the program is opened.
|
||||||
**
|
*/
|
||||||
**
|
@Override
|
||||||
** Function 1
|
protected void programActivated(Program program) {
|
||||||
**
|
program.addListener(this);
|
||||||
**
|
}
|
||||||
********************************************************************
|
|
||||||
*******************************************************************/
|
|
||||||
private void Function_1 () {
|
|
||||||
// do something with a program location
|
|
||||||
Msg.info(this, getPluginDescription().getName()
|
|
||||||
+ ": Program Location==> " + currentLocation.getAddress());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the program is closed.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void programDeactivated(Program program) {
|
||||||
|
program.removeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/*******************************************************************
|
||||||
* Set up Actions
|
********************************************************************
|
||||||
*/
|
**
|
||||||
private void setupActions() {
|
**
|
||||||
|
** Function 1
|
||||||
|
**
|
||||||
|
**
|
||||||
|
********************************************************************
|
||||||
|
*******************************************************************/
|
||||||
|
private void Function_1() {
|
||||||
|
// do something with a program location
|
||||||
|
Msg.info(this, getPluginDescription().getName() + ": Program Location==> " +
|
||||||
|
currentLocation.getAddress());
|
||||||
|
}
|
||||||
|
|
||||||
//
|
/**
|
||||||
// Function 1
|
* Set up Actions
|
||||||
//
|
*/
|
||||||
action = new DockingAction("Function 1 Code", getName() ) {
|
private void setupActions() {
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionContext e) {
|
|
||||||
Function_1();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isValidContext( ActionContext context ) {
|
|
||||||
return context instanceof ListingActionContext;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
action.setEnabled( false );
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Function 1
|
||||||
|
//
|
||||||
|
action = new DockingAction("Function 1 Code", getName()) {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionContext e) {
|
||||||
|
Function_1();
|
||||||
|
}
|
||||||
|
|
||||||
action.setMenuBarData( new MenuData(
|
@Override
|
||||||
new String[]{"Misc", "Menu","Menu item 1"}, null, null ) );
|
public boolean isValidContext(ActionContext context) {
|
||||||
|
return context instanceof ListingActionContext;
|
||||||
|
}
|
||||||
// call method in base class to enable this action when a
|
};
|
||||||
// program location event comes in; disable it when focus is
|
action.setEnabled(false);
|
||||||
// lost; it will be disable when the program is closed
|
|
||||||
enableOnLocation(action);
|
|
||||||
|
|
||||||
action.setHelpLocation(new HelpLocation("SampleHelpTopic",
|
|
||||||
"TemplateProgramPlugin_Anchor_Name"));
|
|
||||||
tool.addAction(action);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
action.setMenuBarData(
|
||||||
|
new MenuData(new String[] { "Misc", "Menu", "Menu item 1" }, null, null));
|
||||||
|
|
||||||
|
action.setHelpLocation(
|
||||||
|
new HelpLocation("SampleHelpTopic", "TemplateProgramPlugin_Anchor_Name"));
|
||||||
|
tool.addAction(action);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -23,20 +22,18 @@ import ghidra.program.model.address.AddressSetView;
|
||||||
import ghidra.program.model.listing.Function;
|
import ghidra.program.model.listing.Function;
|
||||||
import ghidra.program.model.listing.FunctionIterator;
|
import ghidra.program.model.listing.FunctionIterator;
|
||||||
|
|
||||||
public class DeleteFunctionDefaultPlates extends GhidraScript {
|
public class DeleteFunctionDefaultPlatesScript extends GhidraScript {
|
||||||
|
|
||||||
private static String DEFAULT_PLATE = " FUNCTION";
|
private static String DEFAULT_PLATE = " FUNCTION";
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see ghidra.app.script.GhidraScript#run()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void run() throws Exception {
|
public void run() throws Exception {
|
||||||
|
|
||||||
AddressSetView set = currentProgram.getMemory();
|
AddressSetView set = currentProgram.getMemory();
|
||||||
if (currentSelection != null && !currentSelection.isEmpty()) {
|
if (currentSelection != null && !currentSelection.isEmpty()) {
|
||||||
set = currentSelection;
|
set = currentSelection;
|
||||||
}
|
}
|
||||||
int updateCount=0;
|
int updateCount = 0;
|
||||||
FunctionIterator iter = currentProgram.getFunctionManager().getFunctions(set, true);
|
FunctionIterator iter = currentProgram.getFunctionManager().getFunctions(set, true);
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
Function function = iter.next();
|
Function function = iter.next();
|
||||||
|
@ -47,7 +44,7 @@ public class DeleteFunctionDefaultPlates extends GhidraScript {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (updateCount > 0) {
|
if (updateCount > 0) {
|
||||||
String cmt = updateCount > 1? "comments" : "comment";
|
String cmt = updateCount > 1 ? "comments" : "comment";
|
||||||
println("Removed " + updateCount + " default plate " + cmt + ".");
|
println("Removed " + updateCount + " default plate " + cmt + ".");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
|
@ -13,7 +13,7 @@
|
||||||
</HEAD>
|
</HEAD>
|
||||||
|
|
||||||
<BODY>
|
<BODY>
|
||||||
<H1><A name="Code_Browser"></A>Listing View</H1>
|
<H1><A name="Code_Browser"></A><A name="Listing"></A>Listing View</H1>
|
||||||
|
|
||||||
<P>The Listing View is the main windows for displaying and working with a program's instruction
|
<P>The Listing View is the main windows for displaying and working with a program's instruction
|
||||||
and data.</P>
|
and data.</P>
|
||||||
|
|
|
@ -476,6 +476,17 @@
|
||||||
|
|
||||||
<P class="providedbyplugin">Provided by: <I>Go To Next-Previous Code Unit</I> plugin</P>
|
<P class="providedbyplugin">Provided by: <I>Go To Next-Previous Code Unit</I> plugin</P>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This file is different than most, since it has multiple plugins contributing to the
|
||||||
|
content. Add some space at the bottom of the file to separate this last contribution
|
||||||
|
-->
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
|
||||||
<H2><A name="Next_Previous_Function"></A>Next/Previous Function</H2>
|
<H2><A name="Next_Previous_Function"></A>Next/Previous Function</H2>
|
||||||
|
|
||||||
|
@ -497,8 +508,21 @@
|
||||||
<P> This action navigates the cursor to the closest function entry point that is at an
|
<P> This action navigates the cursor to the closest function entry point that is at an
|
||||||
address less than the current address. The default keybinding is <TT><B>Control-Up Arrow</B></TT>.</P>
|
address less than the current address. The default keybinding is <TT><B>Control-Up Arrow</B></TT>.</P>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
</BLOCKQUOTE>
|
|
||||||
<P class="providedbyplugin">Provided by: <I>CodeBrowser</I> plugin</P>
|
<P class="providedbyplugin">Provided by: <I>CodeBrowser</I> plugin</P>
|
||||||
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This file is different than most, since it has multiple plugins contributing to the
|
||||||
|
content. Add some space at the bottom of the file to separate this last contribution
|
||||||
|
-->
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
|
||||||
<H2><A name="Navigation_History"></A>Navigation History</H2>
|
<H2><A name="Navigation_History"></A>Navigation History</H2>
|
||||||
|
|
||||||
|
@ -554,9 +578,54 @@
|
||||||
<P>After clearing the history, the <IMG src="images/left.png" border="0"> and <IMG
|
<P>After clearing the history, the <IMG src="images/left.png" border="0"> and <IMG
|
||||||
src="images/right.png" border="0"> buttons are disabled</P>
|
src="images/right.png" border="0"> buttons are disabled</P>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
</BLOCKQUOTE>
|
|
||||||
|
<P class="providedbyplugin">Provided by: <I>Next/Previous</I> plugin</P>
|
||||||
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This file is different than most, since it has multiple plugins contributing to the
|
||||||
|
content. Add some space at the bottom of the file to separate this contribution.
|
||||||
|
-->
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<H2>Component Provider Navigation</H2>
|
||||||
|
|
||||||
|
<BLOCKQUOTE>
|
||||||
|
<P>
|
||||||
|
This section lists actions that allow the user to navigate between component providers.
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<H3><A name="Navigation_Previous_Provider"></A>Go To Last Active Component</H3>
|
||||||
|
|
||||||
|
<BLOCKQUOTE>
|
||||||
|
<P>
|
||||||
|
Allows the user to switch focus back to the previously focused component provider.
|
||||||
|
</P>
|
||||||
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
<P class="providedbyplugin">Provided by: <I>ProviderNavigation</I> plugin</P>
|
||||||
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This file is different than most, since it has multiple plugins contributing to the
|
||||||
|
content. Add some space at the bottom of the file to separate this contribution.
|
||||||
|
-->
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
<BR>
|
||||||
|
|
||||||
|
|
||||||
<P class="providedbyplugin">Provided by: <I>Next/Previous</I> plugin</P>
|
|
||||||
|
|
||||||
<P class="relatedtopic">Related Topics:</P>
|
<P class="relatedtopic">Related Topics:</P>
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
completely different instruction sets. To disassemble properly, the mode register must be set
|
completely different instruction sets. To disassemble properly, the mode register must be set
|
||||||
at the address where the disassembly begins.</P>
|
at the address where the disassembly begins.</P>
|
||||||
|
|
||||||
<H2><A name="RegisterManager"></A>Register Manager</H2>
|
<H2><A name="Register_Manager"></A>Register Manager</H2>
|
||||||
|
|
||||||
<BLOCKQUOTE>
|
<BLOCKQUOTE>
|
||||||
<P>The <I>Register Manager</I> displays the assigned values of registers at addresses within
|
<P>The <I>Register Manager</I> displays the assigned values of registers at addresses within
|
||||||
|
|
|
@ -22,7 +22,6 @@ import javax.swing.ToolTipManager;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import docking.DockingWindowManager;
|
|
||||||
import docking.framework.SplashScreen;
|
import docking.framework.SplashScreen;
|
||||||
import ghidra.base.help.GhidraHelpService;
|
import ghidra.base.help.GhidraHelpService;
|
||||||
import ghidra.framework.Application;
|
import ghidra.framework.Application;
|
||||||
|
@ -86,7 +85,6 @@ public class GhidraRun implements GhidraLaunchable {
|
||||||
updateSplashScreenStatusMessage("Populating Ghidra help...");
|
updateSplashScreenStatusMessage("Populating Ghidra help...");
|
||||||
GhidraHelpService.install();
|
GhidraHelpService.install();
|
||||||
|
|
||||||
DockingWindowManager.enableDiagnosticActions(SystemUtilities.isInDevelopmentMode());
|
|
||||||
ExtensionUtils.cleanupUninstalledExtensions();
|
ExtensionUtils.cleanupUninstalledExtensions();
|
||||||
|
|
||||||
// Allows handling of old content which did not have a content type property
|
// Allows handling of old content which did not have a content type property
|
||||||
|
|
|
@ -22,8 +22,7 @@ import javax.swing.KeyStroke;
|
||||||
|
|
||||||
import docking.ActionContext;
|
import docking.ActionContext;
|
||||||
import docking.DockingUtils;
|
import docking.DockingUtils;
|
||||||
import docking.action.DockingAction;
|
import docking.action.*;
|
||||||
import docking.action.KeyBindingData;
|
|
||||||
import ghidra.app.plugin.core.navigation.FindAppliedDataTypesService;
|
import ghidra.app.plugin.core.navigation.FindAppliedDataTypesService;
|
||||||
import ghidra.app.plugin.core.navigation.locationreferences.ReferenceUtils;
|
import ghidra.app.plugin.core.navigation.locationreferences.ReferenceUtils;
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
|
@ -44,7 +43,7 @@ public abstract class AbstractFindReferencesDataTypeAction extends DockingAction
|
||||||
|
|
||||||
protected AbstractFindReferencesDataTypeAction(PluginTool tool, String name, String owner,
|
protected AbstractFindReferencesDataTypeAction(PluginTool tool, String name, String owner,
|
||||||
KeyStroke defaultKeyStroke) {
|
KeyStroke defaultKeyStroke) {
|
||||||
super(name, owner);
|
super(name, owner, KeyBindingType.SHARED);
|
||||||
this.tool = tool;
|
this.tool = tool;
|
||||||
|
|
||||||
setHelpLocation(new HelpLocation("LocationReferencesPlugin", "Data_Types"));
|
setHelpLocation(new HelpLocation("LocationReferencesPlugin", "Data_Types"));
|
||||||
|
@ -69,11 +68,6 @@ public abstract class AbstractFindReferencesDataTypeAction extends DockingAction
|
||||||
setKeyBindingData(new KeyBindingData(keyStroke));
|
setKeyBindingData(new KeyBindingData(keyStroke));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean usesSharedKeyBinding() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabledForContext(ActionContext context) {
|
public boolean isEnabledForContext(ActionContext context) {
|
||||||
DataType dataType = getDataType(context);
|
DataType dataType = getDataType(context);
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,28 +15,28 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.context;
|
package ghidra.app.context;
|
||||||
|
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import docking.ActionContext;
|
import docking.ActionContext;
|
||||||
import docking.action.DockingAction;
|
import docking.action.DockingAction;
|
||||||
|
import docking.action.KeyBindingType;
|
||||||
|
|
||||||
public abstract class ListingContextAction extends DockingAction {
|
public abstract class ListingContextAction extends DockingAction {
|
||||||
|
|
||||||
public ListingContextAction(String name, String owner) {
|
public ListingContextAction(String name, String owner) {
|
||||||
this(name, owner, true);
|
super(name, owner);
|
||||||
}
|
|
||||||
|
|
||||||
public ListingContextAction(String name, String owner, boolean isKeyBindingManaged) {
|
|
||||||
super(name, owner, isKeyBindingManaged);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ListingContextAction(String name, String owner, KeyBindingType kbType) {
|
||||||
|
super(name, owner, kbType);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabledForContext(ActionContext context) {
|
public boolean isEnabledForContext(ActionContext context) {
|
||||||
if (!(context instanceof ListingActionContext)) {
|
if (!(context instanceof ListingActionContext)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return isEnabledForContext((ListingActionContext)context);
|
return isEnabledForContext((ListingActionContext) context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -45,38 +44,38 @@ public abstract class ListingContextAction extends DockingAction {
|
||||||
if (!(context instanceof ListingActionContext)) {
|
if (!(context instanceof ListingActionContext)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return isValidContext((ListingActionContext)context);
|
return isValidContext((ListingActionContext) context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAddToPopup(ActionContext context) {
|
public boolean isAddToPopup(ActionContext context) {
|
||||||
if (!(context instanceof ListingActionContext)) {
|
if (!(context instanceof ListingActionContext)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return isAddToPopup((ListingActionContext)context);
|
return isAddToPopup((ListingActionContext) context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionContext context) {
|
public void actionPerformed(ActionContext context) {
|
||||||
actionPerformed((ListingActionContext)context);
|
actionPerformed((ListingActionContext) context);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isAddToPopup(ListingActionContext context) {
|
protected boolean isAddToPopup(ListingActionContext context) {
|
||||||
return isEnabledForContext( context );
|
return isEnabledForContext(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isValidContext(ListingActionContext context) {
|
protected boolean isValidContext(ListingActionContext context) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isEnabledForContext(ListingActionContext context) {
|
protected boolean isEnabledForContext(ListingActionContext context) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void actionPerformed(ListingActionContext context) {
|
protected void actionPerformed(ListingActionContext context) {
|
||||||
|
// clients need to override this method
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes) {
|
public boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes) {
|
||||||
for (Class<?> class1 : contextTypes) {
|
for (Class<?> class1 : contextTypes) {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,6 +15,10 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin;
|
package ghidra.app.plugin;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import docking.ActionContext;
|
||||||
|
import docking.action.DockingAction;
|
||||||
import ghidra.app.events.*;
|
import ghidra.app.events.*;
|
||||||
import ghidra.app.services.GoToService;
|
import ghidra.app.services.GoToService;
|
||||||
import ghidra.framework.plugintool.*;
|
import ghidra.framework.plugintool.*;
|
||||||
|
@ -25,10 +28,6 @@ import ghidra.program.model.listing.*;
|
||||||
import ghidra.program.util.ProgramLocation;
|
import ghidra.program.util.ProgramLocation;
|
||||||
import ghidra.program.util.ProgramSelection;
|
import ghidra.program.util.ProgramSelection;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import docking.action.DockingAction;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class to handle common program events: Program Open/Close,
|
* Base class to handle common program events: Program Open/Close,
|
||||||
* Program Location, Program Selection, and Program Highlight.
|
* Program Location, Program Selection, and Program Highlight.
|
||||||
|
@ -87,10 +86,10 @@ public abstract class ProgramPlugin extends Plugin {
|
||||||
}
|
}
|
||||||
registerEventConsumed(ProgramOpenedPluginEvent.class);
|
registerEventConsumed(ProgramOpenedPluginEvent.class);
|
||||||
registerEventConsumed(ProgramClosedPluginEvent.class);
|
registerEventConsumed(ProgramClosedPluginEvent.class);
|
||||||
programActionList = new ArrayList<DockingAction>(3);
|
programActionList = new ArrayList<>(3);
|
||||||
locationActionList = new ArrayList<DockingAction>(3);
|
locationActionList = new ArrayList<>(3);
|
||||||
selectionActionList = new ArrayList<DockingAction>(3);
|
selectionActionList = new ArrayList<>(3);
|
||||||
highlightActionList = new ArrayList<DockingAction>(3);
|
highlightActionList = new ArrayList<>(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProgramPlugin(PluginTool tool, boolean consumeLocationChange,
|
public ProgramPlugin(PluginTool tool, boolean consumeLocationChange,
|
||||||
|
@ -201,7 +200,10 @@ public abstract class ProgramPlugin extends Plugin {
|
||||||
* the program is closed.
|
* the program is closed.
|
||||||
* @throws IllegalArgumentException if this action was called for
|
* @throws IllegalArgumentException if this action was called for
|
||||||
* another enableOnXXX(PlugAction) method.
|
* another enableOnXXX(PlugAction) method.
|
||||||
|
* @deprecated {@link ActionContext} is now used for action enablement. Deprecated in 9.1; to
|
||||||
|
* be removed no sooner than two versions after that.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
protected void enableOnProgram(DockingAction action) {
|
protected void enableOnProgram(DockingAction action) {
|
||||||
if (locationActionList.contains(action)) {
|
if (locationActionList.contains(action)) {
|
||||||
throw new IllegalArgumentException("Action already added to location action list");
|
throw new IllegalArgumentException("Action already added to location action list");
|
||||||
|
@ -222,7 +224,10 @@ public abstract class ProgramPlugin extends Plugin {
|
||||||
* is null.
|
* is null.
|
||||||
* @throws IllegalArgumentException if this action was called for
|
* @throws IllegalArgumentException if this action was called for
|
||||||
* another enableOnXXX(PlugAction) method.
|
* another enableOnXXX(PlugAction) method.
|
||||||
|
* @deprecated {@link ActionContext} is now used for action enablement. Deprecated in 9.1; to
|
||||||
|
* be removed no sooner than two versions after that.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
protected void enableOnLocation(DockingAction action) {
|
protected void enableOnLocation(DockingAction action) {
|
||||||
if (programActionList.contains(action)) {
|
if (programActionList.contains(action)) {
|
||||||
throw new IllegalArgumentException("Action already added to program action list");
|
throw new IllegalArgumentException("Action already added to program action list");
|
||||||
|
@ -243,7 +248,10 @@ public abstract class ProgramPlugin extends Plugin {
|
||||||
* the selection is null or empty.
|
* the selection is null or empty.
|
||||||
* @throws IllegalArgumentException if this action was called for
|
* @throws IllegalArgumentException if this action was called for
|
||||||
* another enableOnXXX(PlugAction) method.
|
* another enableOnXXX(PlugAction) method.
|
||||||
|
* @deprecated {@link ActionContext} is now used for action enablement. Deprecated in 9.1; to
|
||||||
|
* be removed no sooner than two versions after that.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
protected void enableOnSelection(DockingAction action) {
|
protected void enableOnSelection(DockingAction action) {
|
||||||
if (programActionList.contains(action)) {
|
if (programActionList.contains(action)) {
|
||||||
throw new IllegalArgumentException("Action already added to program action list");
|
throw new IllegalArgumentException("Action already added to program action list");
|
||||||
|
@ -263,7 +271,10 @@ public abstract class ProgramPlugin extends Plugin {
|
||||||
* the highlight is null or empty.
|
* the highlight is null or empty.
|
||||||
* @throws IllegalArgumentException if this action was called for
|
* @throws IllegalArgumentException if this action was called for
|
||||||
* another enableOnXXX(PlugAction) method.
|
* another enableOnXXX(PlugAction) method.
|
||||||
|
* @deprecated {@link ActionContext} is now used for action enablement. Deprecated in 9.1; to
|
||||||
|
* be removed no sooner than two versions after that.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
protected void enableOnHighlight(DockingAction action) {
|
protected void enableOnHighlight(DockingAction action) {
|
||||||
if (programActionList.contains(action)) {
|
if (programActionList.contains(action)) {
|
||||||
throw new IllegalArgumentException("Action already added to program action list");
|
throw new IllegalArgumentException("Action already added to program action list");
|
||||||
|
@ -378,8 +389,8 @@ public abstract class ProgramPlugin extends Plugin {
|
||||||
if (currentProgram == null) {
|
if (currentProgram == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
firePluginEvent(new ProgramSelectionPluginEvent(getName(), new ProgramSelection(set),
|
firePluginEvent(
|
||||||
currentProgram));
|
new ProgramSelectionPluginEvent(getName(), new ProgramSelection(set), currentProgram));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -22,7 +22,6 @@ import javax.swing.Icon;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
import docking.ActionContext;
|
import docking.ActionContext;
|
||||||
import docking.DockingUtils;
|
|
||||||
import docking.action.*;
|
import docking.action.*;
|
||||||
import docking.widgets.table.GTable;
|
import docking.widgets.table.GTable;
|
||||||
import ghidra.app.CorePluginPackage;
|
import ghidra.app.CorePluginPackage;
|
||||||
|
@ -72,7 +71,6 @@ public class BookmarkPlugin extends ProgramPlugin
|
||||||
|
|
||||||
private BookmarkProvider provider;
|
private BookmarkProvider provider;
|
||||||
private DockingAction addAction;
|
private DockingAction addAction;
|
||||||
private DockingAction showAction;
|
|
||||||
private DockingAction deleteAction;
|
private DockingAction deleteAction;
|
||||||
private CreateBookmarkDialog createDialog;
|
private CreateBookmarkDialog createDialog;
|
||||||
private GoToService goToService;
|
private GoToService goToService;
|
||||||
|
@ -113,19 +111,6 @@ public class BookmarkPlugin extends ProgramPlugin
|
||||||
addAction.setEnabled(true);
|
addAction.setEnabled(true);
|
||||||
tool.addAction(addAction);
|
tool.addAction(addAction);
|
||||||
|
|
||||||
showAction = new DockingAction("Show Bookmarks", getName()) {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionContext context) {
|
|
||||||
tool.showComponentProvider(provider, true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
showAction.setKeyBindingData(
|
|
||||||
new KeyBindingData(KeyEvent.VK_B, DockingUtils.CONTROL_KEY_MODIFIER_MASK));
|
|
||||||
showAction.setToolBarData(new ToolBarData(BookmarkNavigator.NOTE_ICON, "View"));
|
|
||||||
showAction.setDescription("Display All Bookmarks");
|
|
||||||
tool.addAction(showAction);
|
|
||||||
|
|
||||||
MultiIconBuilder builder = new MultiIconBuilder(Icons.CONFIGURE_FILTER_ICON);
|
MultiIconBuilder builder = new MultiIconBuilder(Icons.CONFIGURE_FILTER_ICON);
|
||||||
builder.addLowerRightIcon(ResourceManager.loadImage("images/check.png"));
|
builder.addLowerRightIcon(ResourceManager.loadImage("images/check.png"));
|
||||||
Icon filterTypesChanged = builder.build();
|
Icon filterTypesChanged = builder.build();
|
||||||
|
@ -213,10 +198,6 @@ public class BookmarkPlugin extends ProgramPlugin
|
||||||
addAction.dispose();
|
addAction.dispose();
|
||||||
addAction = null;
|
addAction = null;
|
||||||
}
|
}
|
||||||
if (showAction != null) {
|
|
||||||
showAction.dispose();
|
|
||||||
showAction = null;
|
|
||||||
}
|
|
||||||
if (provider != null) {
|
if (provider != null) {
|
||||||
provider.dispose();
|
provider.dispose();
|
||||||
provider = null;
|
provider = null;
|
||||||
|
|
|
@ -17,6 +17,7 @@ package ghidra.app.plugin.core.bookmark;
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
@ -24,8 +25,8 @@ import javax.swing.*;
|
||||||
import javax.swing.event.TableModelListener;
|
import javax.swing.event.TableModelListener;
|
||||||
import javax.swing.table.TableColumn;
|
import javax.swing.table.TableColumn;
|
||||||
|
|
||||||
import docking.ActionContext;
|
import docking.*;
|
||||||
import docking.WindowPosition;
|
import docking.action.KeyBindingData;
|
||||||
import docking.widgets.combobox.GhidraComboBox;
|
import docking.widgets.combobox.GhidraComboBox;
|
||||||
import docking.widgets.table.GTable;
|
import docking.widgets.table.GTable;
|
||||||
import ghidra.app.context.ProgramActionContext;
|
import ghidra.app.context.ProgramActionContext;
|
||||||
|
@ -58,6 +59,9 @@ public class BookmarkProvider extends ComponentProviderAdapter {
|
||||||
super(tool, "Bookmarks", plugin.getName(), ProgramActionContext.class);
|
super(tool, "Bookmarks", plugin.getName(), ProgramActionContext.class);
|
||||||
|
|
||||||
setIcon(BookmarkNavigator.NOTE_ICON);
|
setIcon(BookmarkNavigator.NOTE_ICON);
|
||||||
|
addToToolbar();
|
||||||
|
setKeyBinding(new KeyBindingData(KeyEvent.VK_B, DockingUtils.CONTROL_KEY_MODIFIER_MASK));
|
||||||
|
|
||||||
model = new BookmarkTableModel(tool, null);
|
model = new BookmarkTableModel(tool, null);
|
||||||
threadedTablePanel = new GhidraThreadedTablePanel<>(model);
|
threadedTablePanel = new GhidraThreadedTablePanel<>(model);
|
||||||
|
|
||||||
|
|
|
@ -62,12 +62,14 @@ public class CallTreePlugin extends ProgramPlugin {
|
||||||
ResourceManager.loadImage("images/arrow_rotate_clockwise.png");
|
ResourceManager.loadImage("images/arrow_rotate_clockwise.png");
|
||||||
|
|
||||||
private List<CallTreeProvider> providers = new ArrayList<>();
|
private List<CallTreeProvider> providers = new ArrayList<>();
|
||||||
private DockingAction showProviderAction;
|
private DockingAction showCallTreeFromMenuAction;
|
||||||
|
private CallTreeProvider primaryProvider;
|
||||||
|
|
||||||
public CallTreePlugin(PluginTool tool) {
|
public CallTreePlugin(PluginTool tool) {
|
||||||
super(tool, true, false, false);
|
super(tool, true, false, false);
|
||||||
|
|
||||||
createActions();
|
createActions();
|
||||||
|
primaryProvider = new CallTreeProvider(this, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -116,32 +118,44 @@ public class CallTreePlugin extends ProgramPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createActions() {
|
private void createActions() {
|
||||||
showProviderAction = new DockingAction("Show Function Call Trees", getName()) {
|
|
||||||
|
|
||||||
@Override
|
// use the name of the provider so that the shared key binding data will get used
|
||||||
public void actionPerformed(ActionContext context) {
|
String actionName = CallTreeProvider.TITLE;
|
||||||
showOrCreateNewCallTree(currentLocation);
|
showCallTreeFromMenuAction =
|
||||||
}
|
new DockingAction(actionName, getName(), KeyBindingType.SHARED) {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionContext context) {
|
||||||
|
showOrCreateNewCallTree(currentLocation);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAddToPopup(ActionContext context) {
|
public boolean isAddToPopup(ActionContext context) {
|
||||||
return (context instanceof ListingActionContext);
|
return (context instanceof ListingActionContext);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
showProviderAction.setPopupMenuData(new MenuData(
|
|
||||||
|
showCallTreeFromMenuAction.setPopupMenuData(new MenuData(
|
||||||
new String[] { "References", "Show Call Trees" }, PROVIDER_ICON, "ShowReferencesTo"));
|
new String[] { "References", "Show Call Trees" }, PROVIDER_ICON, "ShowReferencesTo"));
|
||||||
showProviderAction.setToolBarData(new ToolBarData(PROVIDER_ICON, "View"));
|
showCallTreeFromMenuAction.setHelpLocation(
|
||||||
showProviderAction.setHelpLocation(new HelpLocation("CallTreePlugin", "Call_Tree_Plugin"));
|
new HelpLocation("CallTreePlugin", "Call_Tree_Plugin"));
|
||||||
tool.addAction(showProviderAction);
|
tool.addAction(showCallTreeFromMenuAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void creatAndShowProvider() {
|
private void creatAndShowProvider() {
|
||||||
CallTreeProvider provider = new CallTreeProvider(this);
|
CallTreeProvider provider = new CallTreeProvider(this, false);
|
||||||
providers.add(provider);
|
providers.add(provider);
|
||||||
provider.initialize(currentProgram, currentLocation);
|
provider.initialize(currentProgram, currentLocation);
|
||||||
tool.showComponentProvider(provider, true);
|
tool.showComponentProvider(provider, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CallTreeProvider getPrimaryProvider() {
|
||||||
|
return primaryProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
DockingAction getShowCallTreeFromMenuAction() {
|
||||||
|
return showCallTreeFromMenuAction;
|
||||||
|
}
|
||||||
|
|
||||||
ProgramLocation getCurrentLocation() {
|
ProgramLocation getCurrentLocation() {
|
||||||
return currentLocation;
|
return currentLocation;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ import resources.ResourceManager;
|
||||||
public class CallTreeProvider extends ComponentProviderAdapter implements DomainObjectListener {
|
public class CallTreeProvider extends ComponentProviderAdapter implements DomainObjectListener {
|
||||||
|
|
||||||
static final String EXPAND_ACTION_NAME = "Fully Expand Selected Nodes";
|
static final String EXPAND_ACTION_NAME = "Fully Expand Selected Nodes";
|
||||||
private static final String TITLE = "Function Call Trees";
|
static final String TITLE = "Function Call Trees";
|
||||||
private static final Icon EMPTY_ICON = ResourceManager.loadImage("images/EmptyIcon16.gif");
|
private static final Icon EMPTY_ICON = ResourceManager.loadImage("images/EmptyIcon16.gif");
|
||||||
private static final Icon EXPAND_ICON = Icons.EXPAND_ALL_ICON;
|
private static final Icon EXPAND_ICON = Icons.EXPAND_ALL_ICON;
|
||||||
private static final Icon COLLAPSE_ICON = Icons.COLLAPSE_ALL_ICON;
|
private static final Icon COLLAPSE_ICON = Icons.COLLAPSE_ALL_ICON;
|
||||||
|
@ -74,6 +74,7 @@ public class CallTreeProvider extends ComponentProviderAdapter implements Domain
|
||||||
private JSplitPane splitPane;
|
private JSplitPane splitPane;
|
||||||
private GTree incomingTree;
|
private GTree incomingTree;
|
||||||
private GTree outgoingTree;
|
private GTree outgoingTree;
|
||||||
|
private boolean isPrimary;
|
||||||
|
|
||||||
private SwingUpdateManager reloadUpdateManager = new SwingUpdateManager(500, () -> doUpdate());
|
private SwingUpdateManager reloadUpdateManager = new SwingUpdateManager(500, () -> doUpdate());
|
||||||
|
|
||||||
|
@ -93,20 +94,21 @@ public class CallTreeProvider extends ComponentProviderAdapter implements Domain
|
||||||
private AtomicInteger recurseDepth = new AtomicInteger();
|
private AtomicInteger recurseDepth = new AtomicInteger();
|
||||||
private NumberIcon recurseIcon;
|
private NumberIcon recurseIcon;
|
||||||
|
|
||||||
public CallTreeProvider(CallTreePlugin plugin) {
|
public CallTreeProvider(CallTreePlugin plugin, boolean isPrimary) {
|
||||||
super(plugin.getTool(), TITLE, plugin.getName());
|
super(plugin.getTool(), TITLE, plugin.getName());
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
|
this.isPrimary = isPrimary;
|
||||||
|
|
||||||
component = buildComponent();
|
component = buildComponent();
|
||||||
|
|
||||||
// try to give the trees a suitable amount of space by default
|
// try to give the trees a suitable amount of space by default
|
||||||
component.setPreferredSize(new Dimension(800, 400));
|
component.setPreferredSize(new Dimension(800, 400));
|
||||||
|
|
||||||
setTransient();
|
|
||||||
setWindowMenuGroup(TITLE);
|
setWindowMenuGroup(TITLE);
|
||||||
setDefaultWindowPosition(WindowPosition.BOTTOM);
|
setDefaultWindowPosition(WindowPosition.BOTTOM);
|
||||||
|
|
||||||
setIcon(CallTreePlugin.PROVIDER_ICON);
|
setIcon(CallTreePlugin.PROVIDER_ICON);
|
||||||
|
addToToolbar();
|
||||||
setHelpLocation(new HelpLocation(plugin.getName(), "Call_Tree_Plugin"));
|
setHelpLocation(new HelpLocation(plugin.getName(), "Call_Tree_Plugin"));
|
||||||
|
|
||||||
addToTool();
|
addToTool();
|
||||||
|
@ -430,7 +432,11 @@ public class CallTreeProvider extends ComponentProviderAdapter implements Domain
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
navigateIncomingToggleAction.setSelected(false);
|
|
||||||
|
// note: the default state is to follow navigation events for the primary provider;
|
||||||
|
// non-primary providers will function like snapshots of the function with
|
||||||
|
// which they were activated.
|
||||||
|
navigateIncomingToggleAction.setSelected(isPrimary);
|
||||||
navigateIncomingToggleAction.setToolBarData(new ToolBarData(
|
navigateIncomingToggleAction.setToolBarData(new ToolBarData(
|
||||||
Icons.NAVIGATE_ON_INCOMING_EVENT_ICON, navigationOptionsToolbarGroup, "2"));
|
Icons.NAVIGATE_ON_INCOMING_EVENT_ICON, navigationOptionsToolbarGroup, "2"));
|
||||||
navigateIncomingToggleAction.setDescription(HTMLUtilities.toHTML("Incoming Navigation" +
|
navigateIncomingToggleAction.setDescription(HTMLUtilities.toHTML("Incoming Navigation" +
|
||||||
|
@ -818,7 +824,9 @@ public class CallTreeProvider extends ComponentProviderAdapter implements Domain
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void componentHidden() {
|
public void componentHidden() {
|
||||||
plugin.removeProvider(this);
|
if (!isPrimary) {
|
||||||
|
plugin.removeProvider(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reload() {
|
private void reload() {
|
||||||
|
@ -869,6 +877,7 @@ public class CallTreeProvider extends ComponentProviderAdapter implements Domain
|
||||||
// changes, which means we will get here while setting the location, but our program
|
// changes, which means we will get here while setting the location, but our program
|
||||||
// will have been null'ed out.
|
// will have been null'ed out.
|
||||||
currentProgram = plugin.getCurrentProgram();
|
currentProgram = plugin.getCurrentProgram();
|
||||||
|
currentProgram.addListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Function function = plugin.getFunction(location);
|
Function function = plugin.getFunction(location);
|
||||||
|
|
|
@ -915,18 +915,13 @@ public class CodeBrowserPlugin extends Plugin
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// note: this action gets added later when the TableService is added
|
||||||
tableFromSelectionAction.setEnabled(false);
|
tableFromSelectionAction.setEnabled(false);
|
||||||
tableFromSelectionAction.setMenuBarData(new MenuData(
|
tableFromSelectionAction.setMenuBarData(new MenuData(
|
||||||
new String[] { ToolConstants.MENU_SELECTION, "Create Table From Selection" }, null,
|
new String[] { ToolConstants.MENU_SELECTION, "Create Table From Selection" }, null,
|
||||||
"SelectUtils"));
|
"SelectUtils"));
|
||||||
tableFromSelectionAction
|
tableFromSelectionAction.setHelpLocation(
|
||||||
.setHelpLocation(new HelpLocation("CodeBrowserPlugin", "Selection_Table"));
|
new HelpLocation("CodeBrowserPlugin", "Selection_Table"));
|
||||||
|
|
||||||
// don't add the actions initially if the service isn't there
|
|
||||||
TableService tableService = tool.getService(TableService.class);
|
|
||||||
if (tableService != null) {
|
|
||||||
tool.addAction(tableFromSelectionAction);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private GhidraProgramTableModel<Address> createTableModel(CodeUnitIterator iterator,
|
private GhidraProgramTableModel<Address> createTableModel(CodeUnitIterator iterator,
|
||||||
|
@ -1001,8 +996,8 @@ public class CodeBrowserPlugin extends Plugin
|
||||||
public boolean goToField(Address a, String fieldName, int occurrence, int row, int col,
|
public boolean goToField(Address a, String fieldName, int occurrence, int row, int col,
|
||||||
boolean scroll) {
|
boolean scroll) {
|
||||||
|
|
||||||
boolean result = SystemUtilities
|
boolean result = SystemUtilities.runSwingNow(
|
||||||
.runSwingNow(() -> doGoToField(a, fieldName, occurrence, row, col, scroll));
|
() -> doGoToField(a, fieldName, occurrence, row, col, scroll));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@ import docking.widgets.fieldpanel.FieldPanel;
|
||||||
import docking.widgets.fieldpanel.HoverHandler;
|
import docking.widgets.fieldpanel.HoverHandler;
|
||||||
import docking.widgets.fieldpanel.internal.FieldPanelCoordinator;
|
import docking.widgets.fieldpanel.internal.FieldPanelCoordinator;
|
||||||
import docking.widgets.fieldpanel.support.*;
|
import docking.widgets.fieldpanel.support.*;
|
||||||
import ghidra.GhidraOptions;
|
|
||||||
import ghidra.app.nav.*;
|
import ghidra.app.nav.*;
|
||||||
import ghidra.app.plugin.core.clipboard.CodeBrowserClipboardProvider;
|
import ghidra.app.plugin.core.clipboard.CodeBrowserClipboardProvider;
|
||||||
import ghidra.app.plugin.core.codebrowser.actions.*;
|
import ghidra.app.plugin.core.codebrowser.actions.*;
|
||||||
|
@ -54,6 +53,7 @@ import ghidra.program.model.address.*;
|
||||||
import ghidra.program.model.listing.*;
|
import ghidra.program.model.listing.*;
|
||||||
import ghidra.program.util.*;
|
import ghidra.program.util.*;
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
|
import ghidra.util.Swing;
|
||||||
import resources.ResourceManager;
|
import resources.ResourceManager;
|
||||||
|
|
||||||
public class CodeViewerProvider extends NavigatableComponentProviderAdapter
|
public class CodeViewerProvider extends NavigatableComponentProviderAdapter
|
||||||
|
@ -62,8 +62,6 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
|
||||||
|
|
||||||
private static final String TITLE = "Listing: ";
|
private static final String TITLE = "Listing: ";
|
||||||
|
|
||||||
private static final String OPERAND_OPTIONS_PREFIX = GhidraOptions.OPERAND_GROUP_TITLE + ".";
|
|
||||||
|
|
||||||
private static final Icon LISTING_FORMAT_EXPAND_ICON =
|
private static final Icon LISTING_FORMAT_EXPAND_ICON =
|
||||||
ResourceManager.loadImage("images/field.header.down.png");
|
ResourceManager.loadImage("images/field.header.down.png");
|
||||||
private static final Icon LISTING_FORMAT_COLLAPSE_ICON =
|
private static final Icon LISTING_FORMAT_COLLAPSE_ICON =
|
||||||
|
@ -92,9 +90,6 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
|
||||||
private ProgramDropProvider curDropProvider;
|
private ProgramDropProvider curDropProvider;
|
||||||
private ToggleDockingAction toggleHoverAction;
|
private ToggleDockingAction toggleHoverAction;
|
||||||
|
|
||||||
//TODO - Need to improve CodeUnit.getRepresentation format options interface before adding this
|
|
||||||
//TODO private ToggleOperandMarkupAction[] toggleOperandMarkupActions;
|
|
||||||
|
|
||||||
private ProgramLocation currentLocation;
|
private ProgramLocation currentLocation;
|
||||||
|
|
||||||
private ListingPanel otherPanel;
|
private ListingPanel otherPanel;
|
||||||
|
@ -117,17 +112,26 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
|
||||||
private MultiListingLayoutModel multiModel;
|
private MultiListingLayoutModel multiModel;
|
||||||
|
|
||||||
public CodeViewerProvider(CodeBrowserPluginInterface plugin, FormatManager formatMgr,
|
public CodeViewerProvider(CodeBrowserPluginInterface plugin, FormatManager formatMgr,
|
||||||
boolean connected) {
|
boolean isConnected) {
|
||||||
super(plugin.getTool(), plugin.getName(), plugin.getName(), CodeViewerActionContext.class);
|
super(plugin.getTool(), "Listing", plugin.getName(), CodeViewerActionContext.class);
|
||||||
|
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.formatMgr = formatMgr;
|
this.formatMgr = formatMgr;
|
||||||
setConnected(connected);
|
|
||||||
|
setConnected(isConnected);
|
||||||
|
setIcon(ResourceManager.loadImage("images/Browser.gif"));
|
||||||
|
if (!isConnected) {
|
||||||
|
setTransient();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
addToToolbar();
|
||||||
|
}
|
||||||
setHelpLocation(new HelpLocation("CodeBrowserPlugin", "Code_Browser"));
|
setHelpLocation(new HelpLocation("CodeBrowserPlugin", "Code_Browser"));
|
||||||
setDefaultWindowPosition(WindowPosition.RIGHT);
|
setDefaultWindowPosition(WindowPosition.RIGHT);
|
||||||
setIcon(ResourceManager.loadImage("images/Browser.gif"));
|
|
||||||
listingPanel = new ListingPanel(formatMgr);
|
listingPanel = new ListingPanel(formatMgr);
|
||||||
listingPanel.enablePropertyBasedColorModel(true);
|
listingPanel.enablePropertyBasedColorModel(true);
|
||||||
decorationPanel = new ListingPanelContainer(listingPanel, connected);
|
decorationPanel = new ListingPanelContainer(listingPanel, isConnected);
|
||||||
ListingHighlightProvider listingHighlighter =
|
ListingHighlightProvider listingHighlighter =
|
||||||
createListingHighlighter(listingPanel, tool, decorationPanel);
|
createListingHighlighter(listingPanel, tool, decorationPanel);
|
||||||
highlighterAdapter = new ProgramHighlighterProvider(listingHighlighter);
|
highlighterAdapter = new ProgramHighlighterProvider(listingHighlighter);
|
||||||
|
@ -136,7 +140,7 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
|
||||||
setWindowMenuGroup("Listing");
|
setWindowMenuGroup("Listing");
|
||||||
setIntraGroupPosition(WindowPosition.RIGHT);
|
setIntraGroupPosition(WindowPosition.RIGHT);
|
||||||
|
|
||||||
setTitle(connected ? TITLE : "[" + TITLE + "]");
|
setTitle(isConnected ? TITLE : "[" + TITLE + "]");
|
||||||
fieldNavigator = new FieldNavigator(tool, this);
|
fieldNavigator = new FieldNavigator(tool, this);
|
||||||
listingPanel.addButtonPressedListener(fieldNavigator);
|
listingPanel.addButtonPressedListener(fieldNavigator);
|
||||||
addToTool();
|
addToTool();
|
||||||
|
@ -150,6 +154,12 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
|
||||||
tool.addPopupListener(this);
|
tool.addPopupListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSnapshot() {
|
||||||
|
// we are a snapshot when we are 'disconnected'
|
||||||
|
return !isConnected();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if this listing is backed by a dynamic data source (e.g., debugger)
|
* @return true if this listing is backed by a dynamic data source (e.g., debugger)
|
||||||
*/
|
*/
|
||||||
|
@ -399,9 +409,9 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateTitle() {
|
void updateTitle() {
|
||||||
String subTitle = program == null ? "" : program.getDomainFile().getName();
|
String subTitle = program == null ? "" : ' ' + program.getDomainFile().getName();
|
||||||
String newTitle = isConnected() ? TITLE : "[" + TITLE + "]";
|
String newTitle = isConnected() ? TITLE : "[" + TITLE + subTitle + "]";
|
||||||
setTitle(newTitle + subTitle);
|
setTitle(newTitle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -882,7 +892,7 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
|
||||||
final ViewerPosition vp = listingPanel.getFieldPanel().getViewerPosition();
|
final ViewerPosition vp = listingPanel.getFieldPanel().getViewerPosition();
|
||||||
// invoke later to give the window manage a chance to create the new window
|
// invoke later to give the window manage a chance to create the new window
|
||||||
// (its done in an invoke later)
|
// (its done in an invoke later)
|
||||||
SwingUtilities.invokeLater(() -> {
|
Swing.runLater(() -> {
|
||||||
newProvider.doSetProgram(program);
|
newProvider.doSetProgram(program);
|
||||||
newProvider.listingPanel.getFieldPanel().setViewerPosition(vp.getIndex(),
|
newProvider.listingPanel.getFieldPanel().setViewerPosition(vp.getIndex(),
|
||||||
vp.getXOffset(), vp.getYOffset());
|
vp.getXOffset(), vp.getYOffset());
|
||||||
|
@ -949,7 +959,7 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
|
||||||
|
|
||||||
class ToggleHeaderAction extends ToggleDockingAction {
|
class ToggleHeaderAction extends ToggleDockingAction {
|
||||||
ToggleHeaderAction() {
|
ToggleHeaderAction() {
|
||||||
super("Toggle Header", CodeViewerProvider.this.getName());
|
super("Toggle Header", plugin.getName());
|
||||||
setEnabled(true);
|
setEnabled(true);
|
||||||
|
|
||||||
setToolBarData(new ToolBarData(LISTING_FORMAT_EXPAND_ICON, "zzz"));
|
setToolBarData(new ToolBarData(LISTING_FORMAT_EXPAND_ICON, "zzz"));
|
||||||
|
@ -960,14 +970,14 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
|
||||||
public void actionPerformed(ActionContext context) {
|
public void actionPerformed(ActionContext context) {
|
||||||
boolean show = !listingPanel.isHeaderShowing();
|
boolean show = !listingPanel.isHeaderShowing();
|
||||||
listingPanel.showHeader(show);
|
listingPanel.showHeader(show);
|
||||||
getToolBarData()
|
getToolBarData().setIcon(
|
||||||
.setIcon(show ? LISTING_FORMAT_COLLAPSE_ICON : LISTING_FORMAT_EXPAND_ICON);
|
show ? LISTING_FORMAT_COLLAPSE_ICON : LISTING_FORMAT_EXPAND_ICON);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ToggleHoverAction extends ToggleDockingAction {
|
private class ToggleHoverAction extends ToggleDockingAction {
|
||||||
ToggleHoverAction() {
|
ToggleHoverAction() {
|
||||||
super("Toggle Mouse Hover Popups", CodeViewerProvider.this.getName());
|
super("Toggle Mouse Hover Popups", CodeViewerProvider.this.getOwner());
|
||||||
setEnabled(true);
|
setEnabled(true);
|
||||||
setToolBarData(new ToolBarData(HOVER_ON_ICON, "yyyz"));
|
setToolBarData(new ToolBarData(HOVER_ON_ICON, "yyyz"));
|
||||||
setSelected(true);
|
setSelected(true);
|
||||||
|
@ -987,31 +997,6 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ToggleOperandMarkupAction extends ToggleDockingAction {
|
|
||||||
final String optionName;
|
|
||||||
|
|
||||||
ToggleOperandMarkupAction(String operandOption) {
|
|
||||||
super(operandOption, CodeViewerProvider.this.getName());
|
|
||||||
this.optionName = OPERAND_OPTIONS_PREFIX + operandOption;
|
|
||||||
boolean state =
|
|
||||||
tool.getOptions(GhidraOptions.CATEGORY_BROWSER_FIELDS).getBoolean(optionName, true);
|
|
||||||
setMenuBarData(new MenuData(new String[] { operandOption }));
|
|
||||||
setSelected(state);
|
|
||||||
setEnabled(true);
|
|
||||||
setHelpLocation(new HelpLocation("CodeBrowserPlugin", "Operands_Field"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object getOptionName() {
|
|
||||||
return optionName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionContext context) {
|
|
||||||
boolean state = isSelected();
|
|
||||||
tool.getOptions(GhidraOptions.CATEGORY_BROWSER_FIELDS).setBoolean(optionName, state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class that allows clients to install transient highlighters while keeping the
|
* A class that allows clients to install transient highlighters while keeping the
|
||||||
* middle-mouse highlighting on at the same time.
|
* middle-mouse highlighting on at the same time.
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.codebrowser.actions;
|
package ghidra.app.plugin.core.codebrowser.actions;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import docking.ActionContext;
|
import docking.ActionContext;
|
||||||
|
@ -24,21 +22,17 @@ import docking.action.DockingAction;
|
||||||
import ghidra.app.plugin.core.codebrowser.CodeViewerActionContext;
|
import ghidra.app.plugin.core.codebrowser.CodeViewerActionContext;
|
||||||
|
|
||||||
public abstract class CodeViewerContextAction extends DockingAction {
|
public abstract class CodeViewerContextAction extends DockingAction {
|
||||||
|
|
||||||
public CodeViewerContextAction(String name, String owner) {
|
public CodeViewerContextAction(String name, String owner) {
|
||||||
this(name, owner, true);
|
super(name, owner);
|
||||||
}
|
|
||||||
|
|
||||||
public CodeViewerContextAction(String name, String owner, boolean isKeyBindingManaged) {
|
|
||||||
super(name, owner, isKeyBindingManaged);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabledForContext(ActionContext context) {
|
public boolean isEnabledForContext(ActionContext context) {
|
||||||
if (!(context instanceof CodeViewerActionContext)) {
|
if (!(context instanceof CodeViewerActionContext)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return isEnabledForContext((CodeViewerActionContext)context);
|
return isEnabledForContext((CodeViewerActionContext) context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -46,26 +40,25 @@ public abstract class CodeViewerContextAction extends DockingAction {
|
||||||
if (!(context instanceof CodeViewerActionContext)) {
|
if (!(context instanceof CodeViewerActionContext)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return isValidContext((CodeViewerActionContext)context);
|
return isValidContext((CodeViewerActionContext) context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAddToPopup(ActionContext context) {
|
public boolean isAddToPopup(ActionContext context) {
|
||||||
if (!(context instanceof CodeViewerActionContext)) {
|
if (!(context instanceof CodeViewerActionContext)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return isAddToPopup((CodeViewerActionContext)context);
|
return isAddToPopup((CodeViewerActionContext) context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionContext context) {
|
public void actionPerformed(ActionContext context) {
|
||||||
actionPerformed((CodeViewerActionContext)context);
|
actionPerformed((CodeViewerActionContext) context);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isAddToPopup(CodeViewerActionContext context) {
|
protected boolean isAddToPopup(CodeViewerActionContext context) {
|
||||||
return isEnabledForContext( context );
|
return isEnabledForContext(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected boolean isValidContext(CodeViewerActionContext context) {
|
protected boolean isValidContext(CodeViewerActionContext context) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -76,9 +69,9 @@ public abstract class CodeViewerContextAction extends DockingAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void actionPerformed(CodeViewerActionContext context) {
|
protected void actionPerformed(CodeViewerActionContext context) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes) {
|
public boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes) {
|
||||||
for (Class<?> class1 : contextTypes) {
|
for (Class<?> class1 : contextTypes) {
|
||||||
|
|
|
@ -39,7 +39,7 @@ public class CollapseAllDataAction extends ProgramLocationContextAction {
|
||||||
private CodeViewerProvider provider;
|
private CodeViewerProvider provider;
|
||||||
|
|
||||||
public CollapseAllDataAction(CodeViewerProvider provider) {
|
public CollapseAllDataAction(CodeViewerProvider provider) {
|
||||||
super("Collapse All Data", provider.getName());
|
super("Collapse All Data", provider.getOwner());
|
||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
|
|
||||||
setPopupMenuData(new MenuData(new String[] { "Collapse All Data" }, null, "Structure"));
|
setPopupMenuData(new MenuData(new String[] { "Collapse All Data" }, null, "Structure"));
|
||||||
|
@ -95,8 +95,7 @@ public class CollapseAllDataAction extends ProgramLocationContextAction {
|
||||||
|
|
||||||
ProgramLocation location = context.getLocation();
|
ProgramLocation location = context.getLocation();
|
||||||
Data data = getTopLevelComponentData(location);
|
Data data = getTopLevelComponentData(location);
|
||||||
TaskLauncher.launchModal("Collapse Data",
|
TaskLauncher.launchModal("Collapse Data", monitor -> model.closeAllData(data, monitor));
|
||||||
monitor -> model.closeAllData(data, monitor));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ListingModel getModel() {
|
private ListingModel getModel() {
|
||||||
|
|
|
@ -36,7 +36,7 @@ public class ExpandAllDataAction extends ProgramLocationContextAction {
|
||||||
private CodeViewerProvider provider;
|
private CodeViewerProvider provider;
|
||||||
|
|
||||||
public ExpandAllDataAction(CodeViewerProvider provider) {
|
public ExpandAllDataAction(CodeViewerProvider provider) {
|
||||||
super("Expand All Data", provider.getName());
|
super("Expand All Data", provider.getOwner());
|
||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
|
|
||||||
setPopupMenuData(new MenuData(new String[] { "Expand All Data" }, null, "Structure"));
|
setPopupMenuData(new MenuData(new String[] { "Expand All Data" }, null, "Structure"));
|
||||||
|
|
|
@ -39,7 +39,7 @@ public class ToggleExpandCollapseDataAction extends ProgramLocationContextAction
|
||||||
private CodeViewerProvider provider;
|
private CodeViewerProvider provider;
|
||||||
|
|
||||||
public ToggleExpandCollapseDataAction(CodeViewerProvider provider) {
|
public ToggleExpandCollapseDataAction(CodeViewerProvider provider) {
|
||||||
super("Toggle Expand/Collapse Data", provider.getName());
|
super("Toggle Expand/Collapse Data", provider.getOwner());
|
||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
|
|
||||||
setPopupMenuData(
|
setPopupMenuData(
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.commentwindow;
|
package ghidra.app.plugin.core.commentwindow;
|
||||||
|
|
||||||
import docking.ActionContext;
|
|
||||||
import docking.action.DockingAction;
|
import docking.action.DockingAction;
|
||||||
import ghidra.app.CorePluginPackage;
|
import ghidra.app.CorePluginPackage;
|
||||||
import ghidra.app.events.ProgramSelectionPluginEvent;
|
import ghidra.app.events.ProgramSelectionPluginEvent;
|
||||||
|
@ -186,13 +185,7 @@ public class CommentWindowPlugin extends ProgramPlugin implements DomainObjectLi
|
||||||
|
|
||||||
private void createActions() {
|
private void createActions() {
|
||||||
|
|
||||||
selectAction = new MakeProgramSelectionAction(getName(), provider.getTable()) {
|
selectAction = new MakeProgramSelectionAction(this, provider.getTable());
|
||||||
@Override
|
|
||||||
protected void makeSelection(ActionContext context) {
|
|
||||||
selectComment(provider.selectComment());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
tool.addLocalAction(provider, selectAction);
|
tool.addLocalAction(provider, selectAction);
|
||||||
|
|
||||||
DockingAction selectionAction = new SelectionNavigationAction(this, provider.getTable());
|
DockingAction selectionAction = new SelectionNavigationAction(this, provider.getTable());
|
||||||
|
|
|
@ -15,15 +15,14 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.compositeeditor;
|
package ghidra.app.plugin.core.compositeeditor;
|
||||||
|
|
||||||
import ghidra.framework.plugintool.Plugin;
|
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
|
||||||
import ghidra.util.HelpLocation;
|
|
||||||
|
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
import docking.action.*;
|
import docking.action.*;
|
||||||
|
import ghidra.framework.plugintool.Plugin;
|
||||||
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
|
import ghidra.util.HelpLocation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CompositeEditorAction is an abstract class that should be extended for any
|
* CompositeEditorAction is an abstract class that should be extended for any
|
||||||
|
@ -45,13 +44,14 @@ abstract public class CompositeEditorTableAction extends DockingAction implement
|
||||||
|
|
||||||
public static final String EDIT_ACTION_PREFIX = "Editor: ";
|
public static final String EDIT_ACTION_PREFIX = "Editor: ";
|
||||||
|
|
||||||
/**
|
|
||||||
* Defines an <code>Action</code> object with the specified
|
|
||||||
* description string and a the specified icon.
|
|
||||||
*/
|
|
||||||
public CompositeEditorTableAction(CompositeEditorProvider provider, String name, String group,
|
public CompositeEditorTableAction(CompositeEditorProvider provider, String name, String group,
|
||||||
String[] popupPath, String[] menuPath, ImageIcon icon) {
|
String[] popupPath, String[] menuPath, ImageIcon icon) {
|
||||||
super(name, provider.plugin.getName());
|
this(provider, name, group, popupPath, menuPath, icon, KeyBindingType.INDIVIDUAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompositeEditorTableAction(CompositeEditorProvider provider, String name, String group,
|
||||||
|
String[] popupPath, String[] menuPath, ImageIcon icon, KeyBindingType kbType) {
|
||||||
|
super(name, provider.plugin.getName(), kbType);
|
||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
model = provider.getModel();
|
model = provider.getModel();
|
||||||
if (menuPath != null) {
|
if (menuPath != null) {
|
||||||
|
@ -70,9 +70,6 @@ abstract public class CompositeEditorTableAction extends DockingAction implement
|
||||||
setHelpLocation(new HelpLocation(provider.getHelpTopic(), helpAnchor));
|
setHelpLocation(new HelpLocation(provider.getHelpTopic(), helpAnchor));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see ghidra.framework.plugintool.PluginAction#dispose()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
model.removeCompositeEditorModelListener(this);
|
model.removeCompositeEditorModelListener(this);
|
||||||
|
@ -93,64 +90,53 @@ abstract public class CompositeEditorTableAction extends DockingAction implement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
abstract public void adjustEnablement();
|
abstract public void adjustEnablement();
|
||||||
|
|
||||||
public String getHelpName() {
|
public String getHelpName() {
|
||||||
String actionName = getName();
|
String actionName = getName();
|
||||||
if (actionName.startsWith(CompositeEditorTableAction.EDIT_ACTION_PREFIX)) {
|
if (actionName.startsWith(CompositeEditorTableAction.EDIT_ACTION_PREFIX)) {
|
||||||
actionName = actionName.substring(CompositeEditorTableAction.EDIT_ACTION_PREFIX.length());
|
actionName =
|
||||||
|
actionName.substring(CompositeEditorTableAction.EDIT_ACTION_PREFIX.length());
|
||||||
}
|
}
|
||||||
return actionName;
|
return actionName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
@Override
|
||||||
* @see ghidra.app.plugin.stackeditor.EditorModelListener#selectionChanged()
|
|
||||||
*/
|
|
||||||
public void selectionChanged() {
|
public void selectionChanged() {
|
||||||
adjustEnablement();
|
adjustEnablement();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see ghidra.app.plugin.stackeditor.EditorModelListener#editStateChanged(int)
|
|
||||||
*/
|
|
||||||
public void editStateChanged(int i) {
|
public void editStateChanged(int i) {
|
||||||
adjustEnablement();
|
adjustEnablement();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
@Override
|
||||||
* @see ghidra.app.plugin.compositeeditor.CompositeEditorModelListener#compositeEditStateChanged(int)
|
|
||||||
*/
|
|
||||||
public void compositeEditStateChanged(int type) {
|
public void compositeEditStateChanged(int type) {
|
||||||
adjustEnablement();
|
adjustEnablement();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
@Override
|
||||||
* @see ghidra.app.plugin.compositeeditor.CompositeEditorModelListener#endFieldEditing()
|
|
||||||
*/
|
|
||||||
public void endFieldEditing() {
|
public void endFieldEditing() {
|
||||||
adjustEnablement();
|
adjustEnablement();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
@Override
|
||||||
* @see ghidra.app.plugin.compositeeditor.CompositeEditorModelListener#componentDataChanged()
|
|
||||||
*/
|
|
||||||
public void componentDataChanged() {
|
public void componentDataChanged() {
|
||||||
adjustEnablement();
|
adjustEnablement();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
@Override
|
||||||
* @see ghidra.app.plugin.compositeeditor.CompositeEditorModelListener#compositeInfoChanged()
|
|
||||||
*/
|
|
||||||
public void compositeInfoChanged() {
|
public void compositeInfoChanged() {
|
||||||
adjustEnablement();
|
adjustEnablement();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
@Override
|
||||||
* @see ghidra.app.plugin.compositeeditor.CompositeEditorModelListener#statusChanged(java.lang.String, boolean)
|
|
||||||
*/
|
|
||||||
public void statusChanged(String message, boolean beep) {
|
public void statusChanged(String message, boolean beep) {
|
||||||
|
// we are an action; don't care about status messages
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void showUndefinedStateChanged(boolean showUndefinedBytes) {
|
public void showUndefinedStateChanged(boolean showUndefinedBytes) {
|
||||||
adjustEnablement();
|
adjustEnablement();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import javax.swing.KeyStroke;
|
||||||
|
|
||||||
import docking.ActionContext;
|
import docking.ActionContext;
|
||||||
import docking.action.KeyBindingData;
|
import docking.action.KeyBindingData;
|
||||||
|
import docking.action.KeyBindingType;
|
||||||
import ghidra.program.model.data.CycleGroup;
|
import ghidra.program.model.data.CycleGroup;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,7 +33,7 @@ public class CycleGroupAction extends CompositeEditorTableAction {
|
||||||
public CycleGroupAction(CompositeEditorProvider provider, CycleGroup cycleGroup) {
|
public CycleGroupAction(CompositeEditorProvider provider, CycleGroup cycleGroup) {
|
||||||
super(provider, cycleGroup.getName(), GROUP_NAME,
|
super(provider, cycleGroup.getName(), GROUP_NAME,
|
||||||
new String[] { "Cycle", cycleGroup.getName() },
|
new String[] { "Cycle", cycleGroup.getName() },
|
||||||
new String[] { "Cycle", cycleGroup.getName() }, null);
|
new String[] { "Cycle", cycleGroup.getName() }, null, KeyBindingType.SHARED);
|
||||||
this.cycleGroup = cycleGroup;
|
this.cycleGroup = cycleGroup;
|
||||||
|
|
||||||
initKeyStroke(cycleGroup.getDefaultKeyStroke());
|
initKeyStroke(cycleGroup.getDefaultKeyStroke());
|
||||||
|
@ -46,11 +47,6 @@ public class CycleGroupAction extends CompositeEditorTableAction {
|
||||||
setKeyBindingData(new KeyBindingData(keyStroke));
|
setKeyBindingData(new KeyBindingData(keyStroke));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean usesSharedKeyBinding() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CycleGroup getCycleGroup() {
|
public CycleGroup getCycleGroup() {
|
||||||
return cycleGroup;
|
return cycleGroup;
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,11 +64,11 @@ public class ConsoleComponentProvider extends ComponentProviderAdapter
|
||||||
private PrintWriter stdin;
|
private PrintWriter stdin;
|
||||||
private Program currentProgram;
|
private Program currentProgram;
|
||||||
|
|
||||||
public ConsoleComponentProvider(PluginTool tool, String name) {
|
public ConsoleComponentProvider(PluginTool tool, String owner) {
|
||||||
super(tool, name, name);
|
super(tool, "Console", owner);
|
||||||
|
|
||||||
setDefaultWindowPosition(WindowPosition.BOTTOM);
|
setDefaultWindowPosition(WindowPosition.BOTTOM);
|
||||||
setHelpLocation(new HelpLocation(getName(), "console"));
|
setHelpLocation(new HelpLocation(owner, owner));
|
||||||
setIcon(ResourceManager.loadImage(CONSOLE_GIF));
|
setIcon(ResourceManager.loadImage(CONSOLE_GIF));
|
||||||
setWindowMenuGroup("Console");
|
setWindowMenuGroup("Console");
|
||||||
setSubTitle("Scripting");
|
setSubTitle("Scripting");
|
||||||
|
@ -94,7 +94,7 @@ public class ConsoleComponentProvider extends ComponentProviderAdapter
|
||||||
|
|
||||||
private void createOptions() {
|
private void createOptions() {
|
||||||
ToolOptions options = tool.getOptions("Console");
|
ToolOptions options = tool.getOptions("Console");
|
||||||
HelpLocation help = new HelpLocation(getName(), "ConsolePlugin");
|
HelpLocation help = new HelpLocation(getOwner(), getOwner());
|
||||||
options.registerOption(FONT_OPTION_LABEL, DEFAULT_FONT, help, FONT_DESCRIPTION);
|
options.registerOption(FONT_OPTION_LABEL, DEFAULT_FONT, help, FONT_DESCRIPTION);
|
||||||
options.setOptionsHelpLocation(help);
|
options.setOptionsHelpLocation(help);
|
||||||
font = options.getFont(FONT_OPTION_LABEL, DEFAULT_FONT);
|
font = options.getFont(FONT_OPTION_LABEL, DEFAULT_FONT);
|
||||||
|
@ -260,7 +260,7 @@ public class ConsoleComponentProvider extends ComponentProviderAdapter
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createActions() {
|
private void createActions() {
|
||||||
clearAction = new DockingAction("Clear Console", getName()) {
|
clearAction = new DockingAction("Clear Console", getOwner()) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionContext context) {
|
public void actionPerformed(ActionContext context) {
|
||||||
|
@ -273,7 +273,7 @@ public class ConsoleComponentProvider extends ComponentProviderAdapter
|
||||||
|
|
||||||
clearAction.setEnabled(true);
|
clearAction.setEnabled(true);
|
||||||
|
|
||||||
scrollAction = new ToggleDockingAction("Scroll Lock", getName()) {
|
scrollAction = new ToggleDockingAction("Scroll Lock", getOwner()) {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionContext context) {
|
public void actionPerformed(ActionContext context) {
|
||||||
textPane.setScrollLock(isSelected());
|
textPane.setScrollLock(isSelected());
|
||||||
|
|
|
@ -20,8 +20,7 @@ import java.awt.event.KeyEvent;
|
||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
|
|
||||||
import docking.ActionContext;
|
import docking.ActionContext;
|
||||||
import docking.action.DockingAction;
|
import docking.action.*;
|
||||||
import docking.action.KeyBindingData;
|
|
||||||
import ghidra.app.context.ListingActionContext;
|
import ghidra.app.context.ListingActionContext;
|
||||||
import ghidra.app.util.datatype.DataTypeSelectionDialog;
|
import ghidra.app.util.datatype.DataTypeSelectionDialog;
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
|
@ -43,7 +42,7 @@ public class ChooseDataTypeAction extends DockingAction {
|
||||||
private final static String ACTION_NAME = "Choose Data Type";
|
private final static String ACTION_NAME = "Choose Data Type";
|
||||||
|
|
||||||
public ChooseDataTypeAction(DataPlugin plugin) {
|
public ChooseDataTypeAction(DataPlugin plugin) {
|
||||||
super(ACTION_NAME, plugin.getName(), false);
|
super(ACTION_NAME, plugin.getName(), KeyBindingType.SHARED);
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
|
|
||||||
initKeyStroke(KEY_BINDING);
|
initKeyStroke(KEY_BINDING);
|
||||||
|
@ -57,11 +56,6 @@ public class ChooseDataTypeAction extends DockingAction {
|
||||||
setKeyBindingData(new KeyBindingData(keyStroke));
|
setKeyBindingData(new KeyBindingData(keyStroke));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean usesSharedKeyBinding() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionContext context) {
|
public void actionPerformed(ActionContext context) {
|
||||||
ListingActionContext programActionContext =
|
ListingActionContext programActionContext =
|
||||||
|
|
|
@ -44,7 +44,7 @@ class CreateArrayAction extends DockingAction {
|
||||||
private DataPlugin plugin;
|
private DataPlugin plugin;
|
||||||
|
|
||||||
public CreateArrayAction(DataPlugin plugin) {
|
public CreateArrayAction(DataPlugin plugin) {
|
||||||
super("Define Array", plugin.getName(), false);
|
super("Define Array", plugin.getName(), KeyBindingType.SHARED);
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
|
|
||||||
setPopupMenuData(new MenuData(CREATE_ARRAY_POPUP_MENU, "BasicData"));
|
setPopupMenuData(new MenuData(CREATE_ARRAY_POPUP_MENU, "BasicData"));
|
||||||
|
@ -61,11 +61,6 @@ class CreateArrayAction extends DockingAction {
|
||||||
setKeyBindingData(new KeyBindingData(keyStroke));
|
setKeyBindingData(new KeyBindingData(keyStroke));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean usesSharedKeyBinding() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionContext context) {
|
public void actionPerformed(ActionContext context) {
|
||||||
ListingActionContext programActionContext =
|
ListingActionContext programActionContext =
|
||||||
|
|
|
@ -18,8 +18,7 @@ package ghidra.app.plugin.core.data;
|
||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
|
|
||||||
import docking.ActionContext;
|
import docking.ActionContext;
|
||||||
import docking.action.DockingAction;
|
import docking.action.*;
|
||||||
import docking.action.KeyBindingData;
|
|
||||||
import ghidra.app.cmd.data.*;
|
import ghidra.app.cmd.data.*;
|
||||||
import ghidra.app.context.ListingActionContext;
|
import ghidra.app.context.ListingActionContext;
|
||||||
import ghidra.framework.cmd.BackgroundCommand;
|
import ghidra.framework.cmd.BackgroundCommand;
|
||||||
|
@ -41,7 +40,7 @@ public class CycleGroupAction extends DockingAction {
|
||||||
private CycleGroup cycleGroup;
|
private CycleGroup cycleGroup;
|
||||||
|
|
||||||
CycleGroupAction(CycleGroup group, DataPlugin plugin) {
|
CycleGroupAction(CycleGroup group, DataPlugin plugin) {
|
||||||
super(group.getName(), plugin.getName(), false);
|
super(group.getName(), plugin.getName(), KeyBindingType.SHARED);
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.cycleGroup = group;
|
this.cycleGroup = group;
|
||||||
|
|
||||||
|
@ -56,11 +55,6 @@ public class CycleGroupAction extends DockingAction {
|
||||||
setKeyBindingData(new KeyBindingData(keyStroke));
|
setKeyBindingData(new KeyBindingData(keyStroke));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean usesSharedKeyBinding() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
cycleGroup = null;
|
cycleGroup = null;
|
||||||
|
|
|
@ -17,8 +17,7 @@ package ghidra.app.plugin.core.data;
|
||||||
|
|
||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
|
|
||||||
import docking.action.KeyBindingData;
|
import docking.action.*;
|
||||||
import docking.action.MenuData;
|
|
||||||
import ghidra.app.context.ListingActionContext;
|
import ghidra.app.context.ListingActionContext;
|
||||||
import ghidra.app.context.ListingContextAction;
|
import ghidra.app.context.ListingContextAction;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.*;
|
||||||
|
@ -45,7 +44,7 @@ class DataAction extends ListingContextAction {
|
||||||
* @param plugin the plugin that owns this action
|
* @param plugin the plugin that owns this action
|
||||||
*/
|
*/
|
||||||
public DataAction(String name, String group, DataType dataType, DataPlugin plugin) {
|
public DataAction(String name, String group, DataType dataType, DataPlugin plugin) {
|
||||||
super(name, plugin.getName(), false);
|
super(name, plugin.getName(), KeyBindingType.SHARED);
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.dataType = dataType;
|
this.dataType = dataType;
|
||||||
|
|
||||||
|
@ -54,11 +53,6 @@ class DataAction extends ListingContextAction {
|
||||||
initKeyStroke(getDefaultKeyStroke());
|
initKeyStroke(getDefaultKeyStroke());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean usesSharedKeyBinding() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected KeyStroke getDefaultKeyStroke() {
|
protected KeyStroke getDefaultKeyStroke() {
|
||||||
return null; // we have no default, but our subclasses may
|
return null; // we have no default, but our subclasses may
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import javax.swing.ImageIcon;
|
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.tree.TreePath;
|
import javax.swing.tree.TreePath;
|
||||||
|
|
||||||
|
@ -60,7 +59,6 @@ import ghidra.util.HelpLocation;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.datastruct.LRUMap;
|
import ghidra.util.datastruct.LRUMap;
|
||||||
import ghidra.util.task.TaskLauncher;
|
import ghidra.util.task.TaskLauncher;
|
||||||
import resources.ResourceManager;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plugin to pop up the dialog to manage data types in the program
|
* Plugin to pop up the dialog to manage data types in the program
|
||||||
|
@ -82,14 +80,12 @@ import resources.ResourceManager;
|
||||||
public class DataTypeManagerPlugin extends ProgramPlugin
|
public class DataTypeManagerPlugin extends ProgramPlugin
|
||||||
implements DomainObjectListener, DataTypeManagerService, PopupListener {
|
implements DomainObjectListener, DataTypeManagerService, PopupListener {
|
||||||
|
|
||||||
final static String DATA_TYPES_ICON = "images/dataTypes.png";
|
|
||||||
private static final String SEACH_PROVIDER_NAME = "Search DataTypes Provider";
|
private static final String SEACH_PROVIDER_NAME = "Search DataTypes Provider";
|
||||||
private static final int RECENTLY_USED_CACHE_SIZE = 10;
|
private static final int RECENTLY_USED_CACHE_SIZE = 10;
|
||||||
|
|
||||||
private static final String STANDARD_ARCHIVE_MENU = "Standard Archive";
|
private static final String STANDARD_ARCHIVE_MENU = "Standard Archive";
|
||||||
private static final String RECENTLY_OPENED_MENU = "Recently Opened Archive";
|
private static final String RECENTLY_OPENED_MENU = "Recently Opened Archive";
|
||||||
|
|
||||||
private DockingAction manageDataAction;
|
|
||||||
private DataTypeManagerHandler dataTypeManagerHandler;
|
private DataTypeManagerHandler dataTypeManagerHandler;
|
||||||
private DataTypesProvider provider;
|
private DataTypesProvider provider;
|
||||||
private OpenVersionedFileDialog openDialog;
|
private OpenVersionedFileDialog openDialog;
|
||||||
|
@ -126,12 +122,10 @@ public class DataTypeManagerPlugin extends ProgramPlugin
|
||||||
@Override
|
@Override
|
||||||
public void archiveClosed(Archive archive) {
|
public void archiveClosed(Archive archive) {
|
||||||
if (archive instanceof ProjectArchive) {
|
if (archive instanceof ProjectArchive) {
|
||||||
|
// Program is handled by deactivation event
|
||||||
((ProjectArchive) archive).getDomainObject().removeListener(
|
((ProjectArchive) archive).getDomainObject().removeListener(
|
||||||
DataTypeManagerPlugin.this);
|
DataTypeManagerPlugin.this);
|
||||||
}
|
}
|
||||||
// Program is handled by deactivation.
|
|
||||||
|
|
||||||
// Otherwise, don't care.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -467,21 +461,6 @@ public class DataTypeManagerPlugin extends ProgramPlugin
|
||||||
* Create the actions for the menu on the tool.
|
* Create the actions for the menu on the tool.
|
||||||
*/
|
*/
|
||||||
private void createActions() {
|
private void createActions() {
|
||||||
// create action
|
|
||||||
manageDataAction = new DockingAction("Data Type Manager", getName()) {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionContext context) {
|
|
||||||
tool.showComponentProvider(provider, true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ImageIcon dtIcon = ResourceManager.loadImage(DATA_TYPES_ICON);
|
|
||||||
manageDataAction.setToolBarData(new ToolBarData(dtIcon, "View"));
|
|
||||||
|
|
||||||
manageDataAction.setDescription("Display Data Types");
|
|
||||||
manageDataAction.setHelpLocation(provider.getHelpLocation());
|
|
||||||
|
|
||||||
tool.addAction(manageDataAction);
|
|
||||||
|
|
||||||
createStandardArchivesMenu();
|
createStandardArchivesMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,8 @@ import resources.ResourceManager;
|
||||||
import util.HistoryList;
|
import util.HistoryList;
|
||||||
|
|
||||||
public class DataTypesProvider extends ComponentProviderAdapter {
|
public class DataTypesProvider extends ComponentProviderAdapter {
|
||||||
|
|
||||||
|
private static final String DATA_TYPES_ICON = "images/dataTypes.png";
|
||||||
private static final String TITLE = "Data Type Manager";
|
private static final String TITLE = "Data Type Manager";
|
||||||
private static final String POINTER_FILTER_STATE = "PointerFilterState";
|
private static final String POINTER_FILTER_STATE = "PointerFilterState";
|
||||||
private static final String ARRAY_FILTER_STATE = "ArrayFilterState";
|
private static final String ARRAY_FILTER_STATE = "ArrayFilterState";
|
||||||
|
@ -95,9 +97,12 @@ public class DataTypesProvider extends ComponentProviderAdapter {
|
||||||
|
|
||||||
public DataTypesProvider(DataTypeManagerPlugin plugin, String providerName) {
|
public DataTypesProvider(DataTypeManagerPlugin plugin, String providerName) {
|
||||||
super(plugin.getTool(), providerName, plugin.getName(), DataTypesActionContext.class);
|
super(plugin.getTool(), providerName, plugin.getName(), DataTypesActionContext.class);
|
||||||
setTitle(TITLE);
|
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
|
|
||||||
|
setTitle(TITLE);
|
||||||
|
setIcon(ResourceManager.loadImage(DATA_TYPES_ICON));
|
||||||
|
addToToolbar();
|
||||||
|
|
||||||
navigationHistory.setAllowDuplicates(true);
|
navigationHistory.setAllowDuplicates(true);
|
||||||
|
|
||||||
buildComponent();
|
buildComponent();
|
||||||
|
@ -106,11 +111,6 @@ public class DataTypesProvider extends ComponentProviderAdapter {
|
||||||
createLocalActions();
|
createLocalActions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ImageIcon getIcon() {
|
|
||||||
return ResourceManager.loadImage(DataTypeManagerPlugin.DATA_TYPES_ICON);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This creates all the actions for opening/creating data type archives.
|
* This creates all the actions for opening/creating data type archives.
|
||||||
* It also creates the action for refreshing the built-in data types
|
* It also creates the action for refreshing the built-in data types
|
||||||
|
|
|
@ -123,7 +123,7 @@ class NextPreviousDataTypeAction extends MultiActionDockingAction {
|
||||||
private class NavigationAction extends DockingAction {
|
private class NavigationAction extends DockingAction {
|
||||||
|
|
||||||
private NavigationAction(DataType dt) {
|
private NavigationAction(DataType dt) {
|
||||||
super("DataTypeNavigationAction_" + ++navigationActionIdCount, owner, false);
|
super("DataTypeNavigationAction_" + ++navigationActionIdCount, owner);
|
||||||
|
|
||||||
setMenuBarData(new MenuData(new String[] { dt.getDisplayName() }));
|
setMenuBarData(new MenuData(new String[] { dt.getDisplayName() }));
|
||||||
setEnabled(true);
|
setEnabled(true);
|
||||||
|
|
|
@ -18,7 +18,6 @@ package ghidra.app.plugin.core.datawindow;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
import docking.ActionContext;
|
|
||||||
import docking.action.DockingAction;
|
import docking.action.DockingAction;
|
||||||
import ghidra.app.CorePluginPackage;
|
import ghidra.app.CorePluginPackage;
|
||||||
import ghidra.app.events.ProgramSelectionPluginEvent;
|
import ghidra.app.events.ProgramSelectionPluginEvent;
|
||||||
|
@ -180,13 +179,7 @@ public class DataWindowPlugin extends ProgramPlugin implements DomainObjectListe
|
||||||
*/
|
*/
|
||||||
private void createActions() {
|
private void createActions() {
|
||||||
|
|
||||||
selectAction = new MakeProgramSelectionAction(getName(), provider.getTable()) {
|
selectAction = new MakeProgramSelectionAction(this, provider.getTable());
|
||||||
@Override
|
|
||||||
protected void makeSelection(ActionContext context) {
|
|
||||||
selectData(provider.selectData());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
tool.addLocalAction(provider, selectAction);
|
tool.addLocalAction(provider, selectAction);
|
||||||
|
|
||||||
filterAction = new FilterAction(this);
|
filterAction = new FilterAction(this);
|
||||||
|
|
|
@ -23,6 +23,8 @@ import java.util.Map.Entry;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import docking.*;
|
import docking.*;
|
||||||
import docking.action.ToggleDockingAction;
|
import docking.action.ToggleDockingAction;
|
||||||
import docking.action.ToolBarData;
|
import docking.action.ToolBarData;
|
||||||
|
@ -34,7 +36,6 @@ import docking.widgets.filter.FilterTextField;
|
||||||
import docking.widgets.label.GLabel;
|
import docking.widgets.label.GLabel;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
import ghidra.util.StringUtilities;
|
|
||||||
import ghidra.util.task.SwingUpdateManager;
|
import ghidra.util.task.SwingUpdateManager;
|
||||||
import resources.Icons;
|
import resources.Icons;
|
||||||
|
|
||||||
|
@ -351,7 +352,7 @@ class FilterAction extends ToggleDockingAction {
|
||||||
String curType = itr.next();
|
String curType = itr.next();
|
||||||
Boolean lEnabled = typeEnabledMap.get(curType);
|
Boolean lEnabled = typeEnabledMap.get(curType);
|
||||||
StringBuffer buildMetaCurTypeBuff = new StringBuffer(curType);
|
StringBuffer buildMetaCurTypeBuff = new StringBuffer(curType);
|
||||||
int firstIndex = StringUtilities.indexOfIgnoreCase(curType, filteredText, 0);
|
int firstIndex = StringUtils.indexOfIgnoreCase(curType, filteredText, 0);
|
||||||
int lastIndex = firstIndex + filteredText.length();
|
int lastIndex = firstIndex + filteredText.length();
|
||||||
buildMetaCurTypeBuff.insert(lastIndex, "</b>");//THIS MUST ALWAYS COME BEFORE FIRST INDEX (FOR NO MATH on INDEX)
|
buildMetaCurTypeBuff.insert(lastIndex, "</b>");//THIS MUST ALWAYS COME BEFORE FIRST INDEX (FOR NO MATH on INDEX)
|
||||||
buildMetaCurTypeBuff.insert(firstIndex, "<b>");
|
buildMetaCurTypeBuff.insert(firstIndex, "<b>");
|
||||||
|
@ -409,7 +410,7 @@ class FilterAction extends ToggleDockingAction {
|
||||||
while (iteratorIndex.hasNext()) {
|
while (iteratorIndex.hasNext()) {
|
||||||
Entry<String, Boolean> entry = iteratorIndex.next();
|
Entry<String, Boolean> entry = iteratorIndex.next();
|
||||||
String checkboxName = entry.getKey();
|
String checkboxName = entry.getKey();
|
||||||
if (StringUtilities.containsIgnoreCase(checkboxName, filteredText)) {
|
if (StringUtils.containsIgnoreCase(checkboxName, filteredText)) {
|
||||||
checkboxNameList.add(checkboxName);
|
checkboxNameList.add(checkboxName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ import javax.swing.event.DocumentListener;
|
||||||
|
|
||||||
import docking.ActionContext;
|
import docking.ActionContext;
|
||||||
import docking.DialogComponentProvider;
|
import docking.DialogComponentProvider;
|
||||||
import docking.action.*;
|
import docking.action.DockingAction;
|
||||||
import docking.widgets.checkbox.GCheckBox;
|
import docking.widgets.checkbox.GCheckBox;
|
||||||
import docking.widgets.label.GDLabel;
|
import docking.widgets.label.GDLabel;
|
||||||
import docking.widgets.label.GLabel;
|
import docking.widgets.label.GLabel;
|
||||||
|
@ -40,11 +40,13 @@ import ghidra.program.model.mem.MemoryBlock;
|
||||||
import ghidra.program.util.ProgramSelection;
|
import ghidra.program.util.ProgramSelection;
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
import ghidra.util.table.*;
|
import ghidra.util.table.*;
|
||||||
|
import ghidra.util.table.actions.MakeProgramSelectionAction;
|
||||||
import ghidra.util.task.Task;
|
import ghidra.util.task.Task;
|
||||||
import resources.ResourceManager;
|
|
||||||
|
|
||||||
public class AddressTableDialog extends DialogComponentProvider {
|
public class AddressTableDialog extends DialogComponentProvider {
|
||||||
static final int DEFAULT_MINIMUM_TABLE_SIZE = 3;
|
private static final int DEFAULT_MINIMUM_TABLE_SIZE = 3;
|
||||||
|
private static final String DIALOG_NAME = "Search For Address Tables";
|
||||||
|
|
||||||
private JPanel mainPanel;
|
private JPanel mainPanel;
|
||||||
private String[] blockData;
|
private String[] blockData;
|
||||||
private AutoTableDisassemblerPlugin plugin;
|
private AutoTableDisassemblerPlugin plugin;
|
||||||
|
@ -67,7 +69,7 @@ public class AddressTableDialog extends DialogComponentProvider {
|
||||||
private GhidraThreadedTablePanel<AddressTable> resultsTablePanel;
|
private GhidraThreadedTablePanel<AddressTable> resultsTablePanel;
|
||||||
|
|
||||||
public AddressTableDialog(AutoTableDisassemblerPlugin plugin) {
|
public AddressTableDialog(AutoTableDisassemblerPlugin plugin) {
|
||||||
super("Search For Address Tables", false, true, true, true);
|
super(DIALOG_NAME, false, true, true, true);
|
||||||
setHelpLocation(
|
setHelpLocation(
|
||||||
new HelpLocation(HelpTopics.SEARCH, AutoTableDisassemblerPlugin.SEARCH_ACTION_NAME));
|
new HelpLocation(HelpTopics.SEARCH, AutoTableDisassemblerPlugin.SEARCH_ACTION_NAME));
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
|
@ -125,8 +127,7 @@ public class AddressTableDialog extends DialogComponentProvider {
|
||||||
JPanel makeTablePanel = new JPanel(new FlowLayout());
|
JPanel makeTablePanel = new JPanel(new FlowLayout());
|
||||||
|
|
||||||
makeTableButton = new JButton("Make Table");
|
makeTableButton = new JButton("Make Table");
|
||||||
makeTableButton.setToolTipText(
|
makeTableButton.setToolTipText("Make a table of addresses at the selected location(s).");
|
||||||
"Make a table of addresses at the selected location(s).");
|
|
||||||
makeTablePanel.add(makeTableButton);
|
makeTablePanel.add(makeTableButton);
|
||||||
makeTableButton.setEnabled(false);
|
makeTableButton.setEnabled(false);
|
||||||
makeTableButton.addActionListener(e -> plugin.makeTable(resultsTable.getSelectedRows()));
|
makeTableButton.addActionListener(e -> plugin.makeTable(resultsTable.getSelectedRows()));
|
||||||
|
@ -175,8 +176,7 @@ public class AddressTableDialog extends DialogComponentProvider {
|
||||||
skipLabel = new GDLabel("Skip Length: ");
|
skipLabel = new GDLabel("Skip Length: ");
|
||||||
skipField = new JTextField(5);
|
skipField = new JTextField(5);
|
||||||
skipField.setName("Skip");
|
skipField.setName("Skip");
|
||||||
skipLabel.setToolTipText(
|
skipLabel.setToolTipText("Number of bytes to skip between found addresses in a table.");
|
||||||
"Number of bytes to skip between found addresses in a table.");
|
|
||||||
skipField.setText("0");
|
skipField.setText("0");
|
||||||
|
|
||||||
JPanel alignPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
|
JPanel alignPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
|
||||||
|
@ -194,8 +194,7 @@ public class AddressTableDialog extends DialogComponentProvider {
|
||||||
|
|
||||||
selectionButton = new GCheckBox("Search Selection");
|
selectionButton = new GCheckBox("Search Selection");
|
||||||
selectionButton.setSelected(false);
|
selectionButton.setSelected(false);
|
||||||
selectionButton.setToolTipText(
|
selectionButton.setToolTipText("If checked, search only the current selection.");
|
||||||
"If checked, search only the current selection.");
|
|
||||||
JPanel searchOptionsWestPanel = new JPanel(new GridLayout(2, 1));
|
JPanel searchOptionsWestPanel = new JPanel(new GridLayout(2, 1));
|
||||||
searchOptionsWestPanel.add(selectionButton);
|
searchOptionsWestPanel.add(selectionButton);
|
||||||
|
|
||||||
|
@ -233,8 +232,7 @@ public class AddressTableDialog extends DialogComponentProvider {
|
||||||
"Label the top of the address table and all members of the table.");
|
"Label the top of the address table and all members of the table.");
|
||||||
|
|
||||||
offsetLabel = new GDLabel("Offset: ");
|
offsetLabel = new GDLabel("Offset: ");
|
||||||
offsetLabel.setToolTipText(
|
offsetLabel.setToolTipText("Offset from the beginning of the selected table(s)");
|
||||||
"Offset from the beginning of the selected table(s)");
|
|
||||||
offsetLabel.setEnabled(false);
|
offsetLabel.setEnabled(false);
|
||||||
|
|
||||||
JLabel viewOffsetLabel = new GDLabel(" ");
|
JLabel viewOffsetLabel = new GDLabel(" ");
|
||||||
|
@ -242,8 +240,7 @@ public class AddressTableDialog extends DialogComponentProvider {
|
||||||
|
|
||||||
viewOffset = new HintTextField(20);
|
viewOffset = new HintTextField(20);
|
||||||
viewOffset.setName("viewOffset");
|
viewOffset.setName("viewOffset");
|
||||||
viewOffset.setToolTipText(
|
viewOffset.setToolTipText("Address of the selected table starting at the given offset");
|
||||||
"Address of the selected table starting at the given offset");
|
|
||||||
viewOffset.setHintText("table start address");
|
viewOffset.setHintText("table start address");
|
||||||
viewOffset.showHint();
|
viewOffset.showHint();
|
||||||
|
|
||||||
|
@ -526,20 +523,31 @@ public class AddressTableDialog extends DialogComponentProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createAction() {
|
private void createAction() {
|
||||||
DockingAction selectAction =
|
|
||||||
new DockingAction("Make Selection", "AsciiFinderDialog", false) {
|
DockingAction selectAction = new MakeProgramSelectionAction(plugin, resultsTable) {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionContext context) {
|
protected ProgramSelection makeSelection(ActionContext context) {
|
||||||
makeSelection();
|
Program program = plugin.getProgram();
|
||||||
|
AddressSet set = new AddressSet();
|
||||||
|
AutoTableDisassemblerModel model = plugin.getModel();
|
||||||
|
int[] selectedRows = resultsTable.getSelectedRows();
|
||||||
|
for (int selectedRow : selectedRows) {
|
||||||
|
Address selectedAddress = model.getAddress(selectedRow);
|
||||||
|
AddressTable addrTab = model.get(selectedAddress);
|
||||||
|
if (addrTab != null) {
|
||||||
|
set.addRange(selectedAddress,
|
||||||
|
selectedAddress.add(addrTab.getByteLength() - 1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
ProgramSelection selection = new ProgramSelection(set);
|
||||||
selectAction.setDescription("Make a selection using selected rows");
|
if (!set.isEmpty()) {
|
||||||
selectAction.setEnabled(true);
|
plugin.firePluginEvent(
|
||||||
Icon icon = ResourceManager.loadImage("images/text_align_justify.png");
|
new ProgramSelectionPluginEvent(plugin.getName(), selection, program));
|
||||||
selectAction.setPopupMenuData(new MenuData(new String[] { "Make Selection" }, icon));
|
}
|
||||||
selectAction.setToolBarData(new ToolBarData(icon));
|
|
||||||
selectAction.setHelpLocation(
|
return selection;
|
||||||
new HelpLocation(HelpTopics.SEARCH, "Search_Make_Selection_Address_Tables"));
|
}
|
||||||
|
};
|
||||||
|
|
||||||
selectionNavigationAction = new SelectionNavigationAction(plugin, resultsTable);
|
selectionNavigationAction = new SelectionNavigationAction(plugin, resultsTable);
|
||||||
selectionNavigationAction.setHelpLocation(
|
selectionNavigationAction.setHelpLocation(
|
||||||
|
@ -548,7 +556,7 @@ public class AddressTableDialog extends DialogComponentProvider {
|
||||||
addAction(selectAction);
|
addAction(selectAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void makeSelection() {
|
private void doMakeSelection() {
|
||||||
Program program = plugin.getProgram();
|
Program program = plugin.getProgram();
|
||||||
AddressSet set = new AddressSet();
|
AddressSet set = new AddressSet();
|
||||||
AutoTableDisassemblerModel model = plugin.getModel();
|
AutoTableDisassemblerModel model = plugin.getModel();
|
||||||
|
|
|
@ -140,15 +140,19 @@ public class AutoTableDisassemblerPlugin extends ProgramPlugin implements Domain
|
||||||
public void actionPerformed(ActionContext context) {
|
public void actionPerformed(ActionContext context) {
|
||||||
startDialog();
|
startDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabledForContext(ActionContext context) {
|
||||||
|
return currentProgram != null;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
findTableAction.setHelpLocation(
|
findTableAction.setHelpLocation(
|
||||||
new HelpLocation(HelpTopics.SEARCH, findTableAction.getName()));
|
new HelpLocation(HelpTopics.SEARCH, findTableAction.getName()));
|
||||||
findTableAction.setMenuBarData(
|
findTableAction.setMenuBarData(
|
||||||
new MenuData(new String[] { ToolConstants.MENU_SEARCH, "For Address Tables..." }, null,
|
new MenuData(new String[] { ToolConstants.MENU_SEARCH, "For Address Tables..." }, null,
|
||||||
"search for"));
|
"search for"));
|
||||||
|
|
||||||
findTableAction.setDescription(getPluginDescription().getDescription());
|
findTableAction.setDescription(getPluginDescription().getDescription());
|
||||||
enableOnLocation(findTableAction);
|
|
||||||
tool.addAction(findTableAction);
|
tool.addAction(findTableAction);
|
||||||
|
|
||||||
} // end of createActions()
|
} // end of createActions()
|
||||||
|
|
|
@ -54,12 +54,7 @@ public class EquateTablePlugin extends ProgramPlugin implements DomainObjectList
|
||||||
public EquateTablePlugin(PluginTool tool) {
|
public EquateTablePlugin(PluginTool tool) {
|
||||||
super(tool, true, false);
|
super(tool, true, false);
|
||||||
|
|
||||||
updateMgr = new SwingUpdateManager(1000, 3000, new Runnable() {
|
updateMgr = new SwingUpdateManager(1000, 3000, () -> provider.updateEquates());
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
provider.updateEquates();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
provider = new EquateTableProvider(this);
|
provider = new EquateTableProvider(this);
|
||||||
}
|
}
|
||||||
|
@ -131,10 +126,10 @@ public class EquateTablePlugin extends ProgramPlugin implements DomainObjectList
|
||||||
|
|
||||||
ev.containsEvent(ChangeManager.DOCR_CODE_ADDED) ||
|
ev.containsEvent(ChangeManager.DOCR_CODE_ADDED) ||
|
||||||
ev.containsEvent(ChangeManager.DOCR_CODE_MOVED) ||
|
ev.containsEvent(ChangeManager.DOCR_CODE_MOVED) ||
|
||||||
ev.containsEvent(ChangeManager.DOCR_CODE_REMOVED) ||
|
ev.containsEvent(ChangeManager.DOCR_CODE_REMOVED) ||
|
||||||
|
|
||||||
ev.containsEvent(ChangeManager.DOCR_DATA_TYPE_CHANGED)) {
|
ev.containsEvent(ChangeManager.DOCR_DATA_TYPE_CHANGED)) {
|
||||||
|
|
||||||
updateMgr.update();
|
updateMgr.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,9 +149,6 @@ public class EquateTablePlugin extends ProgramPlugin implements DomainObjectList
|
||||||
provider.programClosed();
|
provider.programClosed();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete the list of equates.
|
|
||||||
*/
|
|
||||||
void deleteEquates(List<Equate> equates) {
|
void deleteEquates(List<Equate> equates) {
|
||||||
if (equates.isEmpty()) {
|
if (equates.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
|
@ -173,13 +165,11 @@ public class EquateTablePlugin extends ProgramPlugin implements DomainObjectList
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String title = "Delete Equate" + (equates.size() > 1 ? "s" : "") + "?";
|
String title = "Delete Equate" + (equates.size() > 1 ? "s" : "") + "?";
|
||||||
String msg =
|
String msg = "Do you really want to delete the equate" + (equates.size() > 1 ? "s" : "") +
|
||||||
"Do you really want to delete the equate" + (equates.size() > 1 ? "s" : "") + ": " +
|
": " + equates + " ?" + "\n\n NOTE: All references will be removed.";
|
||||||
equates + " ?" + "\n\n NOTE: All references will be removed.";
|
|
||||||
|
|
||||||
int option =
|
int option = OptionDialog.showOptionDialog(provider.getComponent(), title, msg, "Delete",
|
||||||
OptionDialog.showOptionDialog(provider.getComponent(), title, msg, "Delete",
|
OptionDialog.QUESTION_MESSAGE);
|
||||||
OptionDialog.QUESTION_MESSAGE);
|
|
||||||
|
|
||||||
if (option != OptionDialog.CANCEL_OPTION) {
|
if (option != OptionDialog.CANCEL_OPTION) {
|
||||||
tool.execute(new RemoveEquateCmd(equateNames, getTool()), currentProgram);
|
tool.execute(new RemoveEquateCmd(equateNames, getTool()), currentProgram);
|
||||||
|
@ -236,26 +226,24 @@ public class EquateTablePlugin extends ProgramPlugin implements DomainObjectList
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the equate exists, checks to make sure the value matches the
|
* If the equate exists, checks to make sure the value matches the current scalar value
|
||||||
* current scalar value.
|
|
||||||
*
|
*
|
||||||
* @param dialog the dialog whose status area should be set with any error messages.
|
* @param equate the equate to check
|
||||||
* @param equateStr the candidate equate name for the set or rename operation.
|
* @param equateStr the candidate equate name for the set or rename operation
|
||||||
|
* @return true if valid
|
||||||
*/
|
*/
|
||||||
boolean isValid(Equate equate, String equateStr) {
|
boolean isValid(Equate equate, String equateStr) {
|
||||||
// these are valid in the sense that they represent a clear or remove operation.
|
// these are valid in the sense that they represent a clear or remove operation
|
||||||
if (equateStr == null || equateStr.length() <= 0) {
|
if (equateStr == null || equateStr.length() <= 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// look up the new equate string
|
|
||||||
EquateTable equateTable = currentProgram.getEquateTable();
|
EquateTable equateTable = currentProgram.getEquateTable();
|
||||||
Equate newEquate = equateTable.getEquate(equateStr);
|
Equate newEquate = equateTable.getEquate(equateStr);
|
||||||
|
|
||||||
if (newEquate != null && !newEquate.equals(equate)) {
|
if (newEquate != null && !newEquate.equals(equate)) {
|
||||||
Msg.showInfo(getClass(), provider.getComponent(), "Rename Equate Failed!", "Equate " +
|
Msg.showInfo(getClass(), provider.getComponent(), "Rename Equate Failed!",
|
||||||
equateStr + " exists with value 0x" + Long.toHexString(newEquate.getValue()) +
|
"Equate " + equateStr + " exists with value 0x" +
|
||||||
" (" + newEquate.getValue() + ")");
|
Long.toHexString(newEquate.getValue()) + " (" + newEquate.getValue() + ")");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -41,7 +41,7 @@ public class ChooseDataTypeAction extends DockingAction {
|
||||||
private FunctionPlugin plugin;
|
private FunctionPlugin plugin;
|
||||||
|
|
||||||
public ChooseDataTypeAction(FunctionPlugin plugin) {
|
public ChooseDataTypeAction(FunctionPlugin plugin) {
|
||||||
super(ACTION_NAME, plugin.getName(), false);
|
super(ACTION_NAME, plugin.getName(), KeyBindingType.SHARED);
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
|
|
||||||
setHelpLocation(new HelpLocation("DataTypeEditors", "DataTypeSelectionDialog"));
|
setHelpLocation(new HelpLocation("DataTypeEditors", "DataTypeSelectionDialog"));
|
||||||
|
@ -57,11 +57,6 @@ public class ChooseDataTypeAction extends DockingAction {
|
||||||
setKeyBindingData(new KeyBindingData(keyStroke));
|
setKeyBindingData(new KeyBindingData(keyStroke));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean usesSharedKeyBinding() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionContext actionContext) {
|
public void actionPerformed(ActionContext actionContext) {
|
||||||
ListingActionContext context = (ListingActionContext) actionContext.getContextObject();
|
ListingActionContext context = (ListingActionContext) actionContext.getContextObject();
|
||||||
|
|
|
@ -19,8 +19,7 @@ import java.awt.event.KeyEvent;
|
||||||
|
|
||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
|
|
||||||
import docking.action.KeyBindingData;
|
import docking.action.*;
|
||||||
import docking.action.MenuData;
|
|
||||||
import docking.widgets.dialogs.NumberInputDialog;
|
import docking.widgets.dialogs.NumberInputDialog;
|
||||||
import ghidra.app.context.ListingActionContext;
|
import ghidra.app.context.ListingActionContext;
|
||||||
import ghidra.app.context.ListingContextAction;
|
import ghidra.app.context.ListingContextAction;
|
||||||
|
@ -37,7 +36,7 @@ class CreateArrayAction extends ListingContextAction {
|
||||||
private FunctionPlugin plugin;
|
private FunctionPlugin plugin;
|
||||||
|
|
||||||
public CreateArrayAction(FunctionPlugin plugin) {
|
public CreateArrayAction(FunctionPlugin plugin) {
|
||||||
super("Define Array", plugin.getName(), false);
|
super("Define Array", plugin.getName(), KeyBindingType.SHARED);
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
|
|
||||||
setPopupMenu(plugin.getDataActionMenuName(null));
|
setPopupMenu(plugin.getDataActionMenuName(null));
|
||||||
|
@ -54,11 +53,6 @@ class CreateArrayAction extends ListingContextAction {
|
||||||
setKeyBindingData(new KeyBindingData(keyStroke));
|
setKeyBindingData(new KeyBindingData(keyStroke));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean usesSharedKeyBinding() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setPopupMenu(String name) {
|
private void setPopupMenu(String name) {
|
||||||
setPopupMenuData(new MenuData(
|
setPopupMenuData(new MenuData(
|
||||||
new String[] { FunctionPlugin.SET_DATA_TYPE_PULLRIGHT, "Array..." }, null, "Array"));
|
new String[] { FunctionPlugin.SET_DATA_TYPE_PULLRIGHT, "Array..." }, null, "Array"));
|
||||||
|
|
|
@ -17,8 +17,7 @@ package ghidra.app.plugin.core.function;
|
||||||
|
|
||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
|
|
||||||
import docking.action.KeyBindingData;
|
import docking.action.*;
|
||||||
import docking.action.MenuData;
|
|
||||||
import ghidra.app.context.ListingActionContext;
|
import ghidra.app.context.ListingActionContext;
|
||||||
import ghidra.app.context.ListingContextAction;
|
import ghidra.app.context.ListingContextAction;
|
||||||
import ghidra.app.util.HelpTopics;
|
import ghidra.app.util.HelpTopics;
|
||||||
|
@ -38,7 +37,7 @@ public class CycleGroupAction extends ListingContextAction {
|
||||||
private CycleGroup cycleGroup;
|
private CycleGroup cycleGroup;
|
||||||
|
|
||||||
CycleGroupAction(CycleGroup group, FunctionPlugin plugin) {
|
CycleGroupAction(CycleGroup group, FunctionPlugin plugin) {
|
||||||
super(group.getName(), plugin.getName(), false);
|
super(group.getName(), plugin.getName(), KeyBindingType.SHARED);
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.cycleGroup = group;
|
this.cycleGroup = group;
|
||||||
|
|
||||||
|
@ -56,11 +55,6 @@ public class CycleGroupAction extends ListingContextAction {
|
||||||
setKeyBindingData(new KeyBindingData(keyStroke));
|
setKeyBindingData(new KeyBindingData(keyStroke));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean usesSharedKeyBinding() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setPopupMenu(String name, boolean isSignatureAction) {
|
private void setPopupMenu(String name, boolean isSignatureAction) {
|
||||||
setPopupMenuData(new MenuData(
|
setPopupMenuData(new MenuData(
|
||||||
new String[] { FunctionPlugin.SET_DATA_TYPE_PULLRIGHT, "Cycle", cycleGroup.getName() },
|
new String[] { FunctionPlugin.SET_DATA_TYPE_PULLRIGHT, "Cycle", cycleGroup.getName() },
|
||||||
|
|
|
@ -17,8 +17,7 @@ package ghidra.app.plugin.core.function;
|
||||||
|
|
||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
|
|
||||||
import docking.action.KeyBindingData;
|
import docking.action.*;
|
||||||
import docking.action.MenuData;
|
|
||||||
import ghidra.app.context.ListingActionContext;
|
import ghidra.app.context.ListingActionContext;
|
||||||
import ghidra.app.context.ListingContextAction;
|
import ghidra.app.context.ListingContextAction;
|
||||||
import ghidra.program.model.data.DataType;
|
import ghidra.program.model.data.DataType;
|
||||||
|
@ -41,7 +40,7 @@ class DataAction extends ListingContextAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataAction(String name, String group, DataType dataType, FunctionPlugin plugin) {
|
public DataAction(String name, String group, DataType dataType, FunctionPlugin plugin) {
|
||||||
super(name, plugin.getName(), false);
|
super(name, plugin.getName(), KeyBindingType.SHARED);
|
||||||
this.group = group;
|
this.group = group;
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.dataType = dataType;
|
this.dataType = dataType;
|
||||||
|
@ -52,11 +51,6 @@ class DataAction extends ListingContextAction {
|
||||||
initKeyStroke(getDefaultKeyStroke());
|
initKeyStroke(getDefaultKeyStroke());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean usesSharedKeyBinding() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected KeyStroke getDefaultKeyStroke() {
|
protected KeyStroke getDefaultKeyStroke() {
|
||||||
return null; // we have no default, but our subclasses may
|
return null; // we have no default, but our subclasses may
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,11 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.function;
|
package ghidra.app.plugin.core.function;
|
||||||
|
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
|
||||||
|
import docking.ActionContext;
|
||||||
|
import docking.action.KeyBindingData;
|
||||||
|
import docking.action.KeyBindingType;
|
||||||
import ghidra.app.cmd.function.SetVariableCommentCmd;
|
import ghidra.app.cmd.function.SetVariableCommentCmd;
|
||||||
import ghidra.app.context.ListingActionContext;
|
import ghidra.app.context.ListingActionContext;
|
||||||
import ghidra.app.context.ListingContextAction;
|
import ghidra.app.context.ListingContextAction;
|
||||||
|
@ -22,26 +27,19 @@ import ghidra.program.model.listing.Function;
|
||||||
import ghidra.program.model.listing.Variable;
|
import ghidra.program.model.listing.Variable;
|
||||||
import ghidra.program.util.*;
|
import ghidra.program.util.*;
|
||||||
|
|
||||||
import java.awt.event.KeyEvent;
|
|
||||||
|
|
||||||
import docking.ActionContext;
|
|
||||||
import docking.action.KeyBindingData;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <CODE>VariableCommentDeleteAction</CODE> allows the user to delete a function variable comment.
|
* <CODE>VariableCommentDeleteAction</CODE> allows the user to delete a function variable comment.
|
||||||
*/
|
*/
|
||||||
class VariableCommentDeleteAction extends ListingContextAction {
|
class VariableCommentDeleteAction extends ListingContextAction {
|
||||||
|
|
||||||
/** the plugin associated with this action. */
|
|
||||||
FunctionPlugin funcPlugin;
|
FunctionPlugin funcPlugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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 plugin
|
* @param plugin the plugin this action is associated with.
|
||||||
* the plugin this action is associated with.
|
*/
|
||||||
*/
|
|
||||||
VariableCommentDeleteAction(FunctionPlugin plugin) {
|
VariableCommentDeleteAction(FunctionPlugin plugin) {
|
||||||
super("Delete Function Variable Comment", plugin.getName(), false);
|
super("Delete Function Variable Comment", plugin.getName(), KeyBindingType.SHARED);
|
||||||
this.funcPlugin = plugin;
|
this.funcPlugin = plugin;
|
||||||
setKeyBindingData(new KeyBindingData(KeyEvent.VK_DELETE, 0));
|
setKeyBindingData(new KeyBindingData(KeyEvent.VK_DELETE, 0));
|
||||||
}
|
}
|
||||||
|
@ -65,7 +63,6 @@ class VariableCommentDeleteAction extends ListingContextAction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ///////////////////////////////////////////////////////////
|
|
||||||
/**
|
/**
|
||||||
* Get a variable using the current location.
|
* Get a variable using the current location.
|
||||||
*
|
*
|
||||||
|
|
|
@ -43,19 +43,19 @@ class VariableDeleteAction extends ListingContextAction {
|
||||||
* @param plugin the plugin this action is associated with.
|
* @param plugin the plugin this action is associated with.
|
||||||
*/
|
*/
|
||||||
VariableDeleteAction(FunctionPlugin plugin) {
|
VariableDeleteAction(FunctionPlugin plugin) {
|
||||||
super("Delete Function Variable", plugin.getName(), true);
|
super("Delete Function Variable", plugin.getName());
|
||||||
this.funcPlugin = plugin;
|
this.funcPlugin = plugin;
|
||||||
|
|
||||||
setPopupMenuPath(false);
|
setPopupMenuPath(false);
|
||||||
|
|
||||||
setKeyBindingData(new KeyBindingData(KeyEvent.VK_DELETE, 0));
|
setKeyBindingData(new KeyBindingData(KeyEvent.VK_DELETE, 0));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setPopupMenuPath(boolean isParameter) {
|
private void setPopupMenuPath(boolean isParameter) {
|
||||||
setPopupMenuData(new MenuData(new String[] { FunctionPlugin.VARIABLE_MENU_PULLRIGHT,
|
setPopupMenuData(new MenuData(
|
||||||
"Delete " + (isParameter ? "Parameter" : "Local Variable") }, null,
|
new String[] { FunctionPlugin.VARIABLE_MENU_PULLRIGHT,
|
||||||
FunctionPlugin.VARIABLE_MENU_SUBGROUP));
|
"Delete " + (isParameter ? "Parameter" : "Local Variable") },
|
||||||
|
null, FunctionPlugin.VARIABLE_MENU_SUBGROUP));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -190,18 +190,12 @@ public class FunctionWindowPlugin extends ProgramPlugin implements DomainObjectL
|
||||||
|
|
||||||
private void addSelectAction() {
|
private void addSelectAction() {
|
||||||
|
|
||||||
selectAction = new MakeProgramSelectionAction(getName(), provider.getTable()) {
|
selectAction = new MakeProgramSelectionAction(this, provider.getTable());
|
||||||
@Override
|
|
||||||
protected void makeSelection(ActionContext context) {
|
|
||||||
selectFunctions(provider.selectFunctions());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
tool.addLocalAction(provider, selectAction);
|
tool.addLocalAction(provider, selectAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCompareAction() {
|
private void addCompareAction() {
|
||||||
compareAction = new DockingAction("Compare Selected Functions", getName(), false) {
|
compareAction = new DockingAction("Compare Selected Functions", getName()) {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionContext context) {
|
public void actionPerformed(ActionContext context) {
|
||||||
compareSelectedFunctions();
|
compareSelectedFunctions();
|
||||||
|
|
|
@ -16,13 +16,10 @@
|
||||||
package ghidra.app.plugin.core.instructionsearch.ui;
|
package ghidra.app.plugin.core.instructionsearch.ui;
|
||||||
|
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.swing.JToolBar;
|
import javax.swing.JToolBar;
|
||||||
import javax.swing.table.TableCellRenderer;
|
import javax.swing.table.TableCellRenderer;
|
||||||
|
|
||||||
import docking.ActionContext;
|
|
||||||
import docking.action.DockingActionIf;
|
|
||||||
import docking.widgets.table.GTable;
|
import docking.widgets.table.GTable;
|
||||||
import ghidra.app.plugin.core.instructionsearch.model.*;
|
import ghidra.app.plugin.core.instructionsearch.model.*;
|
||||||
import ghidra.util.table.GhidraTable;
|
import ghidra.util.table.GhidraTable;
|
||||||
|
@ -109,17 +106,6 @@ public abstract class AbstractInstructionTable extends GhidraTable {
|
||||||
return (InstructionTableDataObject) getModel().getValueAt(row, col);
|
return (InstructionTableDataObject) getModel().getValueAt(row, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Must invoke the parent implementation of this to have the context menu
|
|
||||||
* created.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public List<DockingActionIf> getDockingActions(ActionContext context) {
|
|
||||||
List<DockingActionIf> list = super.getDockingActions(context);
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Must override so it doesn't return an instance of the base
|
* Must override so it doesn't return an instance of the base
|
||||||
* {@link TableCellRenderer}, which will override our changes in the
|
* {@link TableCellRenderer}, which will override our changes in the
|
||||||
|
|
|
@ -22,7 +22,6 @@ import java.util.List;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
import docking.ActionContext;
|
|
||||||
import docking.DockingWindowManager;
|
import docking.DockingWindowManager;
|
||||||
import docking.action.DockingActionIf;
|
import docking.action.DockingActionIf;
|
||||||
import docking.widgets.EmptyBorderButton;
|
import docking.widgets.EmptyBorderButton;
|
||||||
|
@ -102,7 +101,7 @@ public class InstructionTable extends AbstractInstructionTable {
|
||||||
* (which is all of them).
|
* (which is all of them).
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<DockingActionIf> getDockingActions(ActionContext context) {
|
public List<DockingActionIf> getDockingActions() {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,14 +134,12 @@ public class PreviewTable extends AbstractInstructionTable {
|
||||||
/**
|
/**
|
||||||
* Adds custom context-sensitive menus to the table. This does NOT modify
|
* Adds custom context-sensitive menus to the table. This does NOT modify
|
||||||
* any existing menus; it simply adds to them.
|
* any existing menus; it simply adds to them.
|
||||||
*
|
|
||||||
* @param context the action context
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<DockingActionIf> getDockingActions(ActionContext context) {
|
public List<DockingActionIf> getDockingActions() {
|
||||||
|
|
||||||
// Invoke the base class method to add default menu options.
|
// Invoke the base class method to add default menu options.
|
||||||
List<DockingActionIf> list = super.getDockingActions(context);
|
List<DockingActionIf> list = super.getDockingActions();
|
||||||
|
|
||||||
// And now add our own.
|
// And now add our own.
|
||||||
addCustomMenuItems(list);
|
addCustomMenuItems(list);
|
||||||
|
@ -489,7 +487,7 @@ public class PreviewTable extends AbstractInstructionTable {
|
||||||
*/
|
*/
|
||||||
private void createCopyInstructionWithCommentsAction(String owner) {
|
private void createCopyInstructionWithCommentsAction(String owner) {
|
||||||
copyInstructionWithCommentsAction =
|
copyInstructionWithCommentsAction =
|
||||||
new DockingAction("Selected Instructions (with comments)", owner, false) {
|
new DockingAction("Selected Instructions (with comments)", owner) {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionContext context) {
|
public void actionPerformed(ActionContext context) {
|
||||||
int[] selectedRows = PreviewTable.this.getSelectedRows();
|
int[] selectedRows = PreviewTable.this.getSelectedRows();
|
||||||
|
@ -520,7 +518,7 @@ public class PreviewTable extends AbstractInstructionTable {
|
||||||
* as shown in the table.
|
* as shown in the table.
|
||||||
*/
|
*/
|
||||||
private void createCopyInstructionAction(String owner) {
|
private void createCopyInstructionAction(String owner) {
|
||||||
copyInstructionAction = new DockingAction("Selected Instructions", owner, false) {
|
copyInstructionAction = new DockingAction("Selected Instructions", owner) {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionContext context) {
|
public void actionPerformed(ActionContext context) {
|
||||||
int[] selectedRows = PreviewTable.this.getSelectedRows();
|
int[] selectedRows = PreviewTable.this.getSelectedRows();
|
||||||
|
@ -541,7 +539,7 @@ public class PreviewTable extends AbstractInstructionTable {
|
||||||
* rows, as shown in the table, with no spaces.
|
* rows, as shown in the table, with no spaces.
|
||||||
*/
|
*/
|
||||||
private void createCopyNoSpacesAction(String owner) {
|
private void createCopyNoSpacesAction(String owner) {
|
||||||
copyNoSpacesAction = new DockingAction("Selected instructions (no spaces)", owner, false) {
|
copyNoSpacesAction = new DockingAction("Selected instructions (no spaces)", owner) {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionContext context) {
|
public void actionPerformed(ActionContext context) {
|
||||||
int[] selectedRows = PreviewTable.this.getSelectedRows();
|
int[] selectedRows = PreviewTable.this.getSelectedRows();
|
||||||
|
|
|
@ -19,7 +19,8 @@ import java.io.*;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.Icon;
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
|
||||||
import docking.ActionContext;
|
import docking.ActionContext;
|
||||||
import docking.action.DockingAction;
|
import docking.action.DockingAction;
|
||||||
|
@ -33,12 +34,12 @@ import utility.function.Callback;
|
||||||
|
|
||||||
public class InterpreterComponentProvider extends ComponentProviderAdapter
|
public class InterpreterComponentProvider extends ComponentProviderAdapter
|
||||||
implements InterpreterConsole {
|
implements InterpreterConsole {
|
||||||
|
|
||||||
private static final String CONSOLE_GIF = "images/monitor.png";
|
private static final String CONSOLE_GIF = "images/monitor.png";
|
||||||
private static final String CLEAR_GIF = "images/erase16.png";
|
private static final String CLEAR_GIF = "images/erase16.png";
|
||||||
|
|
||||||
private InterpreterPanel panel;
|
private InterpreterPanel panel;
|
||||||
private InterpreterConnection interpreter;
|
private InterpreterConnection interpreter;
|
||||||
private ImageIcon icon;
|
|
||||||
private List<Callback> firstActivationCallbacks;
|
private List<Callback> firstActivationCallbacks;
|
||||||
|
|
||||||
public InterpreterComponentProvider(InterpreterPanelPlugin plugin,
|
public InterpreterComponentProvider(InterpreterPanelPlugin plugin,
|
||||||
|
@ -54,9 +55,9 @@ public class InterpreterComponentProvider extends ComponentProviderAdapter
|
||||||
addToTool();
|
addToTool();
|
||||||
createActions();
|
createActions();
|
||||||
|
|
||||||
icon = interpreter.getIcon();
|
Icon icon = interpreter.getIcon();
|
||||||
if (icon == null) {
|
if (icon == null) {
|
||||||
ResourceManager.loadImage(CONSOLE_GIF);
|
icon = ResourceManager.loadImage(CONSOLE_GIF);
|
||||||
}
|
}
|
||||||
setIcon(icon);
|
setIcon(icon);
|
||||||
|
|
||||||
|
@ -107,11 +108,6 @@ public class InterpreterComponentProvider extends ComponentProviderAdapter
|
||||||
addLocalAction(disposeAction);
|
addLocalAction(disposeAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Icon getIcon() {
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getWindowSubMenuName() {
|
public String getWindowSubMenuName() {
|
||||||
return interpreter.getTitle();
|
return interpreter.getTitle();
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.memory;
|
package ghidra.app.plugin.core.memory;
|
||||||
|
|
||||||
|
import java.awt.Cursor;
|
||||||
|
|
||||||
import ghidra.app.CorePluginPackage;
|
import ghidra.app.CorePluginPackage;
|
||||||
import ghidra.app.events.ProgramLocationPluginEvent;
|
import ghidra.app.events.ProgramLocationPluginEvent;
|
||||||
import ghidra.app.plugin.PluginCategoryNames;
|
import ghidra.app.plugin.PluginCategoryNames;
|
||||||
|
@ -31,15 +33,6 @@ import ghidra.program.model.mem.MemoryBlock;
|
||||||
import ghidra.program.util.ChangeManager;
|
import ghidra.program.util.ChangeManager;
|
||||||
import ghidra.program.util.ProgramLocation;
|
import ghidra.program.util.ProgramLocation;
|
||||||
|
|
||||||
import java.awt.Cursor;
|
|
||||||
|
|
||||||
import javax.swing.ImageIcon;
|
|
||||||
|
|
||||||
import resources.ResourceManager;
|
|
||||||
import docking.ActionContext;
|
|
||||||
import docking.action.DockingAction;
|
|
||||||
import docking.action.ToolBarData;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <CODE>MemoryMapPlugin</CODE> displays a memory map of all blocks in
|
* <CODE>MemoryMapPlugin</CODE> displays a memory map of all blocks in
|
||||||
* the current program's memory. Options for Adding, Editing, and Deleting
|
* the current program's memory. Options for Adding, Editing, and Deleting
|
||||||
|
@ -61,20 +54,15 @@ public class MemoryMapPlugin extends ProgramPlugin implements DomainObjectListen
|
||||||
final static Cursor WAIT_CURSOR = new Cursor(Cursor.WAIT_CURSOR);
|
final static Cursor WAIT_CURSOR = new Cursor(Cursor.WAIT_CURSOR);
|
||||||
final static Cursor NORM_CURSOR = new Cursor(Cursor.DEFAULT_CURSOR);
|
final static Cursor NORM_CURSOR = new Cursor(Cursor.DEFAULT_CURSOR);
|
||||||
|
|
||||||
private DockingAction memViewAction;
|
|
||||||
private MemoryMapProvider provider;
|
private MemoryMapProvider provider;
|
||||||
private GoToService goToService;
|
private GoToService goToService;
|
||||||
private MemoryMapManager memManager;
|
private MemoryMapManager memManager;
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*/
|
|
||||||
public MemoryMapPlugin(PluginTool tool) {
|
public MemoryMapPlugin(PluginTool tool) {
|
||||||
super(tool, true, false);
|
super(tool, true, false);
|
||||||
|
|
||||||
memManager = new MemoryMapManager(this);
|
memManager = new MemoryMapManager(this);
|
||||||
provider = new MemoryMapProvider(this);
|
provider = new MemoryMapProvider(this);
|
||||||
createActions();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -83,9 +71,6 @@ public class MemoryMapPlugin extends ProgramPlugin implements DomainObjectListen
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
if (memViewAction != null) {
|
|
||||||
memViewAction.dispose();
|
|
||||||
}
|
|
||||||
if (provider != null) {
|
if (provider != null) {
|
||||||
provider.dispose();
|
provider.dispose();
|
||||||
provider = null;
|
provider = null;
|
||||||
|
@ -122,8 +107,9 @@ public class MemoryMapPlugin extends ProgramPlugin implements DomainObjectListen
|
||||||
@Override
|
@Override
|
||||||
protected void init() {
|
protected void init() {
|
||||||
goToService = tool.getService(GoToService.class);
|
goToService = tool.getService(GoToService.class);
|
||||||
if (currentProgram != null)
|
if (currentProgram != null) {
|
||||||
programActivated(currentProgram);
|
programActivated(currentProgram);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -168,29 +154,4 @@ public class MemoryMapPlugin extends ProgramPlugin implements DomainObjectListen
|
||||||
ProgramLocation loc = new ProgramLocation(currentProgram, addr);
|
ProgramLocation loc = new ProgramLocation(currentProgram, addr);
|
||||||
goToService.goTo(loc);
|
goToService.goTo(loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the action for toolbar.
|
|
||||||
*/
|
|
||||||
private void createActions() {
|
|
||||||
|
|
||||||
memViewAction = new DockingAction("View Memory Map", getName()) {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionContext context) {
|
|
||||||
showMemory();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ImageIcon tableImage = ResourceManager.loadImage(MemoryMapProvider.MEMORY_IMAGE);
|
|
||||||
memViewAction.setToolBarData(new ToolBarData(tableImage, "View"));
|
|
||||||
memViewAction.setDescription("Display Memory Map");
|
|
||||||
tool.addAction(memViewAction);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback for the View memory Action
|
|
||||||
*/
|
|
||||||
private void showMemory() {
|
|
||||||
tool.showComponentProvider(provider, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,9 +81,11 @@ class MemoryMapProvider extends ComponentProviderAdapter {
|
||||||
MemoryMapProvider(MemoryMapPlugin plugin) {
|
MemoryMapProvider(MemoryMapPlugin plugin) {
|
||||||
super(plugin.getTool(), "Memory Map", plugin.getName(), ProgramActionContext.class);
|
super(plugin.getTool(), "Memory Map", plugin.getName(), ProgramActionContext.class);
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
|
|
||||||
setHelpLocation(new HelpLocation(plugin.getName(), getName()));
|
setHelpLocation(new HelpLocation(plugin.getName(), getName()));
|
||||||
memManager = plugin.getMemoryMapManager();
|
memManager = plugin.getMemoryMapManager();
|
||||||
setIcon(ResourceManager.loadImage(MEMORY_IMAGE));
|
setIcon(ResourceManager.loadImage(MEMORY_IMAGE));
|
||||||
|
addToToolbar();
|
||||||
mainPanel = buildMainPanel();
|
mainPanel = buildMainPanel();
|
||||||
addToTool();
|
addToTool();
|
||||||
addLocalActions();
|
addLocalActions();
|
||||||
|
@ -107,9 +109,6 @@ class MemoryMapProvider extends ComponentProviderAdapter {
|
||||||
return new ProgramActionContext(this, program);
|
return new ProgramActionContext(this, program);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the status text on this dialog.
|
|
||||||
*/
|
|
||||||
void setStatusText(String msg) {
|
void setStatusText(String msg) {
|
||||||
tool.setStatusInfo(msg);
|
tool.setStatusInfo(msg);
|
||||||
}
|
}
|
||||||
|
@ -367,9 +366,6 @@ class MemoryMapProvider extends ComponentProviderAdapter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
JTable getTable() {
|
JTable getTable() {
|
||||||
return memTable;
|
return memTable;
|
||||||
}
|
}
|
||||||
|
@ -462,7 +458,8 @@ class MemoryMapProvider extends ComponentProviderAdapter {
|
||||||
public void mousePressed(MouseEvent e) {
|
public void mousePressed(MouseEvent e) {
|
||||||
setStatusText("");
|
setStatusText("");
|
||||||
if (!e.isPopupTrigger()) {
|
if (!e.isPopupTrigger()) {
|
||||||
if ((e.getModifiers() & (InputEvent.CTRL_MASK | InputEvent.SHIFT_MASK)) == 0) {
|
if ((e.getModifiersEx() &
|
||||||
|
(InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK)) == 0) {
|
||||||
selectAddress();
|
selectAddress();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -368,7 +368,7 @@ public class NextPrevAddressPlugin extends Plugin {
|
||||||
|
|
||||||
private NavigationAction(Navigatable navigatable, LocationMemento location, boolean isNext,
|
private NavigationAction(Navigatable navigatable, LocationMemento location, boolean isNext,
|
||||||
NavigationHistoryService service, CodeUnitFormat formatter) {
|
NavigationHistoryService service, CodeUnitFormat formatter) {
|
||||||
super("NavigationAction: " + ++idCount, NextPrevAddressPlugin.this.getName(), false);
|
super("NavigationAction: " + ++idCount, NextPrevAddressPlugin.this.getName());
|
||||||
this.location = location;
|
this.location = location;
|
||||||
this.isNext = isNext;
|
this.isNext = isNext;
|
||||||
this.service = service;
|
this.service = service;
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
/* ###
|
||||||
|
* 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.navigation;
|
||||||
|
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import javax.swing.KeyStroke;
|
||||||
|
|
||||||
|
import docking.*;
|
||||||
|
import docking.action.*;
|
||||||
|
import ghidra.app.CorePluginPackage;
|
||||||
|
import ghidra.app.plugin.PluginCategoryNames;
|
||||||
|
import ghidra.framework.plugintool.*;
|
||||||
|
import ghidra.framework.plugintool.util.PluginStatus;
|
||||||
|
import ghidra.framework.plugintool.util.ToolConstants;
|
||||||
|
import ghidra.util.HelpLocation;
|
||||||
|
|
||||||
|
//@formatter:off
|
||||||
|
@PluginInfo(
|
||||||
|
status = PluginStatus.RELEASED,
|
||||||
|
packageName = CorePluginPackage.NAME,
|
||||||
|
category = PluginCategoryNames.NAVIGATION,
|
||||||
|
shortDescription = "Component Provider Navigation",
|
||||||
|
description = "The plugin provides actions to manage switching between Component Providers."
|
||||||
|
)
|
||||||
|
//@formatter:on
|
||||||
|
public class ProviderNavigationPlugin extends Plugin {
|
||||||
|
|
||||||
|
static final String GO_TO_LAST_ACTIVE_COMPONENT_ACTION_NAME = "Go To Last Active Component";
|
||||||
|
|
||||||
|
private ComponentProvider previousActiveProvider;
|
||||||
|
private ComponentProvider currentActiveProvider;
|
||||||
|
private Consumer<ComponentProvider> providerActivator =
|
||||||
|
provider -> tool.showComponentProvider(provider, true);
|
||||||
|
|
||||||
|
private DockingContextListener contextListener = context -> {
|
||||||
|
|
||||||
|
ComponentProvider componentProvider = context.getComponentProvider();
|
||||||
|
if (componentProvider != null) {
|
||||||
|
if (componentProvider != currentActiveProvider) {
|
||||||
|
previousActiveProvider = currentActiveProvider;
|
||||||
|
currentActiveProvider = componentProvider;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public ProviderNavigationPlugin(PluginTool tool) {
|
||||||
|
super(tool);
|
||||||
|
|
||||||
|
createActions();
|
||||||
|
|
||||||
|
tool.addContextListener(contextListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createActions() {
|
||||||
|
|
||||||
|
DockingAction previousProviderAction =
|
||||||
|
new DockingAction(GO_TO_LAST_ACTIVE_COMPONENT_ACTION_NAME, getName()) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionContext context) {
|
||||||
|
providerActivator.accept(previousActiveProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabledForContext(ActionContext context) {
|
||||||
|
return previousActiveProvider != null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
previousProviderAction.setMenuBarData(new MenuData(
|
||||||
|
new String[] { ToolConstants.MENU_NAVIGATION, GO_TO_LAST_ACTIVE_COMPONENT_ACTION_NAME },
|
||||||
|
null, ToolConstants.MENU_NAVIGATION_GROUP_WINDOWS, MenuData.NO_MNEMONIC,
|
||||||
|
"xLowInMenuSubGroup"));
|
||||||
|
previousProviderAction.setKeyBindingData(new KeyBindingData(
|
||||||
|
KeyStroke.getKeyStroke(KeyEvent.VK_F6, DockingUtils.CONTROL_KEY_MODIFIER_MASK)));
|
||||||
|
previousProviderAction.setHelpLocation(
|
||||||
|
new HelpLocation("Navigation", "Navigation_Previous_Provider"));
|
||||||
|
|
||||||
|
tool.addAction(previousProviderAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
// for testing
|
||||||
|
void resetTrackingState() {
|
||||||
|
previousActiveProvider = null;
|
||||||
|
currentActiveProvider = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for testing
|
||||||
|
void setProviderActivator(Consumer<ComponentProvider> newActivator) {
|
||||||
|
this.providerActivator = newActivator;
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,8 +17,7 @@ package ghidra.app.plugin.core.navigation.locationreferences;
|
||||||
|
|
||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
|
|
||||||
import docking.action.KeyBindingData;
|
import docking.action.*;
|
||||||
import docking.action.MenuData;
|
|
||||||
import ghidra.app.actions.AbstractFindReferencesDataTypeAction;
|
import ghidra.app.actions.AbstractFindReferencesDataTypeAction;
|
||||||
import ghidra.app.context.ListingActionContext;
|
import ghidra.app.context.ListingActionContext;
|
||||||
import ghidra.app.context.ListingContextAction;
|
import ghidra.app.context.ListingContextAction;
|
||||||
|
@ -34,7 +33,7 @@ public class FindReferencesToAction extends ListingContextAction {
|
||||||
private int subGroupPosition;
|
private int subGroupPosition;
|
||||||
|
|
||||||
public FindReferencesToAction(LocationReferencesPlugin plugin, int subGroupPosition) {
|
public FindReferencesToAction(LocationReferencesPlugin plugin, int subGroupPosition) {
|
||||||
super(AbstractFindReferencesDataTypeAction.NAME, plugin.getName(), false);
|
super(AbstractFindReferencesDataTypeAction.NAME, plugin.getName(), KeyBindingType.SHARED);
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.subGroupPosition = subGroupPosition;
|
this.subGroupPosition = subGroupPosition;
|
||||||
|
|
||||||
|
@ -54,11 +53,6 @@ public class FindReferencesToAction extends ListingContextAction {
|
||||||
setKeyBindingData(new KeyBindingData(keyStroke));
|
setKeyBindingData(new KeyBindingData(keyStroke));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean usesSharedKeyBinding() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ListingActionContext context) {
|
public void actionPerformed(ListingActionContext context) {
|
||||||
plugin.displayProvider(context);
|
plugin.displayProvider(context);
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.navigation.locationreferences;
|
package ghidra.app.plugin.core.navigation.locationreferences;
|
||||||
|
|
||||||
|
import docking.action.KeyBindingType;
|
||||||
import docking.action.MenuData;
|
import docking.action.MenuData;
|
||||||
import ghidra.app.context.ListingActionContext;
|
import ghidra.app.context.ListingActionContext;
|
||||||
import ghidra.app.context.ListingContextAction;
|
import ghidra.app.context.ListingContextAction;
|
||||||
|
@ -35,7 +36,7 @@ public class FindReferencesToAddressAction extends ListingContextAction {
|
||||||
private LocationReferencesPlugin plugin;
|
private LocationReferencesPlugin plugin;
|
||||||
|
|
||||||
public FindReferencesToAddressAction(LocationReferencesPlugin plugin, int subGroupPosition) {
|
public FindReferencesToAddressAction(LocationReferencesPlugin plugin, int subGroupPosition) {
|
||||||
super("Show References to Address", plugin.getName(), false);
|
super("Show References to Address", plugin.getName(), KeyBindingType.SHARED);
|
||||||
|
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
|
|
||||||
|
|
|
@ -17,13 +17,14 @@ package ghidra.app.plugin.core.navigation.locationreferences;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import docking.widgets.fieldpanel.support.Highlight;
|
import docking.widgets.fieldpanel.support.Highlight;
|
||||||
import ghidra.app.util.viewer.field.*;
|
import ghidra.app.util.viewer.field.*;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.data.Composite;
|
import ghidra.program.model.data.Composite;
|
||||||
import ghidra.program.model.listing.Data;
|
import ghidra.program.model.listing.Data;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.util.StringUtilities;
|
|
||||||
import ghidra.util.datastruct.Accumulator;
|
import ghidra.util.datastruct.Accumulator;
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
@ -115,7 +116,7 @@ public class GenericCompositeDataTypeLocationDescriptor extends GenericDataTypeL
|
||||||
else if (OperandFieldFactory.class.isAssignableFrom(fieldFactoryClass)) {
|
else if (OperandFieldFactory.class.isAssignableFrom(fieldFactoryClass)) {
|
||||||
|
|
||||||
// Not sure how to get the correct part of the text. This is a hack for now.
|
// Not sure how to get the correct part of the text. This is a hack for now.
|
||||||
int offset = StringUtilities.indexOfIgnoreCase(text, typeAndFieldName, 0);
|
int offset = StringUtils.indexOfIgnoreCase(text, typeAndFieldName, 0);
|
||||||
if (offset != -1) {
|
if (offset != -1) {
|
||||||
return new Highlight[] {
|
return new Highlight[] {
|
||||||
new Highlight(offset, offset + typeAndFieldName.length() - 1, highlightColor) };
|
new Highlight(offset, offset + typeAndFieldName.length() - 1, highlightColor) };
|
||||||
|
|
|
@ -41,6 +41,7 @@ import ghidra.util.HelpLocation;
|
||||||
import ghidra.util.table.GhidraTable;
|
import ghidra.util.table.GhidraTable;
|
||||||
import ghidra.util.table.SelectionNavigationAction;
|
import ghidra.util.table.SelectionNavigationAction;
|
||||||
import ghidra.util.table.actions.DeleteTableRowAction;
|
import ghidra.util.table.actions.DeleteTableRowAction;
|
||||||
|
import ghidra.util.table.actions.MakeProgramSelectionAction;
|
||||||
import ghidra.util.task.SwingUpdateManager;
|
import ghidra.util.task.SwingUpdateManager;
|
||||||
import resources.Icons;
|
import resources.Icons;
|
||||||
import resources.ResourceManager;
|
import resources.ResourceManager;
|
||||||
|
@ -51,7 +52,6 @@ import resources.ResourceManager;
|
||||||
public class LocationReferencesProvider extends ComponentProviderAdapter
|
public class LocationReferencesProvider extends ComponentProviderAdapter
|
||||||
implements DomainObjectListener, NavigatableRemovalListener {
|
implements DomainObjectListener, NavigatableRemovalListener {
|
||||||
|
|
||||||
private static Icon SELECT_ICON = ResourceManager.loadImage("images/text_align_justify.png");
|
|
||||||
private static Icon HIGHLIGHT_ICON = ResourceManager.loadImage("images/tag_yellow.png");
|
private static Icon HIGHLIGHT_ICON = ResourceManager.loadImage("images/tag_yellow.png");
|
||||||
private static Icon HOME_ICON = ResourceManager.loadImage("images/go-home.png");
|
private static Icon HOME_ICON = ResourceManager.loadImage("images/go-home.png");
|
||||||
private static Icon REFRESH_ICON = Icons.REFRESH_ICON;
|
private static Icon REFRESH_ICON = Icons.REFRESH_ICON;
|
||||||
|
@ -153,7 +153,7 @@ public class LocationReferencesProvider extends ComponentProviderAdapter
|
||||||
referencesPanel.reloadModel();
|
referencesPanel.reloadModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void makeSelection() {
|
private void doMakeSelection() {
|
||||||
locationReferencesPlugin.firePluginEvent(new ProgramSelectionPluginEvent(
|
locationReferencesPlugin.firePluginEvent(new ProgramSelectionPluginEvent(
|
||||||
locationReferencesPlugin.getName(), referencesPanel.getSelection(), program));
|
locationReferencesPlugin.getName(), referencesPanel.getSelection(), program));
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,10 @@ public class LocationReferencesProvider extends ComponentProviderAdapter
|
||||||
setTitle(generateTitle());
|
setTitle(generateTitle());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the new LocationDescriptor and updates the providers table contents. */
|
/**
|
||||||
|
* Sets the new LocationDescriptor and updates the providers table contents.
|
||||||
|
* @param locationDescriptor the new descriptor
|
||||||
|
*/
|
||||||
void update(LocationDescriptor locationDescriptor) {
|
void update(LocationDescriptor locationDescriptor) {
|
||||||
setLocationDescriptor(locationDescriptor, navigatable);
|
setLocationDescriptor(locationDescriptor, navigatable);
|
||||||
updateManager.updateNow();
|
updateManager.updateNow();
|
||||||
|
@ -246,30 +249,8 @@ public class LocationReferencesProvider extends ComponentProviderAdapter
|
||||||
homeAction.setToolBarData(new ToolBarData(HOME_ICON));
|
homeAction.setToolBarData(new ToolBarData(HOME_ICON));
|
||||||
updateHomeActionState();
|
updateHomeActionState();
|
||||||
|
|
||||||
selectionAction = new DockingAction("Make Selection", locationReferencesPlugin.getName()) {
|
selectionAction =
|
||||||
@Override
|
new MakeProgramSelectionAction(locationReferencesPlugin, referencesPanel.getTable());
|
||||||
public void actionPerformed(ActionContext context) {
|
|
||||||
makeSelection();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabledForContext(ActionContext context) {
|
|
||||||
return referencesPanel.getTable().getSelectedRowCount() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isAddToPopup(ActionContext context) {
|
|
||||||
if (referencesPanel.getTable().getClass().isInstance(context.getContextObject())) {
|
|
||||||
return super.isEnabledForContext(context);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
selectionAction.setPopupMenuData(
|
|
||||||
new MenuData(new String[] { "Make Selection" }, SELECT_ICON));
|
|
||||||
selectionAction.setToolBarData(new ToolBarData(SELECT_ICON));
|
|
||||||
selectionAction.setDescription("Make a program selection from selected rows in table");
|
|
||||||
selectionAction.setEnabled(false); // off by default; updated when the user clicks the table
|
|
||||||
|
|
||||||
highlightAction = new ToggleDockingAction("Highlight Matches", getName()) {
|
highlightAction = new ToggleDockingAction("Highlight Matches", getName()) {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -15,6 +15,15 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.progmgr;
|
package ghidra.app.plugin.core.progmgr;
|
||||||
|
|
||||||
|
import java.awt.event.InputEvent;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
|
||||||
|
import javax.swing.KeyStroke;
|
||||||
|
import javax.swing.Timer;
|
||||||
|
|
||||||
|
import docking.ActionContext;
|
||||||
|
import docking.DockingUtils;
|
||||||
|
import docking.action.*;
|
||||||
import ghidra.app.CorePluginPackage;
|
import ghidra.app.CorePluginPackage;
|
||||||
import ghidra.app.events.*;
|
import ghidra.app.events.*;
|
||||||
import ghidra.app.plugin.PluginCategoryNames;
|
import ghidra.app.plugin.PluginCategoryNames;
|
||||||
|
@ -23,18 +32,10 @@ import ghidra.app.services.ProgramManager;
|
||||||
import ghidra.framework.model.*;
|
import ghidra.framework.model.*;
|
||||||
import ghidra.framework.plugintool.*;
|
import ghidra.framework.plugintool.*;
|
||||||
import ghidra.framework.plugintool.util.PluginStatus;
|
import ghidra.framework.plugintool.util.PluginStatus;
|
||||||
|
import ghidra.framework.plugintool.util.ToolConstants;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
|
|
||||||
import java.awt.event.*;
|
|
||||||
|
|
||||||
import javax.swing.KeyStroke;
|
|
||||||
import javax.swing.Timer;
|
|
||||||
|
|
||||||
import docking.ActionContext;
|
|
||||||
import docking.DockingUtils;
|
|
||||||
import docking.action.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plugin to show a "tab" for each open program; the selected tab is the activated program.
|
* Plugin to show a "tab" for each open program; the selected tab is the activated program.
|
||||||
*/
|
*/
|
||||||
|
@ -58,10 +59,10 @@ public class MultiTabPlugin extends Plugin implements DomainObjectListener {
|
||||||
// DockingUtils calls into Swing code. Further, we don't want Swing code being accessed
|
// DockingUtils calls into Swing code. Further, we don't want Swing code being accessed
|
||||||
// when the Plugin classes are loaded, as they get loaded in the headless environment.
|
// when the Plugin classes are loaded, as they get loaded in the headless environment.
|
||||||
//
|
//
|
||||||
private final KeyStroke NEXT_TAB_KEYSTROKE = KeyStroke.getKeyStroke(KeyEvent.VK_F9,
|
private final KeyStroke NEXT_TAB_KEYSTROKE =
|
||||||
DockingUtils.CONTROL_KEY_MODIFIER_MASK);
|
KeyStroke.getKeyStroke(KeyEvent.VK_F9, DockingUtils.CONTROL_KEY_MODIFIER_MASK);
|
||||||
private final KeyStroke PREVIOUS_TAB_KEYSTROKE = KeyStroke.getKeyStroke(KeyEvent.VK_F8,
|
private final KeyStroke PREVIOUS_TAB_KEYSTROKE =
|
||||||
DockingUtils.CONTROL_KEY_MODIFIER_MASK);
|
KeyStroke.getKeyStroke(KeyEvent.VK_F8, DockingUtils.CONTROL_KEY_MODIFIER_MASK);
|
||||||
|
|
||||||
private MultiTabPanel tabPanel;
|
private MultiTabPanel tabPanel;
|
||||||
private ProgramManager progService;
|
private ProgramManager progService;
|
||||||
|
@ -92,14 +93,17 @@ public class MultiTabPlugin extends Plugin implements DomainObjectListener {
|
||||||
showProgramList();
|
showProgramList();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
goToProgramAction.setMenuBarData(new MenuData(new String[] { "Navigation",
|
goToProgramAction.setMenuBarData(
|
||||||
"Go To Program..." }, null, "GoToProgram", MenuData.NO_MNEMONIC, firstGroup));
|
new MenuData(new String[] { ToolConstants.MENU_NAVIGATION, "Go To Program..." }, null,
|
||||||
goToProgramAction.setKeyBindingData(new KeyBindingData(KeyEvent.VK_F7,
|
ToolConstants.MENU_NAVIGATION_GROUP_WINDOWS, MenuData.NO_MNEMONIC, firstGroup));
|
||||||
InputEvent.CTRL_DOWN_MASK));
|
goToProgramAction.setKeyBindingData(
|
||||||
|
new KeyBindingData(KeyEvent.VK_F7, InputEvent.CTRL_DOWN_MASK));
|
||||||
|
|
||||||
goToProgramAction.setEnabled(false);
|
goToProgramAction.setEnabled(false);
|
||||||
goToProgramAction.setDescription("Shows the program selection dialog with the current program selected");
|
goToProgramAction.setDescription(
|
||||||
goToProgramAction.setHelpLocation(new HelpLocation("ProgramManagerPlugin", "Go_To_Program"));
|
"Shows the program selection dialog with the current program selected");
|
||||||
|
goToProgramAction.setHelpLocation(
|
||||||
|
new HelpLocation("ProgramManagerPlugin", "Go_To_Program"));
|
||||||
|
|
||||||
goToNextProgramAction = new DockingAction("Go To Next Program", getName()) {
|
goToNextProgramAction = new DockingAction("Go To Next Program", getName()) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -109,10 +113,11 @@ public class MultiTabPlugin extends Plugin implements DomainObjectListener {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
goToNextProgramAction.setEnabled(false);
|
goToNextProgramAction.setEnabled(false);
|
||||||
goToNextProgramAction.setDescription("Highlights the next program tab and then switches to that program");
|
goToNextProgramAction.setDescription(
|
||||||
|
"Highlights the next program tab and then switches to that program");
|
||||||
goToNextProgramAction.setKeyBindingData(new KeyBindingData(NEXT_TAB_KEYSTROKE));
|
goToNextProgramAction.setKeyBindingData(new KeyBindingData(NEXT_TAB_KEYSTROKE));
|
||||||
goToNextProgramAction.setHelpLocation(new HelpLocation("ProgramManagerPlugin",
|
goToNextProgramAction.setHelpLocation(
|
||||||
"Go_To_Next_And_Previous_Program"));
|
new HelpLocation("ProgramManagerPlugin", "Go_To_Next_And_Previous_Program"));
|
||||||
|
|
||||||
goToPreviousProgramAction = new DockingAction("Go To Previous Program", getName()) {
|
goToPreviousProgramAction = new DockingAction("Go To Previous Program", getName()) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -122,20 +127,14 @@ public class MultiTabPlugin extends Plugin implements DomainObjectListener {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
goToPreviousProgramAction.setEnabled(false);
|
goToPreviousProgramAction.setEnabled(false);
|
||||||
goToPreviousProgramAction.setMenuBarData(new MenuData(new String[] { "Navigation" }, null,
|
|
||||||
null));
|
|
||||||
goToPreviousProgramAction.setKeyBindingData(new KeyBindingData(PREVIOUS_TAB_KEYSTROKE));
|
goToPreviousProgramAction.setKeyBindingData(new KeyBindingData(PREVIOUS_TAB_KEYSTROKE));
|
||||||
goToPreviousProgramAction.setDescription("Highlights the previous program tab and then switches to that program");
|
goToPreviousProgramAction.setDescription(
|
||||||
goToPreviousProgramAction.setHelpLocation(new HelpLocation("ProgramManagerPlugin",
|
"Highlights the previous program tab and then switches to that program");
|
||||||
"Go_To_Next_And_Previous_Program"));
|
goToPreviousProgramAction.setHelpLocation(
|
||||||
|
new HelpLocation("ProgramManagerPlugin", "Go_To_Next_And_Previous_Program"));
|
||||||
|
|
||||||
// this timer is to give the user time to select successive programs before activating one
|
// this timer is to give the user time to select successive programs before activating one
|
||||||
selectHighlightedProgramTimer = new Timer(750, new ActionListener() {
|
selectHighlightedProgramTimer = new Timer(750, e -> selectHighlightedProgram());
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
selectHighlightedProgram();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
selectHighlightedProgramTimer.setRepeats(false);
|
selectHighlightedProgramTimer.setRepeats(false);
|
||||||
|
|
||||||
goToLastActiveProgramAction = new DockingAction("Go To Last Active Program", getName()) {
|
goToLastActiveProgramAction = new DockingAction("Go To Last Active Program", getName()) {
|
||||||
|
@ -144,14 +143,16 @@ public class MultiTabPlugin extends Plugin implements DomainObjectListener {
|
||||||
switchToProgram(lastActiveProgram);
|
switchToProgram(lastActiveProgram);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
goToLastActiveProgramAction.setMenuBarData(new MenuData(new String[] { "Navigation",
|
goToLastActiveProgramAction.setMenuBarData(new MenuData(
|
||||||
"Go To Last Active Program" }, null, "GoToProgram", MenuData.NO_MNEMONIC, secondGroup));
|
new String[] { ToolConstants.MENU_NAVIGATION, "Go To Last Active Program" }, null,
|
||||||
goToLastActiveProgramAction.setKeyBindingData(new KeyBindingData(KeyEvent.VK_F6,
|
ToolConstants.MENU_NAVIGATION_GROUP_WINDOWS, MenuData.NO_MNEMONIC, secondGroup));
|
||||||
InputEvent.CTRL_DOWN_MASK));
|
goToLastActiveProgramAction.setKeyBindingData(
|
||||||
|
new KeyBindingData(KeyEvent.VK_F6, InputEvent.CTRL_DOWN_MASK));
|
||||||
goToLastActiveProgramAction.setEnabled(false);
|
goToLastActiveProgramAction.setEnabled(false);
|
||||||
goToLastActiveProgramAction.setDescription("Activates the last program used before the current program");
|
goToLastActiveProgramAction.setDescription(
|
||||||
goToLastActiveProgramAction.setHelpLocation(new HelpLocation("ProgramManagerPlugin",
|
"Activates the last program used before the current program");
|
||||||
"Go_To_Last_Active_Program"));
|
goToLastActiveProgramAction.setHelpLocation(
|
||||||
|
new HelpLocation("ProgramManagerPlugin", "Go_To_Last_Active_Program"));
|
||||||
|
|
||||||
tool.addAction(goToProgramAction);
|
tool.addAction(goToProgramAction);
|
||||||
tool.addAction(goToLastActiveProgramAction);
|
tool.addAction(goToLastActiveProgramAction);
|
||||||
|
|
|
@ -64,8 +64,10 @@ public class RegisterManagerProvider extends ComponentProviderAdapter {
|
||||||
RegisterManagerProvider(PluginTool tool, String owner) {
|
RegisterManagerProvider(PluginTool tool, String owner) {
|
||||||
super(tool, "Register Manager", owner, ProgramActionContext.class);
|
super(tool, "Register Manager", owner, ProgramActionContext.class);
|
||||||
buildComponent();
|
buildComponent();
|
||||||
setHelpLocation(new HelpLocation("RegisterPlugin", "RegisterManager"));
|
|
||||||
|
setHelpLocation(new HelpLocation("RegisterPlugin", "Register_Manager"));
|
||||||
setIcon(REGISTER_ICON);
|
setIcon(REGISTER_ICON);
|
||||||
|
addToToolbar();
|
||||||
setDefaultWindowPosition(WindowPosition.WINDOW);
|
setDefaultWindowPosition(WindowPosition.WINDOW);
|
||||||
|
|
||||||
updateMgr = new SwingUpdateManager(500, () -> update());
|
updateMgr = new SwingUpdateManager(500, () -> update());
|
||||||
|
|
|
@ -43,7 +43,6 @@ import ghidra.program.model.listing.*;
|
||||||
import ghidra.program.util.*;
|
import ghidra.program.util.*;
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import resources.ResourceManager;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows the registers available in a program along with any values that are set.
|
* Shows the registers available in a program along with any values that are set.
|
||||||
|
@ -63,7 +62,6 @@ public class RegisterPlugin extends ProgramPlugin {
|
||||||
private RegisterManagerProvider registerMgrProvider;
|
private RegisterManagerProvider registerMgrProvider;
|
||||||
private Register[] registers = new Register[0];
|
private Register[] registers = new Register[0];
|
||||||
|
|
||||||
private DockingAction showRegistersAction;
|
|
||||||
private DockingAction deleteRegisterRangeAction;
|
private DockingAction deleteRegisterRangeAction;
|
||||||
private DockingAction deleteRegisterAtFunctionAction;
|
private DockingAction deleteRegisterAtFunctionAction;
|
||||||
private DockingAction clearRegisterAction;
|
private DockingAction clearRegisterAction;
|
||||||
|
@ -94,21 +92,6 @@ public class RegisterPlugin extends ProgramPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createActions() {
|
private void createActions() {
|
||||||
showRegistersAction = new DockingAction("Display Register Values", getName()) {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionContext context) {
|
|
||||||
tool.showComponentProvider(registerMgrProvider, true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
showRegistersAction.setToolBarData(new ToolBarData(
|
|
||||||
ResourceManager.loadImage("images/registerGroup.png"), "View"));
|
|
||||||
showRegistersAction.setKeyBindingData(new KeyBindingData(KeyEvent.VK_V, 0));
|
|
||||||
|
|
||||||
showRegistersAction.setDescription("Display Register Values");
|
|
||||||
showRegistersAction.setHelpLocation(new HelpLocation("RegisterPlugin", "RegisterManager"));
|
|
||||||
showRegistersAction.setEnabled(true);
|
|
||||||
|
|
||||||
tool.addAction(showRegistersAction);
|
|
||||||
|
|
||||||
setRegisterAction = new DockingAction("Set Register Values", getName()) {
|
setRegisterAction = new DockingAction("Set Register Values", getName()) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -125,10 +108,10 @@ public class RegisterPlugin extends ProgramPlugin {
|
||||||
(contextObject instanceof RegisterManagerProvider);
|
(contextObject instanceof RegisterManagerProvider);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
setRegisterAction.setPopupMenuData(new MenuData(new String[] { "Set Register Values..." },
|
setRegisterAction.setPopupMenuData(
|
||||||
null, "Registers"));
|
new MenuData(new String[] { "Set Register Values..." }, null, "Registers"));
|
||||||
setRegisterAction.setKeyBindingData(new KeyBindingData(KeyEvent.VK_R,
|
setRegisterAction.setKeyBindingData(
|
||||||
InputEvent.CTRL_DOWN_MASK));
|
new KeyBindingData(KeyEvent.VK_R, InputEvent.CTRL_DOWN_MASK));
|
||||||
|
|
||||||
setRegisterAction.setDescription("Set register values in a program.");
|
setRegisterAction.setDescription("Set register values in a program.");
|
||||||
setRegisterAction.setHelpLocation(new HelpLocation("RegisterPlugin", "SetRegisterValues"));
|
setRegisterAction.setHelpLocation(new HelpLocation("RegisterPlugin", "SetRegisterValues"));
|
||||||
|
@ -151,12 +134,12 @@ public class RegisterPlugin extends ProgramPlugin {
|
||||||
(contextObject instanceof RegisterManagerProvider);
|
(contextObject instanceof RegisterManagerProvider);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
clearRegisterAction.setPopupMenuData(new MenuData(
|
clearRegisterAction.setPopupMenuData(
|
||||||
new String[] { "Clear Register Values..." }, null, "Registers"));
|
new MenuData(new String[] { "Clear Register Values..." }, null, "Registers"));
|
||||||
|
|
||||||
clearRegisterAction.setDescription("Clear register values in a program.");
|
clearRegisterAction.setDescription("Clear register values in a program.");
|
||||||
clearRegisterAction.setHelpLocation(new HelpLocation("RegisterPlugin",
|
clearRegisterAction.setHelpLocation(
|
||||||
"ClearRegisterValues"));
|
new HelpLocation("RegisterPlugin", "ClearRegisterValues"));
|
||||||
clearRegisterAction.setEnabled(true);
|
clearRegisterAction.setEnabled(true);
|
||||||
|
|
||||||
tool.addAction(clearRegisterAction);
|
tool.addAction(clearRegisterAction);
|
||||||
|
@ -193,8 +176,8 @@ public class RegisterPlugin extends ProgramPlugin {
|
||||||
deleteRegisterRangeAction.setKeyBindingData(new KeyBindingData(KeyEvent.VK_DELETE, 0));
|
deleteRegisterRangeAction.setKeyBindingData(new KeyBindingData(KeyEvent.VK_DELETE, 0));
|
||||||
|
|
||||||
deleteRegisterRangeAction.setDescription("Delete register value at Function.");
|
deleteRegisterRangeAction.setDescription("Delete register value at Function.");
|
||||||
deleteRegisterRangeAction.setHelpLocation(new HelpLocation("RegisterPlugin",
|
deleteRegisterRangeAction.setHelpLocation(
|
||||||
"DeleteRegisterValueRange"));
|
new HelpLocation("RegisterPlugin", "DeleteRegisterValueRange"));
|
||||||
deleteRegisterRangeAction.setEnabled(true);
|
deleteRegisterRangeAction.setEnabled(true);
|
||||||
|
|
||||||
tool.addAction(deleteRegisterRangeAction);
|
tool.addAction(deleteRegisterRangeAction);
|
||||||
|
@ -222,13 +205,13 @@ public class RegisterPlugin extends ProgramPlugin {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
deleteRegisterAtFunctionAction.setPopupMenuData(new MenuData(
|
deleteRegisterAtFunctionAction.setPopupMenuData(
|
||||||
new String[] { "Delete Register Value Range..." }, null, "Registers"));
|
new MenuData(new String[] { "Delete Register Value Range..." }, null, "Registers"));
|
||||||
deleteRegisterAtFunctionAction.setKeyBindingData(new KeyBindingData(KeyEvent.VK_DELETE, 0));
|
deleteRegisterAtFunctionAction.setKeyBindingData(new KeyBindingData(KeyEvent.VK_DELETE, 0));
|
||||||
|
|
||||||
deleteRegisterAtFunctionAction.setDescription("Delete register value range.");
|
deleteRegisterAtFunctionAction.setDescription("Delete register value range.");
|
||||||
deleteRegisterAtFunctionAction.setHelpLocation(new HelpLocation("RegisterPlugin",
|
deleteRegisterAtFunctionAction.setHelpLocation(
|
||||||
"DeleteRegisterValueRange"));
|
new HelpLocation("RegisterPlugin", "DeleteRegisterValueRange"));
|
||||||
deleteRegisterAtFunctionAction.setEnabled(true);
|
deleteRegisterAtFunctionAction.setEnabled(true);
|
||||||
|
|
||||||
tool.addAction(deleteRegisterAtFunctionAction);
|
tool.addAction(deleteRegisterAtFunctionAction);
|
||||||
|
@ -254,8 +237,8 @@ public class RegisterPlugin extends ProgramPlugin {
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
AddressRange range = it.next();
|
AddressRange range = it.next();
|
||||||
if (range.contains(addr)) {
|
if (range.contains(addr)) {
|
||||||
Command cmd =
|
Command cmd = new SetRegisterCmd(register, range.getMinAddress(),
|
||||||
new SetRegisterCmd(register, range.getMinAddress(), range.getMaxAddress(), null);
|
range.getMaxAddress(), null);
|
||||||
if (!tool.execute(cmd, context.getProgram())) {
|
if (!tool.execute(cmd, context.getProgram())) {
|
||||||
Msg.showError(this, tool.getToolFrame(), "Register Context Error",
|
Msg.showError(this, tool.getToolFrame(), "Register Context Error",
|
||||||
cmd.getStatusMsg());
|
cmd.getStatusMsg());
|
||||||
|
@ -356,7 +339,7 @@ public class RegisterPlugin extends ProgramPlugin {
|
||||||
@Override
|
@Override
|
||||||
protected void programActivated(Program program) {
|
protected void programActivated(Program program) {
|
||||||
registerMgrProvider.setProgram(program);
|
registerMgrProvider.setProgram(program);
|
||||||
ArrayList<Register> list = new ArrayList<Register>();
|
ArrayList<Register> list = new ArrayList<>();
|
||||||
for (Register reg : program.getProgramContext().getRegisters()) {
|
for (Register reg : program.getProgramContext().getRegisters()) {
|
||||||
if (!reg.isHidden()) {
|
if (!reg.isHidden()) {
|
||||||
list.add(reg);
|
list.add(reg);
|
||||||
|
@ -442,7 +425,8 @@ public class RegisterPlugin extends ProgramPlugin {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<?>[] getSupportedProgramLocations() {
|
public Class<?>[] getSupportedProgramLocations() {
|
||||||
return new Class[] { RegisterTransitionFieldLocation.class, RegisterFieldLocation.class };
|
return new Class[] { RegisterTransitionFieldLocation.class,
|
||||||
|
RegisterFieldLocation.class };
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,24 +15,19 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.reloc;
|
package ghidra.app.plugin.core.reloc;
|
||||||
|
|
||||||
import javax.swing.ImageIcon;
|
import docking.action.DockingAction;
|
||||||
|
|
||||||
import docking.ActionContext;
|
|
||||||
import docking.action.*;
|
|
||||||
import ghidra.app.CorePluginPackage;
|
import ghidra.app.CorePluginPackage;
|
||||||
import ghidra.app.events.*;
|
import ghidra.app.events.*;
|
||||||
import ghidra.app.plugin.PluginCategoryNames;
|
import ghidra.app.plugin.PluginCategoryNames;
|
||||||
import ghidra.app.services.GoToService;
|
import ghidra.app.services.GoToService;
|
||||||
import ghidra.app.util.HelpTopics;
|
|
||||||
import ghidra.framework.model.*;
|
import ghidra.framework.model.*;
|
||||||
import ghidra.framework.plugintool.*;
|
import ghidra.framework.plugintool.*;
|
||||||
import ghidra.framework.plugintool.util.PluginStatus;
|
import ghidra.framework.plugintool.util.PluginStatus;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.util.ChangeManager;
|
import ghidra.program.util.ChangeManager;
|
||||||
import ghidra.program.util.ProgramSelection;
|
import ghidra.program.util.ProgramSelection;
|
||||||
import ghidra.util.HelpLocation;
|
|
||||||
import ghidra.util.table.SelectionNavigationAction;
|
import ghidra.util.table.SelectionNavigationAction;
|
||||||
import resources.ResourceManager;
|
import ghidra.util.table.actions.MakeProgramSelectionAction;
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
@PluginInfo(
|
@PluginInfo(
|
||||||
|
@ -66,27 +61,15 @@ public class RelocationTablePlugin extends Plugin implements DomainObjectListene
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createActions() {
|
private void createActions() {
|
||||||
DockingAction programSelectionAction =
|
|
||||||
new DockingAction("Make Selection", getName(), false) {
|
DockingAction selectAction = new MakeProgramSelectionAction(this, provider.getTable());
|
||||||
@Override
|
tool.addLocalAction(provider, selectAction);
|
||||||
public void actionPerformed(ActionContext context) {
|
|
||||||
makeSelection();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
programSelectionAction.setDescription("Make a selection using selected rows");
|
|
||||||
ImageIcon icon = ResourceManager.loadImage("images/text_align_justify.png");
|
|
||||||
programSelectionAction.setToolBarData(new ToolBarData(icon));
|
|
||||||
programSelectionAction.setPopupMenuData(
|
|
||||||
new MenuData(new String[] { "Make Selection" }, icon));
|
|
||||||
programSelectionAction.setHelpLocation(
|
|
||||||
new HelpLocation(HelpTopics.SEARCH, "Make_Selection"));
|
|
||||||
tool.addLocalAction(provider, programSelectionAction);
|
|
||||||
|
|
||||||
DockingAction navigationAction = new SelectionNavigationAction(this, provider.getTable());
|
DockingAction navigationAction = new SelectionNavigationAction(this, provider.getTable());
|
||||||
tool.addLocalAction(provider, navigationAction);
|
tool.addLocalAction(provider, navigationAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void makeSelection() {
|
private void doMakeSelection() {
|
||||||
ProgramSelection selection = provider.getTable().getProgramSelection();
|
ProgramSelection selection = provider.getTable().getProgramSelection();
|
||||||
PluginEvent event = new ProgramSelectionPluginEvent(getName(), selection, currentProgram);
|
PluginEvent event = new ProgramSelectionPluginEvent(getName(), selection, currentProgram);
|
||||||
firePluginEvent(event);
|
firePluginEvent(event);
|
||||||
|
|
|
@ -23,7 +23,6 @@ import javax.swing.*;
|
||||||
import javax.swing.border.Border;
|
import javax.swing.border.Border;
|
||||||
|
|
||||||
import docking.*;
|
import docking.*;
|
||||||
import docking.action.DockingAction;
|
|
||||||
import docking.help.HelpService;
|
import docking.help.HelpService;
|
||||||
import docking.widgets.label.GLabel;
|
import docking.widgets.label.GLabel;
|
||||||
import docking.widgets.table.GTableFilterPanel;
|
import docking.widgets.table.GTableFilterPanel;
|
||||||
|
@ -62,8 +61,6 @@ public class ScalarSearchProvider extends ComponentProviderAdapter {
|
||||||
private GhidraTable scalarTable;
|
private GhidraTable scalarTable;
|
||||||
private ScalarSearchModel scalarModel;
|
private ScalarSearchModel scalarModel;
|
||||||
|
|
||||||
private DockingAction selectAction;
|
|
||||||
|
|
||||||
private ProgramSelection currentSelection;
|
private ProgramSelection currentSelection;
|
||||||
private Program program;
|
private Program program;
|
||||||
private String primarySubTitle;
|
private String primarySubTitle;
|
||||||
|
@ -258,21 +255,11 @@ public class ScalarSearchProvider extends ComponentProviderAdapter {
|
||||||
|
|
||||||
private void createActions() {
|
private void createActions() {
|
||||||
|
|
||||||
selectAction = new MakeProgramSelectionAction(getName(), getTable()) {
|
tool.addLocalAction(this, new MakeProgramSelectionAction(plugin, scalarTable));
|
||||||
@Override
|
tool.addLocalAction(this, new SelectionNavigationAction(plugin, getTable()));
|
||||||
protected void makeSelection(ActionContext context) {
|
|
||||||
selectDataInProgramFromTable(getSelection());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
tool.addLocalAction(this, selectAction);
|
|
||||||
|
|
||||||
DockingAction selectionAction = new SelectionNavigationAction(plugin, getTable());
|
|
||||||
tool.addLocalAction(this, selectionAction);
|
|
||||||
|
|
||||||
GhidraTable table = threadedTablePanel.getTable();
|
GhidraTable table = threadedTablePanel.getTable();
|
||||||
DockingAction removeItemsAction = new DeleteTableRowAction(table, plugin.getName());
|
tool.addLocalAction(this, new DeleteTableRowAction(table, plugin.getName()));
|
||||||
tool.addLocalAction(this, removeItemsAction);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
|
|
|
@ -26,8 +26,10 @@ import java.util.zip.ZipFile;
|
||||||
|
|
||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
|
|
||||||
import docking.*;
|
import docking.ActionContext;
|
||||||
|
import docking.DockingUtils;
|
||||||
import docking.action.*;
|
import docking.action.*;
|
||||||
|
import docking.actions.KeyBindingUtils;
|
||||||
import docking.widgets.table.GTable;
|
import docking.widgets.table.GTable;
|
||||||
import generic.jar.ResourceFile;
|
import generic.jar.ResourceFile;
|
||||||
import ghidra.app.script.GhidraScriptUtil;
|
import ghidra.app.script.GhidraScriptUtil;
|
||||||
|
@ -92,7 +94,7 @@ class GhidraScriptActionManager {
|
||||||
action.setKeyBindingData(null);
|
action.setKeyBindingData(null);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
KeyStroke stroke = DockingKeyBindingAction.parseKeyStroke(strokeStr);
|
KeyStroke stroke = KeyBindingUtils.parseKeyStroke(strokeStr);
|
||||||
if (stroke == null) {
|
if (stroke == null) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -137,7 +139,7 @@ class GhidraScriptActionManager {
|
||||||
saveState.putString(scriptFile.getName(), "");
|
saveState.putString(scriptFile.getName(), "");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
String strokeStr = DockingKeyBindingAction.parseKeyStroke(stroke);
|
String strokeStr = KeyBindingUtils.parseKeyStroke(stroke);
|
||||||
saveState.putString(scriptFile.getName(), strokeStr);
|
saveState.putString(scriptFile.getName(), strokeStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -464,7 +466,6 @@ class GhidraScriptActionManager {
|
||||||
if (action == null) {
|
if (action == null) {
|
||||||
action = new ScriptAction(plugin, script);
|
action = new ScriptAction(plugin, script);
|
||||||
actionMap.put(script, action);
|
actionMap.put(script, action);
|
||||||
plugin.getTool().addAction(action);
|
|
||||||
}
|
}
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
@ -628,13 +629,11 @@ class GhidraScriptActionManager {
|
||||||
private class RerunLastScriptAction extends DockingAction {
|
private class RerunLastScriptAction extends DockingAction {
|
||||||
|
|
||||||
RerunLastScriptAction(String toolbarGroup) {
|
RerunLastScriptAction(String toolbarGroup) {
|
||||||
super(RERUN_LAST_SHARED_ACTION_NAME, plugin.getName(), false);
|
super(RERUN_LAST_SHARED_ACTION_NAME, plugin.getName(), KeyBindingType.SHARED);
|
||||||
|
|
||||||
setToolBarData(
|
setToolBarData(
|
||||||
new ToolBarData(ResourceManager.loadImage("images/play_again.png"), toolbarGroup));
|
new ToolBarData(ResourceManager.loadImage("images/play_again.png"), toolbarGroup));
|
||||||
setDescription("Rerun the last run script");
|
setDescription("Rerun the last run script");
|
||||||
setEnabled(false);
|
|
||||||
|
|
||||||
setHelpLocation(new HelpLocation(plugin.getName(), "Run_Last"));
|
setHelpLocation(new HelpLocation(plugin.getName(), "Run_Last"));
|
||||||
|
|
||||||
initKeyStroke(RERUN_LAST_SCRIPT_KEYSTROKE);
|
initKeyStroke(RERUN_LAST_SCRIPT_KEYSTROKE);
|
||||||
|
@ -648,11 +647,6 @@ class GhidraScriptActionManager {
|
||||||
setKeyBindingData(new KeyBindingData(keyStroke));
|
setKeyBindingData(new KeyBindingData(keyStroke));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean usesSharedKeyBinding() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionContext context) {
|
public void actionPerformed(ActionContext context) {
|
||||||
provider.runLastScript();
|
provider.runLastScript();
|
||||||
|
|
|
@ -103,6 +103,7 @@ public class GhidraScriptComponentProvider extends ComponentProviderAdapter {
|
||||||
|
|
||||||
setHelpLocation(new HelpLocation(plugin.getName(), plugin.getName()));
|
setHelpLocation(new HelpLocation(plugin.getName(), plugin.getName()));
|
||||||
setIcon(ResourceManager.loadImage("images/play.png"));
|
setIcon(ResourceManager.loadImage("images/play.png"));
|
||||||
|
addToToolbar();
|
||||||
setWindowGroup(WINDOW_GROUP);
|
setWindowGroup(WINDOW_GROUP);
|
||||||
|
|
||||||
build();
|
build();
|
||||||
|
|
|
@ -19,9 +19,6 @@ import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
|
||||||
import docking.ActionContext;
|
|
||||||
import docking.action.DockingAction;
|
|
||||||
import docking.action.ToolBarData;
|
|
||||||
import generic.jar.ResourceFile;
|
import generic.jar.ResourceFile;
|
||||||
import ghidra.app.CorePluginPackage;
|
import ghidra.app.CorePluginPackage;
|
||||||
import ghidra.app.plugin.PluginCategoryNames;
|
import ghidra.app.plugin.PluginCategoryNames;
|
||||||
|
@ -36,9 +33,7 @@ import ghidra.framework.plugintool.PluginInfo;
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
import ghidra.framework.plugintool.util.PluginStatus;
|
import ghidra.framework.plugintool.util.PluginStatus;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.util.HelpLocation;
|
|
||||||
import ghidra.util.task.TaskListener;
|
import ghidra.util.task.TaskListener;
|
||||||
import resources.ResourceManager;
|
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
@PluginInfo(
|
@PluginInfo(
|
||||||
|
@ -54,7 +49,6 @@ import resources.ResourceManager;
|
||||||
public class GhidraScriptMgrPlugin extends ProgramPlugin implements GhidraScriptService {
|
public class GhidraScriptMgrPlugin extends ProgramPlugin implements GhidraScriptService {
|
||||||
|
|
||||||
private GhidraScriptComponentProvider provider;
|
private GhidraScriptComponentProvider provider;
|
||||||
private DockingAction action;
|
|
||||||
|
|
||||||
public GhidraScriptMgrPlugin(PluginTool tool) {
|
public GhidraScriptMgrPlugin(PluginTool tool) {
|
||||||
super(tool, true, true, true);
|
super(tool, true, true, true);
|
||||||
|
@ -62,31 +56,9 @@ public class GhidraScriptMgrPlugin extends ProgramPlugin implements GhidraScript
|
||||||
provider = new GhidraScriptComponentProvider(this);
|
provider = new GhidraScriptComponentProvider(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void init() {
|
|
||||||
super.init();
|
|
||||||
|
|
||||||
action = new DockingAction("Display Script Manager", getName()) {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionContext context) {
|
|
||||||
tool.showComponentProvider(provider, true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// ACTIONS - auto generated
|
|
||||||
action.setToolBarData(
|
|
||||||
new ToolBarData(ResourceManager.loadImage("images/play.png"), "View"));
|
|
||||||
|
|
||||||
action.setEnabled(true);
|
|
||||||
action.setHelpLocation(new HelpLocation(getName(), "Script_Manager"));
|
|
||||||
tool.addAction(action);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void dispose() {
|
protected void dispose() {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
action.dispose();
|
|
||||||
provider.dispose();
|
provider.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ package ghidra.app.plugin.core.script;
|
||||||
|
|
||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
|
|
||||||
import docking.DockingKeyBindingAction;
|
import docking.actions.KeyBindingUtils;
|
||||||
|
|
||||||
class KeyBindingsInfo implements Comparable<KeyBindingsInfo> {
|
class KeyBindingsInfo implements Comparable<KeyBindingsInfo> {
|
||||||
boolean hasAction;
|
boolean hasAction;
|
||||||
|
@ -31,7 +31,7 @@ class KeyBindingsInfo implements Comparable<KeyBindingsInfo> {
|
||||||
|
|
||||||
KeyBindingsInfo(boolean hasAction, KeyStroke stroke) {
|
KeyBindingsInfo(boolean hasAction, KeyStroke stroke) {
|
||||||
this.hasAction = hasAction;
|
this.hasAction = hasAction;
|
||||||
this.keystroke = stroke == null ? "" : DockingKeyBindingAction.parseKeyStroke(stroke);
|
this.keystroke = stroke == null ? "" : KeyBindingUtils.parseKeyStroke(stroke);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -21,7 +21,9 @@ import ghidra.docking.settings.Settings;
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
import ghidra.framework.plugintool.ServiceProvider;
|
import ghidra.framework.plugintool.ServiceProvider;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
|
import ghidra.program.model.address.AddressSet;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
|
import ghidra.program.util.ProgramSelection;
|
||||||
import ghidra.program.util.string.FoundString;
|
import ghidra.program.util.string.FoundString;
|
||||||
import ghidra.util.datastruct.Accumulator;
|
import ghidra.util.datastruct.Accumulator;
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
|
@ -46,6 +48,20 @@ public class StringTableModel extends AddressBasedTableModel<FoundString> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProgramSelection getProgramSelection(int[] rows) {
|
||||||
|
|
||||||
|
AddressSet addressSet = new AddressSet();
|
||||||
|
for (int row : rows) {
|
||||||
|
FoundString foundString = getRowObject(row);
|
||||||
|
Address addr = foundString.getAddress();
|
||||||
|
if (addr != null) {
|
||||||
|
addressSet.addRange(addr, addr.add(foundString.getLength() - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new ProgramSelection(addressSet);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Address getAddress(int row) {
|
public Address getAddress(int row) {
|
||||||
FoundString stringData = getRowObject(row);
|
FoundString stringData = getRowObject(row);
|
||||||
|
|
|
@ -28,7 +28,8 @@ import ghidra.app.services.GoToService;
|
||||||
import ghidra.app.util.HelpTopics;
|
import ghidra.app.util.HelpTopics;
|
||||||
import ghidra.framework.plugintool.PluginInfo;
|
import ghidra.framework.plugintool.PluginInfo;
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
import ghidra.framework.plugintool.util.*;
|
import ghidra.framework.plugintool.util.PluginStatus;
|
||||||
|
import ghidra.framework.plugintool.util.ToolConstants;
|
||||||
import ghidra.program.model.address.*;
|
import ghidra.program.model.address.*;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.util.ProgramSelection;
|
import ghidra.program.util.ProgramSelection;
|
||||||
|
@ -99,8 +100,7 @@ public class StringTablePlugin extends ProgramPlugin {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
ArrayList<StringTableProvider> list =
|
ArrayList<StringTableProvider> list = new ArrayList<>(transientProviders);
|
||||||
new ArrayList<>(transientProviders);
|
|
||||||
|
|
||||||
for (StringTableProvider stringTableProvider : list) {
|
for (StringTableProvider stringTableProvider : list) {
|
||||||
stringTableProvider.closeComponent();
|
stringTableProvider.closeComponent();
|
||||||
|
@ -114,8 +114,7 @@ public class StringTablePlugin extends ProgramPlugin {
|
||||||
if (transientProviders.isEmpty()) {
|
if (transientProviders.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ArrayList<StringTableProvider> list =
|
ArrayList<StringTableProvider> list = new ArrayList<>(transientProviders);
|
||||||
new ArrayList<>(transientProviders);
|
|
||||||
for (StringTableProvider stringTableProvider : list) {
|
for (StringTableProvider stringTableProvider : list) {
|
||||||
stringTableProvider.programClosed(program);
|
stringTableProvider.programClosed(program);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,15 +30,12 @@ import docking.widgets.label.GLabel;
|
||||||
import docking.widgets.table.*;
|
import docking.widgets.table.*;
|
||||||
import docking.widgets.table.threaded.ThreadedTableModel;
|
import docking.widgets.table.threaded.ThreadedTableModel;
|
||||||
import docking.widgets.textfield.IntegerTextField;
|
import docking.widgets.textfield.IntegerTextField;
|
||||||
import ghidra.app.events.ProgramSelectionPluginEvent;
|
|
||||||
import ghidra.app.services.GoToService;
|
import ghidra.app.services.GoToService;
|
||||||
import ghidra.app.util.HelpTopics;
|
import ghidra.app.util.HelpTopics;
|
||||||
import ghidra.docking.settings.SettingsImpl;
|
import ghidra.docking.settings.SettingsImpl;
|
||||||
import ghidra.framework.model.DomainObjectChangedEvent;
|
import ghidra.framework.model.DomainObjectChangedEvent;
|
||||||
import ghidra.framework.model.DomainObjectListener;
|
import ghidra.framework.model.DomainObjectListener;
|
||||||
import ghidra.framework.plugintool.ComponentProviderAdapter;
|
import ghidra.framework.plugintool.ComponentProviderAdapter;
|
||||||
import ghidra.program.model.address.Address;
|
|
||||||
import ghidra.program.model.address.AddressSet;
|
|
||||||
import ghidra.program.model.data.StringDataInstance;
|
import ghidra.program.model.data.StringDataInstance;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.model.mem.DumbMemBufferImpl;
|
import ghidra.program.model.mem.DumbMemBufferImpl;
|
||||||
|
@ -50,6 +47,7 @@ import ghidra.util.*;
|
||||||
import ghidra.util.exception.AssertException;
|
import ghidra.util.exception.AssertException;
|
||||||
import ghidra.util.layout.VerticalLayout;
|
import ghidra.util.layout.VerticalLayout;
|
||||||
import ghidra.util.table.*;
|
import ghidra.util.table.*;
|
||||||
|
import ghidra.util.table.actions.MakeProgramSelectionAction;
|
||||||
import ghidra.util.task.TaskLauncher;
|
import ghidra.util.task.TaskLauncher;
|
||||||
import resources.ResourceManager;
|
import resources.ResourceManager;
|
||||||
|
|
||||||
|
@ -304,19 +302,18 @@ public class StringTableProvider extends ComponentProviderAdapter implements Dom
|
||||||
makeCharArrayAction.setHelpLocation(makeStringHelp);
|
makeCharArrayAction.setHelpLocation(makeStringHelp);
|
||||||
addLocalAction(makeCharArrayAction);
|
addLocalAction(makeCharArrayAction);
|
||||||
|
|
||||||
DockingAction selectAction =
|
DockingAction selectAction = new MakeProgramSelectionAction(plugin, table) {
|
||||||
new DockingAction("Make Selection", "AsciiFinderDialog", false) {
|
@Override
|
||||||
@Override
|
protected ProgramSelection makeSelection(ActionContext context) {
|
||||||
public void actionPerformed(ActionContext context) {
|
ProgramSelection selection = super.makeSelection(context);
|
||||||
makeSelection();
|
|
||||||
}
|
// Also make sure this plugin keeps track of the new selection, since it will
|
||||||
};
|
// not receive this new event.
|
||||||
selectAction.setDescription("Make a selection using selected rows");
|
// TODO this should not be necessary; old code perhaps?
|
||||||
selectAction.setEnabled(true);
|
plugin.setSelection(selection);
|
||||||
Icon icon = ResourceManager.loadImage("images/text_align_justify.png");
|
return selection;
|
||||||
selectAction.setToolBarData(new ToolBarData(icon));
|
}
|
||||||
selectAction.setPopupMenuData(new MenuData(new String[] { "Make Selection" }, icon));
|
};
|
||||||
selectAction.setHelpLocation(new HelpLocation(HelpTopics.SEARCH, "Make_Selection_Strings"));
|
|
||||||
|
|
||||||
selectionNavigationAction = new SelectionNavigationAction(plugin, table);
|
selectionNavigationAction = new SelectionNavigationAction(plugin, table);
|
||||||
selectionNavigationAction.setHelpLocation(
|
selectionNavigationAction.setHelpLocation(
|
||||||
|
@ -327,37 +324,6 @@ public class StringTableProvider extends ComponentProviderAdapter implements Dom
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void makeSelection() {
|
|
||||||
AddressSet set = new AddressSet();
|
|
||||||
|
|
||||||
addToAddressSet(set, table.getSelectedRows());
|
|
||||||
|
|
||||||
if (!set.isEmpty()) {
|
|
||||||
|
|
||||||
ProgramSelection ps = new ProgramSelection(set);
|
|
||||||
|
|
||||||
// This event is given this specific source name because AsciiFinderPlugin
|
|
||||||
// is looking for it, so it can circumvent
|
|
||||||
// some unwanted behavior. See AsciiFinderPlugin.firePluginEvent for details.
|
|
||||||
plugin.firePluginEvent(new ProgramSelectionPluginEvent(
|
|
||||||
"AsciiFinderDialogFiredSelection", ps, currentProgram));
|
|
||||||
|
|
||||||
// Also make sure this plugin keeps track of the new selection, since it will
|
|
||||||
// not receive this new event.
|
|
||||||
plugin.setSelection(ps);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void addToAddressSet(AddressSet modifiableSet, int[] rows) {
|
|
||||||
for (int rowValue : rows) {
|
|
||||||
FoundString foundString = stringModel.getRowObject(rowValue);
|
|
||||||
Address addr = foundString.getAddress();
|
|
||||||
if (addr != null) {
|
|
||||||
modifiableSet.addRange(addr, addr.add(foundString.getLength() - 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private JPanel createMainPanel() {
|
private JPanel createMainPanel() {
|
||||||
JPanel panel = new JPanel(new BorderLayout());
|
JPanel panel = new JPanel(new BorderLayout());
|
||||||
panel.add(buildTablePanel(), BorderLayout.CENTER);
|
panel.add(buildTablePanel(), BorderLayout.CENTER);
|
||||||
|
|
|
@ -82,7 +82,7 @@ public class ViewStringsPlugin extends ProgramPlugin implements DomainObjectList
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createActions() {
|
private void createActions() {
|
||||||
DockingAction refreshAction = new DockingAction("Refresh Strings", getName(), false) {
|
DockingAction refreshAction = new DockingAction("Refresh Strings", getName()) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabledForContext(ActionContext context) {
|
public boolean isEnabledForContext(ActionContext context) {
|
||||||
|
@ -100,20 +100,12 @@ public class ViewStringsPlugin extends ProgramPlugin implements DomainObjectList
|
||||||
refreshAction.setHelpLocation(new HelpLocation("ViewStringsPlugin", "Refresh"));
|
refreshAction.setHelpLocation(new HelpLocation("ViewStringsPlugin", "Refresh"));
|
||||||
tool.addLocalAction(provider, refreshAction);
|
tool.addLocalAction(provider, refreshAction);
|
||||||
|
|
||||||
selectAction = new MakeProgramSelectionAction(getName(), provider.getTable()) {
|
tool.addLocalAction(provider, new MakeProgramSelectionAction(this, provider.getTable()));
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void makeSelection(ActionContext context) {
|
|
||||||
selectData(provider.selectData());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
tool.addLocalAction(provider, selectAction);
|
|
||||||
|
|
||||||
linkNavigationAction = new SelectionNavigationAction(this, provider.getTable());
|
linkNavigationAction = new SelectionNavigationAction(this, provider.getTable());
|
||||||
tool.addLocalAction(provider, linkNavigationAction);
|
tool.addLocalAction(provider, linkNavigationAction);
|
||||||
|
|
||||||
showSettingsAction = new DockingAction("Settings...", getName(), false) {
|
showSettingsAction = new DockingAction("Settings", getName()) {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionContext context) {
|
public void actionPerformed(ActionContext context) {
|
||||||
try {
|
try {
|
||||||
|
@ -133,7 +125,7 @@ public class ViewStringsPlugin extends ProgramPlugin implements DomainObjectList
|
||||||
showSettingsAction.setPopupMenuData(new MenuData(new String[] { "Settings..." }, "R"));
|
showSettingsAction.setPopupMenuData(new MenuData(new String[] { "Settings..." }, "R"));
|
||||||
showSettingsAction.setDescription("Shows settings for the selected strings");
|
showSettingsAction.setDescription("Shows settings for the selected strings");
|
||||||
showSettingsAction.setHelpLocation(new HelpLocation("DataPlugin", "Data_Settings"));
|
showSettingsAction.setHelpLocation(new HelpLocation("DataPlugin", "Data_Settings"));
|
||||||
showDefaultSettingsAction = new DockingAction("Default Settings...", getName(), false) {
|
showDefaultSettingsAction = new DockingAction("Default Settings", getName()) {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionContext context) {
|
public void actionPerformed(ActionContext context) {
|
||||||
Data data = provider.getSelectedData();
|
Data data = provider.getSelectedData();
|
||||||
|
|
|
@ -15,11 +15,6 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.symboltree;
|
package ghidra.app.plugin.core.symboltree;
|
||||||
|
|
||||||
import javax.swing.ImageIcon;
|
|
||||||
|
|
||||||
import docking.ActionContext;
|
|
||||||
import docking.action.DockingAction;
|
|
||||||
import docking.action.ToolBarData;
|
|
||||||
import ghidra.app.CorePluginPackage;
|
import ghidra.app.CorePluginPackage;
|
||||||
import ghidra.app.events.*;
|
import ghidra.app.events.*;
|
||||||
import ghidra.app.plugin.PluginCategoryNames;
|
import ghidra.app.plugin.PluginCategoryNames;
|
||||||
|
@ -30,8 +25,6 @@ import ghidra.framework.plugintool.util.PluginStatus;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.model.symbol.*;
|
import ghidra.program.model.symbol.*;
|
||||||
import ghidra.program.util.ProgramLocation;
|
import ghidra.program.util.ProgramLocation;
|
||||||
import ghidra.util.HelpLocation;
|
|
||||||
import resources.ResourceManager;
|
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
@PluginInfo(
|
@PluginInfo(
|
||||||
|
@ -50,17 +43,13 @@ public class SymbolTreePlugin extends Plugin {
|
||||||
|
|
||||||
public static final String PLUGIN_NAME = "SymbolTreePlugin";
|
public static final String PLUGIN_NAME = "SymbolTreePlugin";
|
||||||
|
|
||||||
private DockingAction symTreeAction;
|
|
||||||
private SymbolTreeProvider provider;
|
private SymbolTreeProvider provider;
|
||||||
private Program program;
|
private Program program;
|
||||||
private GoToService goToService;
|
private GoToService goToService;
|
||||||
private boolean processingGoTo;
|
private boolean processingGoTo;
|
||||||
|
|
||||||
final static ImageIcon SYMBOL_TREE_ICON = ResourceManager.loadImage("images/sitemap_color.png");
|
|
||||||
|
|
||||||
public SymbolTreePlugin(PluginTool tool) {
|
public SymbolTreePlugin(PluginTool tool) {
|
||||||
super(tool);
|
super(tool);
|
||||||
createAction();
|
|
||||||
provider = new SymbolTreeProvider(tool, this);
|
provider = new SymbolTreeProvider(tool, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,26 +140,6 @@ public class SymbolTreePlugin extends Plugin {
|
||||||
goToService.goToExternalLocation(extLoc, false);
|
goToService.goToExternalLocation(extLoc, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createAction() {
|
|
||||||
symTreeAction = new DockingAction("Display Symbol Tree", getName()) {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionContext context) {
|
|
||||||
showProvider();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
symTreeAction.setToolBarData(new ToolBarData(SYMBOL_TREE_ICON, "View"));
|
|
||||||
|
|
||||||
symTreeAction.setDescription("Display Symbol Tree");
|
|
||||||
|
|
||||||
symTreeAction.setHelpLocation(new HelpLocation(getName(), "SymbolTree"));
|
|
||||||
|
|
||||||
tool.addAction(symTreeAction);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showProvider() {
|
|
||||||
provider.showComponent(program);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Program getProgram() {
|
public Program getProgram() {
|
||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,9 +45,11 @@ import ghidra.util.*;
|
||||||
import ghidra.util.exception.*;
|
import ghidra.util.exception.*;
|
||||||
import ghidra.util.task.SwingUpdateManager;
|
import ghidra.util.task.SwingUpdateManager;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
import resources.ResourceManager;
|
||||||
|
|
||||||
public class SymbolTreeProvider extends ComponentProviderAdapter {
|
public class SymbolTreeProvider extends ComponentProviderAdapter {
|
||||||
|
|
||||||
|
private static final ImageIcon ICON = ResourceManager.loadImage("images/sitemap_color.png");
|
||||||
private final static String NAME = "Symbol Tree";
|
private final static String NAME = "Symbol Tree";
|
||||||
|
|
||||||
private ClipboardOwner clipboardOwner;
|
private ClipboardOwner clipboardOwner;
|
||||||
|
@ -101,6 +103,9 @@ public class SymbolTreeProvider extends ComponentProviderAdapter {
|
||||||
super(tool, NAME, plugin.getName());
|
super(tool, NAME, plugin.getName());
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
|
|
||||||
|
setIcon(ICON);
|
||||||
|
addToToolbar();
|
||||||
|
|
||||||
domainObjectListener = new SymbolTreeProviderDomainObjectListener();
|
domainObjectListener = new SymbolTreeProviderDomainObjectListener();
|
||||||
|
|
||||||
localClipboard = new Clipboard(NAME);
|
localClipboard = new Clipboard(NAME);
|
||||||
|
@ -231,11 +236,6 @@ public class SymbolTreeProvider extends ComponentProviderAdapter {
|
||||||
setProgram(program);
|
setProgram(program);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ImageIcon getIcon() {
|
|
||||||
return SymbolTreePlugin.SYMBOL_TREE_ICON;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
// Class Methods
|
// Class Methods
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
|
|
|
@ -39,9 +39,6 @@ public class SelectionAction extends SymbolTreeContextAction {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isEnabledForContext(SymbolTreeActionContext context) {
|
protected boolean isEnabledForContext(SymbolTreeActionContext context) {
|
||||||
// if (context.getSymbolCount() == 0) {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
for (Symbol s : context.getSymbols()) {
|
for (Symbol s : context.getSymbols()) {
|
||||||
if (!s.isExternal()) {
|
if (!s.isExternal()) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -18,8 +18,7 @@ package ghidra.app.plugin.core.symboltree.actions;
|
||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
import javax.swing.tree.TreePath;
|
import javax.swing.tree.TreePath;
|
||||||
|
|
||||||
import docking.action.KeyBindingData;
|
import docking.action.*;
|
||||||
import docking.action.MenuData;
|
|
||||||
import ghidra.app.actions.AbstractFindReferencesDataTypeAction;
|
import ghidra.app.actions.AbstractFindReferencesDataTypeAction;
|
||||||
import ghidra.app.nav.Navigatable;
|
import ghidra.app.nav.Navigatable;
|
||||||
import ghidra.app.plugin.core.navigation.locationreferences.LocationReferencesService;
|
import ghidra.app.plugin.core.navigation.locationreferences.LocationReferencesService;
|
||||||
|
@ -57,7 +56,7 @@ public class ShowSymbolReferencesAction extends SymbolTreeContextAction {
|
||||||
};
|
};
|
||||||
|
|
||||||
public ShowSymbolReferencesAction(PluginTool tool, String owner) {
|
public ShowSymbolReferencesAction(PluginTool tool, String owner) {
|
||||||
super(AbstractFindReferencesDataTypeAction.NAME, owner);
|
super(AbstractFindReferencesDataTypeAction.NAME, owner, KeyBindingType.SHARED);
|
||||||
this.tool = tool;
|
this.tool = tool;
|
||||||
|
|
||||||
setPopupMenuData(new MenuData(new String[] { "Show References to" }, "0Middle"));
|
setPopupMenuData(new MenuData(new String[] { "Show References to" }, "0Middle"));
|
||||||
|
@ -76,11 +75,6 @@ public class ShowSymbolReferencesAction extends SymbolTreeContextAction {
|
||||||
setKeyBindingData(new KeyBindingData(keyStroke));
|
setKeyBindingData(new KeyBindingData(keyStroke));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean usesSharedKeyBinding() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void installHelpLocation() {
|
private void installHelpLocation() {
|
||||||
LocationReferencesService locationReferencesService =
|
LocationReferencesService locationReferencesService =
|
||||||
tool.getService(LocationReferencesService.class);
|
tool.getService(LocationReferencesService.class);
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,12 +15,12 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.symboltree.actions;
|
package ghidra.app.plugin.core.symboltree.actions;
|
||||||
|
|
||||||
import ghidra.app.plugin.core.symboltree.SymbolTreeActionContext;
|
|
||||||
|
|
||||||
import javax.swing.tree.TreePath;
|
import javax.swing.tree.TreePath;
|
||||||
|
|
||||||
import docking.ActionContext;
|
import docking.ActionContext;
|
||||||
import docking.action.DockingAction;
|
import docking.action.DockingAction;
|
||||||
|
import docking.action.KeyBindingType;
|
||||||
|
import ghidra.app.plugin.core.symboltree.SymbolTreeActionContext;
|
||||||
|
|
||||||
public abstract class SymbolTreeContextAction extends DockingAction {
|
public abstract class SymbolTreeContextAction extends DockingAction {
|
||||||
|
|
||||||
|
@ -29,6 +28,10 @@ public abstract class SymbolTreeContextAction extends DockingAction {
|
||||||
super(name, owner);
|
super(name, owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SymbolTreeContextAction(String name, String owner, KeyBindingType kbType) {
|
||||||
|
super(name, owner, kbType);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final boolean isEnabledForContext(ActionContext actionContext) {
|
public final boolean isEnabledForContext(ActionContext actionContext) {
|
||||||
if (!(actionContext instanceof SymbolTreeActionContext)) {
|
if (!(actionContext instanceof SymbolTreeActionContext)) {
|
||||||
|
|
|
@ -29,8 +29,12 @@ import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.model.symbol.Symbol;
|
import ghidra.program.model.symbol.Symbol;
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
import ghidra.util.table.GhidraTable;
|
import ghidra.util.table.GhidraTable;
|
||||||
|
import resources.ResourceManager;
|
||||||
|
|
||||||
class ReferenceProvider extends ComponentProviderAdapter {
|
class ReferenceProvider extends ComponentProviderAdapter {
|
||||||
|
|
||||||
|
private static final ImageIcon ICON = ResourceManager.loadImage("images/table_go.png");
|
||||||
|
|
||||||
private SymbolTablePlugin plugin;
|
private SymbolTablePlugin plugin;
|
||||||
private SymbolReferenceModel referenceKeyModel;
|
private SymbolReferenceModel referenceKeyModel;
|
||||||
private ReferencePanel referencePanel;
|
private ReferencePanel referencePanel;
|
||||||
|
@ -39,15 +43,21 @@ class ReferenceProvider extends ComponentProviderAdapter {
|
||||||
ReferenceProvider(SymbolTablePlugin plugin) {
|
ReferenceProvider(SymbolTablePlugin plugin) {
|
||||||
super(plugin.getTool(), "Symbol References", plugin.getName(), ProgramActionContext.class);
|
super(plugin.getTool(), "Symbol References", plugin.getName(), ProgramActionContext.class);
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
|
|
||||||
|
setIcon(ICON);
|
||||||
|
addToToolbar();
|
||||||
setHelpLocation(new HelpLocation(plugin.getName(), "Symbol_References"));
|
setHelpLocation(new HelpLocation(plugin.getName(), "Symbol_References"));
|
||||||
setWindowGroup("symbolTable");
|
setWindowGroup("symbolTable");
|
||||||
setIntraGroupPosition(WindowPosition.RIGHT);
|
setIntraGroupPosition(WindowPosition.RIGHT);
|
||||||
|
|
||||||
renderer = new SymbolRenderer();
|
renderer = new SymbolRenderer();
|
||||||
|
|
||||||
referenceKeyModel =
|
referenceKeyModel =
|
||||||
new SymbolReferenceModel(plugin.getBlockModelService(), plugin.getTool());
|
new SymbolReferenceModel(plugin.getBlockModelService(), plugin.getTool());
|
||||||
referencePanel =
|
referencePanel =
|
||||||
new ReferencePanel(this, referenceKeyModel, renderer, plugin.getGoToService());
|
new ReferencePanel(this, referenceKeyModel, renderer, plugin.getGoToService());
|
||||||
|
|
||||||
|
addToTool();
|
||||||
}
|
}
|
||||||
|
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
@ -119,11 +129,6 @@ class ReferenceProvider extends ComponentProviderAdapter {
|
||||||
return "(" + referenceKeyModel.getDescription() + ")";
|
return "(" + referenceKeyModel.getDescription() + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ImageIcon getIcon() {
|
|
||||||
return SymbolTablePlugin.REF_GIF;
|
|
||||||
}
|
|
||||||
|
|
||||||
void open() {
|
void open() {
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.symtable;
|
package ghidra.app.plugin.core.symtable;
|
||||||
|
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -22,20 +23,23 @@ import javax.swing.ImageIcon;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
|
||||||
import docking.ActionContext;
|
import docking.ActionContext;
|
||||||
|
import docking.DockingUtils;
|
||||||
|
import docking.action.KeyBindingData;
|
||||||
import ghidra.app.context.ProgramActionContext;
|
import ghidra.app.context.ProgramActionContext;
|
||||||
import ghidra.app.context.ProgramSymbolActionContext;
|
import ghidra.app.context.ProgramSymbolActionContext;
|
||||||
import ghidra.app.events.ProgramSelectionPluginEvent;
|
|
||||||
import ghidra.app.util.SymbolInspector;
|
import ghidra.app.util.SymbolInspector;
|
||||||
import ghidra.framework.options.SaveState;
|
import ghidra.framework.options.SaveState;
|
||||||
import ghidra.framework.plugintool.ComponentProviderAdapter;
|
import ghidra.framework.plugintool.ComponentProviderAdapter;
|
||||||
import ghidra.framework.plugintool.PluginEvent;
|
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.model.symbol.Symbol;
|
import ghidra.program.model.symbol.Symbol;
|
||||||
import ghidra.program.util.ProgramSelection;
|
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
import ghidra.util.table.GhidraTable;
|
import ghidra.util.table.GhidraTable;
|
||||||
|
import resources.ResourceManager;
|
||||||
|
|
||||||
class SymbolProvider extends ComponentProviderAdapter {
|
class SymbolProvider extends ComponentProviderAdapter {
|
||||||
|
|
||||||
|
private static final ImageIcon ICON = ResourceManager.loadImage("images/table.png");
|
||||||
|
|
||||||
private SymbolTablePlugin plugin;
|
private SymbolTablePlugin plugin;
|
||||||
private SymbolRenderer renderer;
|
private SymbolRenderer renderer;
|
||||||
private SymbolTableModel symbolKeyModel;
|
private SymbolTableModel symbolKeyModel;
|
||||||
|
@ -44,6 +48,11 @@ class SymbolProvider extends ComponentProviderAdapter {
|
||||||
SymbolProvider(SymbolTablePlugin plugin) {
|
SymbolProvider(SymbolTablePlugin plugin) {
|
||||||
super(plugin.getTool(), "Symbol Table", plugin.getName(), ProgramActionContext.class);
|
super(plugin.getTool(), "Symbol Table", plugin.getName(), ProgramActionContext.class);
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
|
|
||||||
|
setIcon(ICON);
|
||||||
|
addToToolbar();
|
||||||
|
setKeyBinding(new KeyBindingData(KeyEvent.VK_T, DockingUtils.CONTROL_KEY_MODIFIER_MASK));
|
||||||
|
|
||||||
setHelpLocation(new HelpLocation(plugin.getName(), "Symbol_Table"));
|
setHelpLocation(new HelpLocation(plugin.getName(), "Symbol_Table"));
|
||||||
setWindowGroup("symbolTable");
|
setWindowGroup("symbolTable");
|
||||||
renderer = new SymbolRenderer();
|
renderer = new SymbolRenderer();
|
||||||
|
@ -51,6 +60,8 @@ class SymbolProvider extends ComponentProviderAdapter {
|
||||||
symbolKeyModel = new SymbolTableModel(this, plugin.getTool());
|
symbolKeyModel = new SymbolTableModel(this, plugin.getTool());
|
||||||
symbolPanel = new SymbolPanel(this, symbolKeyModel, renderer, plugin.getTool(),
|
symbolPanel = new SymbolPanel(this, symbolKeyModel, renderer, plugin.getTool(),
|
||||||
plugin.getGoToService());
|
plugin.getGoToService());
|
||||||
|
|
||||||
|
addToTool();
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateTitle() {
|
void updateTitle() {
|
||||||
|
@ -77,13 +88,6 @@ class SymbolProvider extends ComponentProviderAdapter {
|
||||||
symbolKeyModel.delete(rowObjects);
|
symbolKeyModel.delete(rowObjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeSelection() {
|
|
||||||
ProgramSelection selection = symbolPanel.getProgramSelection();
|
|
||||||
PluginEvent event =
|
|
||||||
new ProgramSelectionPluginEvent(plugin.getName(), selection, plugin.getProgram());
|
|
||||||
plugin.firePluginEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setFilter() {
|
void setFilter() {
|
||||||
symbolPanel.setFilter();
|
symbolPanel.setFilter();
|
||||||
}
|
}
|
||||||
|
@ -164,11 +168,6 @@ class SymbolProvider extends ComponentProviderAdapter {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ImageIcon getIcon() {
|
|
||||||
return SymbolTablePlugin.SYM_GIF;
|
|
||||||
}
|
|
||||||
|
|
||||||
void open() {
|
void open() {
|
||||||
if (!isVisible()) {
|
if (!isVisible()) {
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
package ghidra.app.plugin.core.symtable;
|
package ghidra.app.plugin.core.symtable;
|
||||||
|
|
||||||
import java.awt.Cursor;
|
import java.awt.Cursor;
|
||||||
import java.awt.event.InputEvent;
|
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
|
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
|
@ -74,12 +73,6 @@ public class SymbolTablePlugin extends Plugin implements DomainObjectListener {
|
||||||
final static Cursor WAIT_CURSOR = new Cursor(Cursor.WAIT_CURSOR);
|
final static Cursor WAIT_CURSOR = new Cursor(Cursor.WAIT_CURSOR);
|
||||||
final static Cursor NORM_CURSOR = new Cursor(Cursor.DEFAULT_CURSOR);
|
final static Cursor NORM_CURSOR = new Cursor(Cursor.DEFAULT_CURSOR);
|
||||||
|
|
||||||
final static ImageIcon SYM_GIF = ResourceManager.loadImage("images/table.png");
|
|
||||||
final static ImageIcon REF_GIF = ResourceManager.loadImage("images/table_go.png");
|
|
||||||
|
|
||||||
private DockingAction viewSymTableAction;
|
|
||||||
private DockingAction viewRefTableAction;
|
|
||||||
|
|
||||||
private DockingAction openRefsAction;
|
private DockingAction openRefsAction;
|
||||||
private DockingAction deleteAction;
|
private DockingAction deleteAction;
|
||||||
private DockingAction makeSelectionAction;
|
private DockingAction makeSelectionAction;
|
||||||
|
@ -113,10 +106,6 @@ public class SymbolTablePlugin extends Plugin implements DomainObjectListener {
|
||||||
symProvider = new SymbolProvider(this);
|
symProvider = new SymbolProvider(this);
|
||||||
refProvider = new ReferenceProvider(this);
|
refProvider = new ReferenceProvider(this);
|
||||||
|
|
||||||
tool.addComponentProvider(symProvider, false);
|
|
||||||
tool.addComponentProvider(refProvider, false);
|
|
||||||
|
|
||||||
createActions();
|
|
||||||
createSymActions();
|
createSymActions();
|
||||||
createRefActions();
|
createRefActions();
|
||||||
|
|
||||||
|
@ -133,8 +122,6 @@ public class SymbolTablePlugin extends Plugin implements DomainObjectListener {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
swingMgr.dispose();
|
swingMgr.dispose();
|
||||||
|
|
||||||
viewSymTableAction.dispose();
|
|
||||||
viewRefTableAction.dispose();
|
|
||||||
deleteAction.dispose();
|
deleteAction.dispose();
|
||||||
makeSelectionAction.dispose();
|
makeSelectionAction.dispose();
|
||||||
|
|
||||||
|
@ -357,38 +344,10 @@ public class SymbolTablePlugin extends Plugin implements DomainObjectListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createActions() {
|
|
||||||
viewSymTableAction = new DockingAction("View Symbol Table", getName()) {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionContext context) {
|
|
||||||
tool.showComponentProvider(symProvider, true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
viewSymTableAction.setToolBarData(
|
|
||||||
new ToolBarData(ResourceManager.loadImage("images/table.png"), "View"));
|
|
||||||
viewSymTableAction.setKeyBindingData(
|
|
||||||
new KeyBindingData(KeyEvent.VK_T, InputEvent.CTRL_DOWN_MASK));
|
|
||||||
|
|
||||||
viewSymTableAction.setDescription("Display Symbol Table");
|
|
||||||
tool.addAction(viewSymTableAction);
|
|
||||||
|
|
||||||
viewRefTableAction = new DockingAction("View Symbol References", getName()) {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionContext context) {
|
|
||||||
tool.showComponentProvider(refProvider, true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
viewRefTableAction.setToolBarData(
|
|
||||||
new ToolBarData(ResourceManager.loadImage("images/table_go.png"), "View"));
|
|
||||||
|
|
||||||
viewRefTableAction.setDescription("Display Symbol References");
|
|
||||||
tool.addAction(viewRefTableAction);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createSymActions() {
|
private void createSymActions() {
|
||||||
String popupGroup = "1";
|
String popupGroup = "1";
|
||||||
|
|
||||||
openRefsAction = new DockingAction("Symbol References", getName()) {
|
openRefsAction = new DockingAction("Symbol References", getName(), KeyBindingType.SHARED) {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionContext context) {
|
public void actionPerformed(ActionContext context) {
|
||||||
refProvider.open();
|
refProvider.open();
|
||||||
|
@ -400,7 +359,7 @@ public class SymbolTablePlugin extends Plugin implements DomainObjectListener {
|
||||||
new MenuData(new String[] { "Symbol References" }, icon, popupGroup));
|
new MenuData(new String[] { "Symbol References" }, icon, popupGroup));
|
||||||
openRefsAction.setToolBarData(new ToolBarData(icon));
|
openRefsAction.setToolBarData(new ToolBarData(icon));
|
||||||
|
|
||||||
openRefsAction.setDescription("Symbol References");
|
openRefsAction.setDescription("Display Symbol References");
|
||||||
tool.addLocalAction(symProvider, openRefsAction);
|
tool.addLocalAction(symProvider, openRefsAction);
|
||||||
|
|
||||||
deleteAction = new DockingAction("Delete Symbols", getName()) {
|
deleteAction = new DockingAction("Delete Symbols", getName()) {
|
||||||
|
@ -434,13 +393,7 @@ public class SymbolTablePlugin extends Plugin implements DomainObjectListener {
|
||||||
DockingAction editExternalLocationAction = new EditExternalLocationAction(this);
|
DockingAction editExternalLocationAction = new EditExternalLocationAction(this);
|
||||||
tool.addLocalAction(symProvider, editExternalLocationAction);
|
tool.addLocalAction(symProvider, editExternalLocationAction);
|
||||||
|
|
||||||
makeSelectionAction = new MakeProgramSelectionAction(getName(), symProvider.getTable()) {
|
makeSelectionAction = new MakeProgramSelectionAction(this, symProvider.getTable());
|
||||||
@Override
|
|
||||||
protected void makeSelection(ActionContext context) {
|
|
||||||
symProvider.makeSelection();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
makeSelectionAction.getPopupMenuData().setMenuGroup(popupGroup);
|
makeSelectionAction.getPopupMenuData().setMenuGroup(popupGroup);
|
||||||
|
|
||||||
tool.addLocalAction(symProvider, makeSelectionAction);
|
tool.addLocalAction(symProvider, makeSelectionAction);
|
||||||
|
|
|
@ -159,10 +159,15 @@ public class TableComponentProvider<T> extends ComponentProviderAdapter
|
||||||
private void createActions(final Plugin plugin) {
|
private void createActions(final Plugin plugin) {
|
||||||
|
|
||||||
GhidraTable table = threadedPanel.getTable();
|
GhidraTable table = threadedPanel.getTable();
|
||||||
selectAction = new MakeProgramSelectionAction(tableServicePlugin.getName(), table) {
|
selectAction = new MakeProgramSelectionAction(tableServicePlugin, table) {
|
||||||
@Override
|
@Override
|
||||||
protected void makeSelection(ActionContext context) {
|
protected ProgramSelection makeSelection(ActionContext context) {
|
||||||
doMakeSelection(plugin);
|
|
||||||
|
ProgramSelection selection = table.getProgramSelection();
|
||||||
|
navigatable.goTo(program, new ProgramLocation(program, selection.getMinAddress()));
|
||||||
|
navigatable.setSelection(selection);
|
||||||
|
navigatable.requestFocus();
|
||||||
|
return selection;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
selectAction.setHelpLocation(new HelpLocation(HelpTopics.SEARCH, "Make_Selection"));
|
selectAction.setHelpLocation(new HelpLocation(HelpTopics.SEARCH, "Make_Selection"));
|
||||||
|
@ -171,32 +176,31 @@ public class TableComponentProvider<T> extends ComponentProviderAdapter
|
||||||
selectionNavigationAction.setHelpLocation(
|
selectionNavigationAction.setHelpLocation(
|
||||||
new HelpLocation(HelpTopics.SEARCH, "Selection_Navigation"));
|
new HelpLocation(HelpTopics.SEARCH, "Selection_Navigation"));
|
||||||
|
|
||||||
DockingAction externalGotoAction =
|
DockingAction externalGotoAction = new DockingAction("Go to External Location", getName()) {
|
||||||
new DockingAction("Go to External Location", getName(), false) {
|
@Override
|
||||||
@Override
|
public void actionPerformed(ActionContext context) {
|
||||||
public void actionPerformed(ActionContext context) {
|
gotoExternalAddress(getSelectedExternalAddress());
|
||||||
gotoExternalAddress(getSelectedExternalAddress());
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabledForContext(ActionContext context) {
|
public boolean isEnabledForContext(ActionContext context) {
|
||||||
return getSelectedExternalAddress() != null &&
|
return getSelectedExternalAddress() != null &&
|
||||||
tool.getService(GoToService.class) != null;
|
tool.getService(GoToService.class) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Address getSelectedExternalAddress() {
|
private Address getSelectedExternalAddress() {
|
||||||
if (table.getSelectedRowCount() != 1) {
|
if (table.getSelectedRowCount() != 1) {
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
ProgramSelection selection = table.getProgramSelection();
|
|
||||||
Program modelProgram = model.getProgram();
|
|
||||||
if (modelProgram == null || selection.getNumAddresses() != 1) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
Address addr = selection.getMinAddress();
|
|
||||||
return addr.isExternalAddress() ? addr : null;
|
|
||||||
}
|
}
|
||||||
};
|
ProgramSelection selection = table.getProgramSelection();
|
||||||
|
Program modelProgram = model.getProgram();
|
||||||
|
if (modelProgram == null || selection.getNumAddresses() != 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Address addr = selection.getMinAddress();
|
||||||
|
return addr.isExternalAddress() ? addr : null;
|
||||||
|
}
|
||||||
|
};
|
||||||
externalGotoAction.setDescription("Go to an external location");
|
externalGotoAction.setDescription("Go to an external location");
|
||||||
externalGotoAction.setEnabled(false);
|
externalGotoAction.setEnabled(false);
|
||||||
|
|
||||||
|
@ -266,19 +270,6 @@ public class TableComponentProvider<T> extends ComponentProviderAdapter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doMakeSelection(Plugin plugin) {
|
|
||||||
ProgramSelection selection = threadedPanel.getTable().getProgramSelection();
|
|
||||||
Program modelProgram = model.getProgram();
|
|
||||||
if (modelProgram == null || selection.getNumAddresses() == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
navigatable.goTo(model.getProgram(),
|
|
||||||
new ProgramLocation(modelProgram, selection.getMinAddress()));
|
|
||||||
navigatable.setSelection(selection);
|
|
||||||
navigatable.requestFocus();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void closeComponent() {
|
public void closeComponent() {
|
||||||
if (navigatable != null) {
|
if (navigatable != null) {
|
||||||
|
|
|
@ -55,11 +55,6 @@ import ghidra.util.task.SwingUpdateManager;
|
||||||
public class TableServicePlugin extends ProgramPlugin
|
public class TableServicePlugin extends ProgramPlugin
|
||||||
implements TableService, DomainObjectListener {
|
implements TableService, DomainObjectListener {
|
||||||
|
|
||||||
static final String MAKE_SELECTION_ACTION_NAME = "Make Selection";
|
|
||||||
static final String REMOVE_ITEMS_ACTION_NAME = "Remove Items";
|
|
||||||
|
|
||||||
static final String SHARED_ACTION_OWNER_SUFFIX = " (Tool)";
|
|
||||||
|
|
||||||
private SwingUpdateManager updateMgr;
|
private SwingUpdateManager updateMgr;
|
||||||
private Map<Program, List<TableComponentProvider<?>>> programMap = new HashMap<>();
|
private Map<Program, List<TableComponentProvider<?>>> programMap = new HashMap<>();
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@ package ghidra.app.plugin.debug;
|
||||||
|
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
|
|
||||||
import javax.swing.ImageIcon;
|
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
|
||||||
import db.DBHandle;
|
import db.DBHandle;
|
||||||
|
@ -34,14 +33,14 @@ public class DbViewerProvider extends ComponentProviderAdapter {
|
||||||
|
|
||||||
private DBHandle dbh;
|
private DBHandle dbh;
|
||||||
private String dbName;
|
private String dbName;
|
||||||
private Plugin plugin;
|
|
||||||
private ImageIcon icon;
|
|
||||||
private DbViewerComponent comp;
|
private DbViewerComponent comp;
|
||||||
|
|
||||||
public DbViewerProvider(Plugin plugin) {
|
public DbViewerProvider(Plugin plugin) {
|
||||||
super(plugin.getTool(), "Database Viewer", plugin.getName());
|
super(plugin.getTool(), "Database Viewer", plugin.getName());
|
||||||
|
|
||||||
|
setIcon(ResourceManager.loadImage(ICON_IMAGE));
|
||||||
setDefaultWindowPosition(WindowPosition.BOTTOM);
|
setDefaultWindowPosition(WindowPosition.BOTTOM);
|
||||||
this.plugin = plugin;
|
|
||||||
setHelpLocation(new HelpLocation(plugin.getName(), "DbViewer"));
|
setHelpLocation(new HelpLocation(plugin.getName(), "DbViewer"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,13 +92,4 @@ public class DbViewerProvider extends ComponentProviderAdapter {
|
||||||
}
|
}
|
||||||
return comp;
|
return comp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ImageIcon getIcon() {
|
|
||||||
if (icon == null) {
|
|
||||||
icon = ResourceManager.loadImage(ICON_IMAGE);
|
|
||||||
}
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ import javax.swing.KeyStroke;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import docking.DockingKeyBindingAction;
|
import docking.actions.KeyBindingUtils;
|
||||||
import generic.jar.ResourceFile;
|
import generic.jar.ResourceFile;
|
||||||
import ghidra.util.HTMLUtilities;
|
import ghidra.util.HTMLUtilities;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
|
@ -318,7 +318,7 @@ public class ScriptInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
keyBinding = DockingKeyBindingAction.parseKeyStroke(buildy.toString());
|
keyBinding = KeyBindingUtils.parseKeyStroke(buildy.toString());
|
||||||
if (keyBinding == null) {
|
if (keyBinding == null) {
|
||||||
// note: this message will be cleared by the parseHeader() method
|
// note: this message will be cleared by the parseHeader() method
|
||||||
keybindingErrorMessage = "Unable to parse keybinding: " + buildy;
|
keybindingErrorMessage = "Unable to parse keybinding: " + buildy;
|
||||||
|
@ -479,7 +479,7 @@ public class ScriptInfo {
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
return DockingKeyBindingAction.parseKeyStroke(keyStroke);
|
return KeyBindingUtils.parseKeyStroke(keyStroke);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String toToolTip(String string) {
|
private String toToolTip(String string) {
|
||||||
|
|
|
@ -25,7 +25,7 @@ import javax.swing.*;
|
||||||
import javax.swing.table.TableCellRenderer;
|
import javax.swing.table.TableCellRenderer;
|
||||||
|
|
||||||
import docking.*;
|
import docking.*;
|
||||||
import docking.action.*;
|
import docking.action.DockingAction;
|
||||||
import docking.widgets.table.*;
|
import docking.widgets.table.*;
|
||||||
import docking.widgets.table.threaded.ThreadedTableModel;
|
import docking.widgets.table.threaded.ThreadedTableModel;
|
||||||
import ghidra.app.nav.Navigatable;
|
import ghidra.app.nav.Navigatable;
|
||||||
|
@ -41,8 +41,8 @@ import ghidra.util.SystemUtilities;
|
||||||
import ghidra.util.datastruct.WeakDataStructureFactory;
|
import ghidra.util.datastruct.WeakDataStructureFactory;
|
||||||
import ghidra.util.datastruct.WeakSet;
|
import ghidra.util.datastruct.WeakSet;
|
||||||
import ghidra.util.table.*;
|
import ghidra.util.table.*;
|
||||||
|
import ghidra.util.table.actions.MakeProgramSelectionAction;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
import resources.ResourceManager;
|
|
||||||
import utility.function.Callback;
|
import utility.function.Callback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -157,23 +157,20 @@ public class TableChooserDialog extends DialogComponentProvider
|
||||||
|
|
||||||
private void createActions() {
|
private void createActions() {
|
||||||
String owner = getClass().getSimpleName();
|
String owner = getClass().getSimpleName();
|
||||||
DockingAction selectAction = new DockingAction("Make Selection", owner, false) {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionContext context) {
|
|
||||||
makeSelection();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
DockingAction selectAction = new MakeProgramSelectionAction(owner, table) {
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabledForContext(ActionContext context) {
|
protected ProgramSelection makeSelection(ActionContext context) {
|
||||||
return table.getSelectedRowCount() != 0;
|
ProgramSelection selection = table.getProgramSelection();
|
||||||
|
if (navigatable != null) {
|
||||||
|
navigatable.goTo(program,
|
||||||
|
new ProgramLocation(program, selection.getMinAddress()));
|
||||||
|
navigatable.setSelection(selection);
|
||||||
|
navigatable.requestFocus();
|
||||||
|
}
|
||||||
|
return selection;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
selectAction.setDescription("Make a selection using selected rows");
|
|
||||||
selectAction.setEnabled(true);
|
|
||||||
Icon icon = ResourceManager.loadImage("images/text_align_justify.png");
|
|
||||||
selectAction.setToolBarData(new ToolBarData(icon));
|
|
||||||
selectAction.setPopupMenuData(new MenuData(new String[] { "Make Selection" }, icon));
|
|
||||||
selectAction.setHelpLocation(new HelpLocation(HelpTopics.SEARCH, "Make_Selection"));
|
|
||||||
|
|
||||||
DockingAction selectionNavigationAction = new SelectionNavigationAction(owner, table);
|
DockingAction selectionNavigationAction = new SelectionNavigationAction(owner, table);
|
||||||
selectionNavigationAction.setHelpLocation(
|
selectionNavigationAction.setHelpLocation(
|
||||||
|
@ -183,18 +180,6 @@ public class TableChooserDialog extends DialogComponentProvider
|
||||||
addAction(selectionNavigationAction);
|
addAction(selectionNavigationAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void makeSelection() {
|
|
||||||
ProgramSelection selection = table.getProgramSelection();
|
|
||||||
if (program == null || program.isClosed() || selection.getNumAddresses() == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (navigatable != null) {
|
|
||||||
navigatable.goTo(program, new ProgramLocation(program, selection.getMinAddress()));
|
|
||||||
navigatable.setSelection(selection);
|
|
||||||
navigatable.requestFocus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void show() {
|
public void show() {
|
||||||
DockingWindowManager manager = DockingWindowManager.getActiveInstance();
|
DockingWindowManager manager = DockingWindowManager.getActiveInstance();
|
||||||
tool.showDialog(this, manager.getMainWindow());
|
tool.showDialog(this, manager.getMainWindow());
|
||||||
|
|
|
@ -62,7 +62,7 @@ public interface PluginConstants {
|
||||||
*/
|
*/
|
||||||
char ANYSINGLECHAR_WILDCARD_CHAR = '?';
|
char ANYSINGLECHAR_WILDCARD_CHAR = '?';
|
||||||
|
|
||||||
String CODE_BROWSER = "CodeBrowserPlugin";
|
String CODE_BROWSER = "Listing";
|
||||||
String MEMORY_MAP = "Memory Map";
|
String MEMORY_MAP = "Memory Map";
|
||||||
String BYTE_VIEWER = "ByteViewerPlugin";
|
String BYTE_VIEWER = "ByteViewerPlugin";
|
||||||
String BOOKMARKS = "Bookmarks";
|
String BOOKMARKS = "Bookmarks";
|
||||||
|
|
|
@ -28,10 +28,10 @@ abstract class DualListingToggleDockingAction extends ToggleDockingAction {
|
||||||
* Constructor that creates a toggle action for a dual listing.
|
* Constructor that creates a toggle action for a dual listing.
|
||||||
* @param name the name for this action
|
* @param name the name for this action
|
||||||
* @param owner the owner of this action
|
* @param owner the owner of this action
|
||||||
* @param isKeybindingManaged true if this action's key binding should be managed
|
* @param supportsKeyBindings true if this action's key binding should be managed
|
||||||
*/
|
*/
|
||||||
public DualListingToggleDockingAction(String name, String owner, boolean isKeybindingManaged) {
|
public DualListingToggleDockingAction(String name, String owner, boolean supportsKeyBindings) {
|
||||||
super(name, owner, isKeybindingManaged);
|
super(name, owner, supportsKeyBindings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -23,8 +23,6 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.event.TreeSelectionEvent;
|
|
||||||
import javax.swing.event.TreeSelectionListener;
|
|
||||||
import javax.swing.tree.TreePath;
|
import javax.swing.tree.TreePath;
|
||||||
import javax.swing.tree.TreeSelectionModel;
|
import javax.swing.tree.TreeSelectionModel;
|
||||||
|
|
||||||
|
@ -65,22 +63,21 @@ class FileSystemBrowserComponentProvider extends ComponentProviderAdapter {
|
||||||
*/
|
*/
|
||||||
public FileSystemBrowserComponentProvider(FileSystemBrowserPlugin plugin, FileSystemRef fsRef) {
|
public FileSystemBrowserComponentProvider(FileSystemBrowserPlugin plugin, FileSystemRef fsRef) {
|
||||||
super(plugin.getTool(), fsRef.getFilesystem().getName(), plugin.getName());
|
super(plugin.getTool(), fsRef.getFilesystem().getName(), plugin.getName());
|
||||||
setTransient();
|
|
||||||
|
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
|
|
||||||
this.rootNode = new FSBRootNode(fsRef);
|
this.rootNode = new FSBRootNode(fsRef);
|
||||||
|
|
||||||
|
setTransient();
|
||||||
|
setIcon(ImageManager.PHOTO);
|
||||||
|
|
||||||
gTree = new GTree(rootNode);
|
gTree = new GTree(rootNode);
|
||||||
gTree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
|
gTree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
|
||||||
gTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() {
|
gTree.getSelectionModel().addTreeSelectionListener(e -> {
|
||||||
@Override
|
tool.contextChanged(FileSystemBrowserComponentProvider.this);
|
||||||
public void valueChanged(TreeSelectionEvent e) {
|
TreePath[] paths = gTree.getSelectionPaths();
|
||||||
tool.contextChanged(FileSystemBrowserComponentProvider.this);
|
if (paths.length == 1) {
|
||||||
TreePath[] paths = gTree.getSelectionPaths();
|
GTreeNode clickedNode = (GTreeNode) paths[0].getLastPathComponent();
|
||||||
if (paths.length == 1) {
|
handleSingleClick(clickedNode);
|
||||||
GTreeNode clickedNode = (GTreeNode) paths[0].getLastPathComponent();
|
|
||||||
handleSingleClick(clickedNode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
gTree.addMouseListener(new MouseAdapter() {
|
gTree.addMouseListener(new MouseAdapter() {
|
||||||
|
@ -301,11 +298,6 @@ class FileSystemBrowserComponentProvider extends ComponentProviderAdapter {
|
||||||
return WindowPosition.WINDOW;
|
return WindowPosition.WINDOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Icon getIcon() {
|
|
||||||
return ImageManager.PHOTO;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dispose() {
|
void dispose() {
|
||||||
if (actionManager != null) {
|
if (actionManager != null) {
|
||||||
actionManager.dispose();
|
actionManager.dispose();
|
||||||
|
|
|
@ -32,7 +32,7 @@ public class TestTool extends GhidraTool {
|
||||||
@Override
|
@Override
|
||||||
protected DockingWindowManager createDockingWindowManager(boolean isDockable, boolean hasStatus,
|
protected DockingWindowManager createDockingWindowManager(boolean isDockable, boolean hasStatus,
|
||||||
boolean isModal) {
|
boolean isModal) {
|
||||||
return new DockingWindowManager("EMPTY", null, this, isModal, isDockable, hasStatus, null);
|
return new DockingWindowManager(this, null, this, isModal, isDockable, hasStatus, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -191,10 +191,10 @@ public class GhidraTable extends GTable {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the program selection equivalent
|
* Returns the program selection equivalent to the rows currently selected in the table.
|
||||||
* to the rows currently selected in the table. This method
|
* This method is only valid when the underlying table model implements
|
||||||
* is only valid when the underlying table model implements
|
* {@link ProgramTableModel}.
|
||||||
* <code>ProgramTableModel</code>.
|
* <P>
|
||||||
* Returns null if no rows are selected or
|
* Returns null if no rows are selected or
|
||||||
* the underlying model does not implement <code>ProgramTableModel</code>.
|
* the underlying model does not implement <code>ProgramTableModel</code>.
|
||||||
* @return the program selection or null.
|
* @return the program selection or null.
|
||||||
|
@ -207,6 +207,20 @@ public class GhidraTable extends GTable {
|
||||||
return programTableModel.getProgramSelection(getSelectedRows());
|
return programTableModel.getProgramSelection(getSelectedRows());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the program being used by this table; null if the underlying model does not
|
||||||
|
* implement {@link ProgramTableModel}
|
||||||
|
*
|
||||||
|
* @return the table's program
|
||||||
|
*/
|
||||||
|
public Program getProgram() {
|
||||||
|
ProgramTableModel programTableModel = getProgramTableModel(dataModel);
|
||||||
|
if (programTableModel == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return programTableModel.getProgram();
|
||||||
|
}
|
||||||
|
|
||||||
private ProgramTableModel getProgramTableModel(TableModel model) {
|
private ProgramTableModel getProgramTableModel(TableModel model) {
|
||||||
if (model instanceof ProgramTableModel) {
|
if (model instanceof ProgramTableModel) {
|
||||||
return (ProgramTableModel) model;
|
return (ProgramTableModel) model;
|
||||||
|
|
|
@ -75,7 +75,7 @@ public class DeleteTableRowAction extends DockingAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
private DeleteTableRowAction(String name, String owner, KeyStroke defaultkeyStroke) {
|
private DeleteTableRowAction(String name, String owner, KeyStroke defaultkeyStroke) {
|
||||||
super(name, owner);
|
super(name, owner, KeyBindingType.SHARED);
|
||||||
|
|
||||||
setDescription("Remove the selected rows from the table");
|
setDescription("Remove the selected rows from the table");
|
||||||
setHelpLocation(new HelpLocation(HelpTopics.SEARCH, "Remove_Items"));
|
setHelpLocation(new HelpLocation(HelpTopics.SEARCH, "Remove_Items"));
|
||||||
|
@ -93,11 +93,6 @@ public class DeleteTableRowAction extends DockingAction {
|
||||||
setKeyBindingData(new KeyBindingData(keyStroke));
|
setKeyBindingData(new KeyBindingData(keyStroke));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean usesSharedKeyBinding() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabledForContext(ActionContext context) {
|
public boolean isEnabledForContext(ActionContext context) {
|
||||||
return table.getSelectedRowCount() > 0;
|
return table.getSelectedRowCount() > 0;
|
||||||
|
@ -200,6 +195,12 @@ public class DeleteTableRowAction extends DockingAction {
|
||||||
|
|
||||||
public DummyDeleteAction(PluginTool tool) {
|
public DummyDeleteAction(PluginTool tool) {
|
||||||
super(NAME, "Tool", DEFAULT_KEYSTROKE);
|
super(NAME, "Tool", DEFAULT_KEYSTROKE);
|
||||||
|
|
||||||
|
// prevent this action from appearing in the toolbar, menus, etc
|
||||||
|
setToolBarData(null);
|
||||||
|
setPopupMenuData(null);
|
||||||
|
setKeyBindingData(null);
|
||||||
|
|
||||||
tool.addAction(this);
|
tool.addAction(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,26 +15,53 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.util.table.actions;
|
package ghidra.util.table.actions;
|
||||||
|
|
||||||
import javax.swing.JTable;
|
|
||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
|
|
||||||
import docking.ActionContext;
|
import docking.ActionContext;
|
||||||
import docking.action.*;
|
import docking.action.*;
|
||||||
|
import ghidra.app.events.ProgramSelectionPluginEvent;
|
||||||
|
import ghidra.framework.plugintool.Plugin;
|
||||||
|
import ghidra.framework.plugintool.PluginEvent;
|
||||||
|
import ghidra.program.model.listing.Program;
|
||||||
|
import ghidra.program.util.ProgramSelection;
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
|
import ghidra.util.table.GhidraTable;
|
||||||
import resources.Icons;
|
import resources.Icons;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An action to make a program selection based on the given table's selection. The clients
|
* An action to make a program selection based on the given table's selection. For the context to
|
||||||
* must implement the make selection code, as they know their own data. Also, for the context to
|
|
||||||
* work, the provider using this action must create an {@link ActionContext} that returns a
|
* work, the provider using this action must create an {@link ActionContext} that returns a
|
||||||
* context object that is the table passed to this action's constructor.
|
* context object that is the table passed to this action's constructor; otherwise, this action
|
||||||
|
* will not be enabled correctly.
|
||||||
*/
|
*/
|
||||||
public abstract class MakeProgramSelectionAction extends DockingAction {
|
public class MakeProgramSelectionAction extends DockingAction {
|
||||||
|
|
||||||
private JTable table;
|
private GhidraTable table;
|
||||||
|
|
||||||
public MakeProgramSelectionAction(String owner, JTable table) {
|
// we will have one of these fields be non-null after construction
|
||||||
super("Make Selection", owner);
|
private Plugin plugin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Special constructor for clients that do not have a plugin. Clients using this
|
||||||
|
* constructor must override {@link #makeSelection(ActionContext)}.
|
||||||
|
*
|
||||||
|
* @param owner the action's owner
|
||||||
|
* @param table the table needed for this action
|
||||||
|
*/
|
||||||
|
public MakeProgramSelectionAction(String owner, GhidraTable table) {
|
||||||
|
super("Make Selection", owner, KeyBindingType.SHARED);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This normal constructor for this action. The given plugin will be used along with the
|
||||||
|
* given table to fire program selection events as the action is executed.
|
||||||
|
*
|
||||||
|
* @param plugin the plugin
|
||||||
|
* @param table the table
|
||||||
|
*/
|
||||||
|
public MakeProgramSelectionAction(Plugin plugin, GhidraTable table) {
|
||||||
|
super("Make Selection", plugin.getName(), KeyBindingType.SHARED);
|
||||||
|
this.plugin = plugin;
|
||||||
this.table = table;
|
this.table = table;
|
||||||
|
|
||||||
setPopupMenuData(
|
setPopupMenuData(
|
||||||
|
@ -45,7 +72,7 @@ public abstract class MakeProgramSelectionAction extends DockingAction {
|
||||||
// this help location provides generic help; clients can override to point to their help
|
// this help location provides generic help; clients can override to point to their help
|
||||||
setHelpLocation(new HelpLocation("Search", "Make_Selection"));
|
setHelpLocation(new HelpLocation("Search", "Make_Selection"));
|
||||||
|
|
||||||
// null for now, but we may want a default binding in the future
|
// null for now, but we may want a default binding in the future
|
||||||
initKeyStroke(null);
|
initKeyStroke(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,11 +84,6 @@ public abstract class MakeProgramSelectionAction extends DockingAction {
|
||||||
setKeyBindingData(new KeyBindingData(keyStroke));
|
setKeyBindingData(new KeyBindingData(keyStroke));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean usesSharedKeyBinding() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAddToPopup(ActionContext context) {
|
public boolean isAddToPopup(ActionContext context) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -75,6 +97,15 @@ public abstract class MakeProgramSelectionAction extends DockingAction {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Program program = table.getProgram();
|
||||||
|
if (program == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (program.isClosed()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int n = table.getSelectedRowCount();
|
int n = table.getSelectedRowCount();
|
||||||
return n > 0;
|
return n > 0;
|
||||||
}
|
}
|
||||||
|
@ -84,5 +115,17 @@ public abstract class MakeProgramSelectionAction extends DockingAction {
|
||||||
makeSelection(context);
|
makeSelection(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void makeSelection(ActionContext context);
|
protected ProgramSelection makeSelection(ActionContext context) {
|
||||||
|
ProgramSelection selection = table.getProgramSelection();
|
||||||
|
|
||||||
|
if (plugin == null) {
|
||||||
|
throw new IllegalStateException("The Make Program Selection action cannot be used " +
|
||||||
|
"without a plugin unless the client overrides this method");
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginEvent event =
|
||||||
|
new ProgramSelectionPluginEvent(plugin.getName(), selection, table.getProgram());
|
||||||
|
plugin.firePluginEvent(event);
|
||||||
|
return selection;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,547 @@
|
||||||
|
/* ###
|
||||||
|
* 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 docking;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
import org.junit.*;
|
||||||
|
|
||||||
|
import docking.action.*;
|
||||||
|
import docking.actions.KeyEntryDialog;
|
||||||
|
import docking.actions.ToolActions;
|
||||||
|
import docking.tool.util.DockingToolConstants;
|
||||||
|
import ghidra.framework.options.ToolOptions;
|
||||||
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
|
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
||||||
|
import ghidra.test.TestEnv;
|
||||||
|
import ghidra.util.Msg;
|
||||||
|
import ghidra.util.SpyErrorLogger;
|
||||||
|
import resources.Icons;
|
||||||
|
import resources.ResourceManager;
|
||||||
|
|
||||||
|
public class ComponentProviderActionsTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
|
// note: this has to happen after the test framework is initialized, so it cannot be static
|
||||||
|
private final Icon ICON = ResourceManager.loadImage("images/refresh.png");
|
||||||
|
private static final String PROVIDER_NAME = "Test Action Provider";
|
||||||
|
private static final KeyStroke CONTROL_T =
|
||||||
|
KeyStroke.getKeyStroke(Character.valueOf('t'), DockingUtils.CONTROL_KEY_MODIFIER_MASK);
|
||||||
|
|
||||||
|
private TestEnv env;
|
||||||
|
private PluginTool tool;
|
||||||
|
private TestActionsComponentProvider provider;
|
||||||
|
private SpyErrorLogger spyLogger = new SpyErrorLogger();
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
env = new TestEnv();
|
||||||
|
tool = env.showTool();
|
||||||
|
|
||||||
|
//tool = env.launchDefaultTool();
|
||||||
|
provider = new TestActionsComponentProvider(tool);
|
||||||
|
|
||||||
|
Msg.setErrorLogger(spyLogger);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
env.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIcon_WithIcon_BeforeAddedToTool() {
|
||||||
|
|
||||||
|
setIcon(ICON);
|
||||||
|
|
||||||
|
showProvider();
|
||||||
|
|
||||||
|
assertWindowMenuActionHasIcon(ICON);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIcon_WithIcon_AfterAddedToTool() {
|
||||||
|
|
||||||
|
setIcon(null);
|
||||||
|
|
||||||
|
showProvider();
|
||||||
|
assertWindowMenuActionHasIcon(Icons.EMPTY_ICON);
|
||||||
|
|
||||||
|
setIcon(ICON);
|
||||||
|
assertWindowMenuActionHasIcon(ICON);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIcon_WithoutIcon() {
|
||||||
|
showProvider();
|
||||||
|
assertWindowMenuActionHasIcon(Icons.EMPTY_ICON);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetKeyBinding_DirectlyOnProvider() {
|
||||||
|
//
|
||||||
|
// This is how clients set key bindings on providers, as desired, when constructing them
|
||||||
|
//
|
||||||
|
|
||||||
|
KeyStroke defaultKs = CONTROL_T;
|
||||||
|
setDefaultKeyBinding(defaultKs);
|
||||||
|
|
||||||
|
showProvider();
|
||||||
|
|
||||||
|
assertProviderKeyStroke(defaultKs);
|
||||||
|
assertOptionsKeyStroke(defaultKs);
|
||||||
|
assertMenuItemHasKeyStroke(defaultKs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetKeyBinding_DirectlyOnProvider_TransientProvider() {
|
||||||
|
//
|
||||||
|
// Transient providers cannot have key bindings
|
||||||
|
//
|
||||||
|
switchToTransientProvider();
|
||||||
|
|
||||||
|
setErrorsExpected(true);
|
||||||
|
setDefaultKeyBinding(CONTROL_T);
|
||||||
|
setErrorsExpected(false);
|
||||||
|
|
||||||
|
showProvider();
|
||||||
|
|
||||||
|
spyLogger.assertLogMessage("Transient", "cannot", "key", "binding");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetTransientAfterSettingKeyBinding() {
|
||||||
|
|
||||||
|
setDefaultKeyBinding(CONTROL_T);
|
||||||
|
|
||||||
|
setErrorsExpected(true);
|
||||||
|
switchToTransientProvider();
|
||||||
|
setErrorsExpected(false);
|
||||||
|
|
||||||
|
showProvider();
|
||||||
|
|
||||||
|
spyLogger.assertLogMessage("Transient", "not", "key", "binding");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalStateException.class)
|
||||||
|
public void testSetTransientAfterAddedProviderToTheTool() {
|
||||||
|
|
||||||
|
showProvider();
|
||||||
|
switchToTransientProvider(); // exception
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetKeyBinding_ViaDialog_FromWindowMenu() {
|
||||||
|
|
||||||
|
showProvider();
|
||||||
|
|
||||||
|
KeyStroke newKs = CONTROL_T;
|
||||||
|
setKeyBindingViaF4Dialog_FromWindowsMenu(newKs);
|
||||||
|
|
||||||
|
assertProviderKeyStroke(newKs);
|
||||||
|
assertOptionsKeyStroke(newKs);
|
||||||
|
assertMenuItemHasKeyStroke(newKs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetKeyBinding_ViaDialog_FromWindowMenu_ToAlreadyBoundAction() {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Test the conflicting key binding use case
|
||||||
|
//
|
||||||
|
|
||||||
|
HasDefaultKeyBindingComponentProvider otherProvider =
|
||||||
|
new HasDefaultKeyBindingComponentProvider(tool);
|
||||||
|
otherProvider.setVisible(true);
|
||||||
|
|
||||||
|
showProvider();
|
||||||
|
|
||||||
|
KeyStroke newKs = CONTROL_T;
|
||||||
|
applyBindingToDialog_FromWindowsMenu(newKs);
|
||||||
|
|
||||||
|
assertCollisionsWithKeyStroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetKeyBinding_ViaOptions_WithoutToolbarAction() {
|
||||||
|
|
||||||
|
showProvider();
|
||||||
|
|
||||||
|
KeyStroke newKs = CONTROL_T;
|
||||||
|
setOptionsKeyStroke(newKs);
|
||||||
|
|
||||||
|
assertProviderKeyStroke(newKs);
|
||||||
|
assertOptionsKeyStroke(newKs);
|
||||||
|
assertMenuItemHasKeyStroke(newKs);
|
||||||
|
assertNoToolbarAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetKeyBinding_ViaOptions_WithToolbarAction() {
|
||||||
|
|
||||||
|
setToolbarIcon(ICON);
|
||||||
|
showProvider();
|
||||||
|
|
||||||
|
KeyStroke newKs = CONTROL_T;
|
||||||
|
setOptionsKeyStroke(newKs);
|
||||||
|
|
||||||
|
assertProviderKeyStroke(newKs);
|
||||||
|
assertOptionsKeyStroke(newKs);
|
||||||
|
assertMenuItemHasKeyStroke(newKs);
|
||||||
|
assertToolbarAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetKeyBinding_ViaDialog_FromToolBar() {
|
||||||
|
|
||||||
|
setToolbarIcon(ICON);
|
||||||
|
showProvider();
|
||||||
|
|
||||||
|
KeyStroke newKs = CONTROL_T;
|
||||||
|
setKeyBindingViaF4Dialog_FromToolsToolbar(newKs);
|
||||||
|
|
||||||
|
assertProviderKeyStroke(newKs);
|
||||||
|
assertOptionsKeyStroke(newKs);
|
||||||
|
assertMenuItemHasKeyStroke(newKs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetKeyBinding_TransientProvider_CannotBeSetFromWindowMenu() {
|
||||||
|
|
||||||
|
switchToTransientProvider();
|
||||||
|
showProvider();
|
||||||
|
|
||||||
|
assertCannotShowKeyBindingDialog_FromWindowsMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetKeyBinding_TransientProvider_CannotBeSetFromToolbar() {
|
||||||
|
|
||||||
|
switchToTransientProvider();
|
||||||
|
|
||||||
|
setErrorsExpected(true);
|
||||||
|
setToolbarIcon(ICON);
|
||||||
|
setErrorsExpected(false);
|
||||||
|
|
||||||
|
spyLogger.assertLogMessage("Transient", "not", "toolbar");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefaultKeyBindingAppearsInWindowMenu() {
|
||||||
|
|
||||||
|
setDefaultKeyBinding(CONTROL_T);
|
||||||
|
showProvider();
|
||||||
|
assertWindowMenuActionHasKeyBinding(CONTROL_T);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddToToolbar_WithoutIcon() {
|
||||||
|
|
||||||
|
runSwing(() -> provider.addToToolbar());
|
||||||
|
|
||||||
|
try {
|
||||||
|
setErrorsExpected(true);
|
||||||
|
runSwingWithExceptions(this::showProvider, true);
|
||||||
|
setErrorsExpected(false);
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (Throwable t) {
|
||||||
|
// good
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetIcon_NullIconWithToolbarAction() {
|
||||||
|
|
||||||
|
setIcon(ICON);
|
||||||
|
runSwing(() -> provider.addToToolbar());
|
||||||
|
showProvider();
|
||||||
|
|
||||||
|
try {
|
||||||
|
setErrorsExpected(true);
|
||||||
|
runSwingWithExceptions(() -> provider.setIcon(null), true);
|
||||||
|
setErrorsExpected(false);
|
||||||
|
fail("Expected an exception passing a null icon when specifying a toolbar action");
|
||||||
|
}
|
||||||
|
catch (Throwable t) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetIcon_WithToolbarAction() {
|
||||||
|
setToolbarIcon(ICON);
|
||||||
|
showProvider();
|
||||||
|
|
||||||
|
assertWindowMenuActionHasIcon(ICON);
|
||||||
|
assertToolbarActionHasIcon(ICON);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetIcon_WithToolbarAction_AfterActionHasBeenAddedToToolbar() {
|
||||||
|
|
||||||
|
//
|
||||||
|
// We currently do not prevent providers from changing their icons. Make sure we respond
|
||||||
|
// to changes correctly.
|
||||||
|
//
|
||||||
|
|
||||||
|
setToolbarIcon(ICON);
|
||||||
|
showProvider();
|
||||||
|
|
||||||
|
Icon newIcon = Icons.COLLAPSE_ALL_ICON;
|
||||||
|
setIcon(newIcon);
|
||||||
|
|
||||||
|
assertWindowMenuActionHasIcon(newIcon);
|
||||||
|
assertToolbarActionHasIcon(newIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================================================
|
||||||
|
// Private Methods
|
||||||
|
//==================================================================================================
|
||||||
|
|
||||||
|
private void switchToTransientProvider() {
|
||||||
|
provider.setTransient();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showProvider() {
|
||||||
|
provider.addToTool();
|
||||||
|
tool.showComponentProvider(provider, true);
|
||||||
|
waitForSwing();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setDefaultKeyBinding(KeyStroke defaultKs) {
|
||||||
|
runSwing(() -> provider.setKeyBinding(new KeyBindingData(defaultKs)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setIcon(Icon icon) {
|
||||||
|
runSwing(() -> provider.setIcon(icon));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setToolbarIcon(Icon icon) {
|
||||||
|
runSwing(() -> {
|
||||||
|
provider.setIcon(icon);
|
||||||
|
provider.addToToolbar();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private DockingActionIf getShowProviderAction() {
|
||||||
|
|
||||||
|
DockingActionIf showProviderAction =
|
||||||
|
getAction(tool, provider.getOwner(), provider.getName());
|
||||||
|
assertNotNull("Could not find action to show ", showProviderAction);
|
||||||
|
return showProviderAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DockingActionIf getWindowMenuShowProviderAction() {
|
||||||
|
waitForSwing();
|
||||||
|
DockingActionIf action = waitFor(() -> {
|
||||||
|
Set<DockingActionIf> actions = getActionsByName(tool, PROVIDER_NAME);
|
||||||
|
|
||||||
|
//@formatter:off
|
||||||
|
return actions
|
||||||
|
.stream()
|
||||||
|
.filter(a -> a.getOwner().equals(DockingWindowManager.DOCKING_WINDOWS_OWNER))
|
||||||
|
.findFirst()
|
||||||
|
.orElseGet(() -> null)
|
||||||
|
;
|
||||||
|
//@formatter:on
|
||||||
|
});
|
||||||
|
|
||||||
|
assertNotNull("Window menu action not installed for provider", action);
|
||||||
|
assertTrue(action.getClass().getSimpleName().contains("ShowComponentAction"));
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DockingActionIf getToolbarShowProviderAction() {
|
||||||
|
|
||||||
|
DockingWindowManager dwm = tool.getWindowManager();
|
||||||
|
ActionToGuiMapper guiActions =
|
||||||
|
(ActionToGuiMapper) getInstanceField("actionToGuiMapper", dwm);
|
||||||
|
GlobalMenuAndToolBarManager toolbarManager =
|
||||||
|
(GlobalMenuAndToolBarManager) getInstanceField("menuAndToolBarManager", guiActions);
|
||||||
|
DockingActionIf action = provider.getShowProviderAction();
|
||||||
|
DockingActionIf toolbarAction = toolbarManager.getToolbarAction(action.getName());
|
||||||
|
return toolbarAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setOptionsKeyStroke(KeyStroke newKs) {
|
||||||
|
ToolOptions keyOptions = tool.getOptions(DockingToolConstants.KEY_BINDINGS);
|
||||||
|
|
||||||
|
// shared option name/format: "Provider Name (Tool)" - the shared action's owner is the Tool
|
||||||
|
runSwing(() -> keyOptions.setKeyStroke(provider.getName() + " (Tool)", newKs));
|
||||||
|
waitForSwing();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertNoToolbarAction() {
|
||||||
|
assertNull("No toolbar action found for provider", getToolbarShowProviderAction());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertToolbarAction() {
|
||||||
|
assertNotNull("No toolbar action found for provider", getToolbarShowProviderAction());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertProviderKeyStroke(KeyStroke expectedKs) {
|
||||||
|
|
||||||
|
DockingActionIf action = getShowProviderAction();
|
||||||
|
KeyStroke actionKs = action.getKeyBinding();
|
||||||
|
assertEquals(expectedKs, actionKs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertOptionsKeyStroke(KeyStroke expectedKs) {
|
||||||
|
|
||||||
|
ToolOptions options = getKeyBindingOptions();
|
||||||
|
|
||||||
|
// Option name: the action name with the 'Tool' as the owner
|
||||||
|
String fullName = provider.getName() + " (Tool)";
|
||||||
|
KeyStroke optionsKs = runSwing(() -> options.getKeyStroke(fullName, null));
|
||||||
|
assertEquals("Key stroke in options does not match expected key stroke", expectedKs,
|
||||||
|
optionsKs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertWindowMenuActionHasIcon(Icon expected) {
|
||||||
|
DockingActionIf action = getWindowMenuShowProviderAction();
|
||||||
|
assertEquals("Windows menu icons for provider does not match the value set on the provider",
|
||||||
|
expected, action.getMenuBarData().getMenuIcon());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertToolbarActionHasIcon(Icon expected) {
|
||||||
|
DockingActionIf action = getToolbarShowProviderAction();
|
||||||
|
assertNotNull("No toolbar action found; it should be there", action);
|
||||||
|
ToolBarData tbData = action.getToolBarData();
|
||||||
|
assertEquals(expected, tbData.getIcon());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertWindowMenuActionHasKeyBinding(KeyStroke ks) {
|
||||||
|
DockingActionIf action = getWindowMenuShowProviderAction();
|
||||||
|
assertEquals(
|
||||||
|
"Windows menu key bindings for provider does not match the value set on the provider",
|
||||||
|
ks, action.getKeyBinding());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertCannotShowKeyBindingDialog_FromWindowsMenu() {
|
||||||
|
// simulate the user mousing over the 'Window' menu's action
|
||||||
|
DockingActionIf windowMenuAction = getWindowMenuShowProviderAction();
|
||||||
|
DockingWindowManager.setMouseOverAction(windowMenuAction);
|
||||||
|
|
||||||
|
performLaunchKeyStrokeDialogAction();
|
||||||
|
DialogComponentProvider warningDialog = waitForDialogComponent("Unable to Set Keybinding");
|
||||||
|
close(warningDialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setKeyBindingViaF4Dialog_FromWindowsMenu(KeyStroke ks) {
|
||||||
|
|
||||||
|
// simulate the user mousing over the 'Window' menu's action
|
||||||
|
DockingActionIf windowMenuAction = getWindowMenuShowProviderAction();
|
||||||
|
DockingWindowManager.setMouseOverAction(windowMenuAction);
|
||||||
|
|
||||||
|
performLaunchKeyStrokeDialogAction();
|
||||||
|
KeyEntryDialog dialog = waitForDialogComponent(KeyEntryDialog.class);
|
||||||
|
|
||||||
|
runSwing(() -> dialog.setKeyStroke(ks));
|
||||||
|
|
||||||
|
pressButtonByText(dialog, "OK");
|
||||||
|
|
||||||
|
assertFalse("Invalid key stroke: " + ks, runSwing(() -> dialog.isVisible()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyBindingToDialog_FromWindowsMenu(KeyStroke ks) {
|
||||||
|
DockingActionIf windowMenuAction = getWindowMenuShowProviderAction();
|
||||||
|
DockingWindowManager.setMouseOverAction(windowMenuAction);
|
||||||
|
|
||||||
|
performLaunchKeyStrokeDialogAction();
|
||||||
|
KeyEntryDialog dialog = waitForDialogComponent(KeyEntryDialog.class);
|
||||||
|
|
||||||
|
runSwing(() -> dialog.setKeyStroke(ks));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertCollisionsWithKeyStroke() {
|
||||||
|
KeyEntryDialog dialog = waitForDialogComponent(KeyEntryDialog.class);
|
||||||
|
|
||||||
|
JTextPane collisionPane = (JTextPane) getInstanceField("collisionPane", dialog);
|
||||||
|
String collisionText = runSwing(() -> collisionPane.getText());
|
||||||
|
assertTrue(collisionText.contains("Actions mapped to"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertMenuItemHasKeyStroke(KeyStroke expected) {
|
||||||
|
|
||||||
|
DockingActionIf action = getWindowMenuShowProviderAction();
|
||||||
|
assertEquals(
|
||||||
|
"Windows menu key binding for provider does not match the value of the provider",
|
||||||
|
expected, action.getKeyBinding());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setKeyBindingViaF4Dialog_FromToolsToolbar(KeyStroke ks) {
|
||||||
|
|
||||||
|
// simulate the user mousing over the 'Window' menu's action
|
||||||
|
DockingActionIf toolbarAction = getToolbarShowProviderAction();
|
||||||
|
assertNotNull("Provider action not installed in toolbar", toolbarAction);
|
||||||
|
DockingWindowManager.setMouseOverAction(toolbarAction);
|
||||||
|
|
||||||
|
performLaunchKeyStrokeDialogAction();
|
||||||
|
KeyEntryDialog dialog = waitForDialogComponent(KeyEntryDialog.class);
|
||||||
|
|
||||||
|
runSwing(() -> dialog.setKeyStroke(ks));
|
||||||
|
|
||||||
|
pressButtonByText(dialog, "OK");
|
||||||
|
|
||||||
|
assertFalse("Invalid key stroke: " + ks, runSwing(() -> dialog.isVisible()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void performLaunchKeyStrokeDialogAction() {
|
||||||
|
ToolActions toolActions = ((AbstractDockingTool) tool).getToolActions();
|
||||||
|
Action action = toolActions.getAction(KeyStroke.getKeyStroke("F4"));
|
||||||
|
assertNotNull(action);
|
||||||
|
runSwing(() -> action.actionPerformed(new ActionEvent(this, 0, "")), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ToolOptions getKeyBindingOptions() {
|
||||||
|
return tool.getOptions(DockingToolConstants.KEY_BINDINGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestActionsComponentProvider extends ComponentProvider {
|
||||||
|
|
||||||
|
private JComponent component = new JTextField("Hey!");
|
||||||
|
|
||||||
|
TestActionsComponentProvider(DockingTool tool) {
|
||||||
|
super(tool, PROVIDER_NAME, "Fooberry Plugin");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JComponent getComponent() {
|
||||||
|
return component;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class HasDefaultKeyBindingComponentProvider extends ComponentProvider {
|
||||||
|
private JComponent component = new JTextField("Hey!");
|
||||||
|
|
||||||
|
HasDefaultKeyBindingComponentProvider(DockingTool tool) {
|
||||||
|
super(tool, HasDefaultKeyBindingComponentProvider.class.getSimpleName(),
|
||||||
|
"Fooberry Plugin");
|
||||||
|
|
||||||
|
setKeyBinding(new KeyBindingData(CONTROL_T));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JComponent getComponent() {
|
||||||
|
return component;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,12 +32,11 @@ import org.junit.Test;
|
||||||
import docking.test.AbstractDockingTest;
|
import docking.test.AbstractDockingTest;
|
||||||
import docking.widgets.label.GDLabel;
|
import docking.widgets.label.GDLabel;
|
||||||
import ghidra.framework.plugintool.ComponentProviderAdapter;
|
import ghidra.framework.plugintool.ComponentProviderAdapter;
|
||||||
|
import ghidra.test.DummyTool;
|
||||||
|
|
||||||
public class DockingWindowManagerTest extends AbstractDockingTest {
|
public class DockingWindowManagerTest extends AbstractDockingTest {
|
||||||
|
|
||||||
public DockingWindowManagerTest() {
|
private DockingTool tool = new DummyTool();
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDefaultGroupWindowPosition() {
|
public void testDefaultGroupWindowPosition() {
|
||||||
|
@ -46,7 +45,7 @@ public class DockingWindowManagerTest extends AbstractDockingTest {
|
||||||
// default window position.
|
// default window position.
|
||||||
//
|
//
|
||||||
|
|
||||||
DockingWindowManager dwm = new DockingWindowManager("test", (List<Image>) null, null);
|
DockingWindowManager dwm = new DockingWindowManager(tool, (List<Image>) null, null);
|
||||||
|
|
||||||
ComponentProvider providerA = addProvider(dwm, "A", "a", RIGHT);
|
ComponentProvider providerA = addProvider(dwm, "A", "a", RIGHT);
|
||||||
ComponentProvider providerB = addProvider(dwm, "B", "b", BOTTOM);
|
ComponentProvider providerB = addProvider(dwm, "B", "b", BOTTOM);
|
||||||
|
@ -66,7 +65,7 @@ public class DockingWindowManagerTest extends AbstractDockingTest {
|
||||||
// intragroup window position. Note: 'Stacked' is the default.
|
// intragroup window position. Note: 'Stacked' is the default.
|
||||||
//
|
//
|
||||||
|
|
||||||
DockingWindowManager dwm = new DockingWindowManager("test", (List<Image>) null, null);
|
DockingWindowManager dwm = new DockingWindowManager(tool, (List<Image>) null, null);
|
||||||
|
|
||||||
ComponentProvider providerA1 = addProvider(dwm, "A1", "a", RIGHT, STACK);
|
ComponentProvider providerA1 = addProvider(dwm, "A1", "a", RIGHT, STACK);
|
||||||
ComponentProvider providerA2 = addProvider(dwm, "A2", "a", BOTTOM, STACK);
|
ComponentProvider providerA2 = addProvider(dwm, "A2", "a", BOTTOM, STACK);
|
||||||
|
@ -84,7 +83,7 @@ public class DockingWindowManagerTest extends AbstractDockingTest {
|
||||||
// intragroup window position.
|
// intragroup window position.
|
||||||
//
|
//
|
||||||
|
|
||||||
DockingWindowManager dwm = new DockingWindowManager("test", (List<Image>) null, null);
|
DockingWindowManager dwm = new DockingWindowManager(tool, (List<Image>) null, null);
|
||||||
|
|
||||||
ComponentProvider providerA1 = addProvider(dwm, "A1", "a", RIGHT, STACK);
|
ComponentProvider providerA1 = addProvider(dwm, "A1", "a", RIGHT, STACK);
|
||||||
ComponentProvider providerA2 = addProvider(dwm, "A2", "a", LEFT, BOTTOM);
|
ComponentProvider providerA2 = addProvider(dwm, "A2", "a", LEFT, BOTTOM);
|
||||||
|
@ -101,7 +100,7 @@ public class DockingWindowManagerTest extends AbstractDockingTest {
|
||||||
// intragroup window position.
|
// intragroup window position.
|
||||||
//
|
//
|
||||||
|
|
||||||
DockingWindowManager dwm = new DockingWindowManager("test", (List<Image>) null, null);
|
DockingWindowManager dwm = new DockingWindowManager(tool, (List<Image>) null, null);
|
||||||
|
|
||||||
ComponentProvider providerA1 = addProvider(dwm, "A1", "a", RIGHT, WINDOW);
|
ComponentProvider providerA1 = addProvider(dwm, "A1", "a", RIGHT, WINDOW);
|
||||||
ComponentProvider providerA2 = addProvider(dwm, "A2", "a", LEFT, WINDOW);
|
ComponentProvider providerA2 = addProvider(dwm, "A2", "a", LEFT, WINDOW);
|
||||||
|
@ -122,7 +121,7 @@ public class DockingWindowManagerTest extends AbstractDockingTest {
|
||||||
//
|
//
|
||||||
|
|
||||||
// note: the positions specified here are for default positions, not intragroup positions
|
// note: the positions specified here are for default positions, not intragroup positions
|
||||||
DockingWindowManager dwm = new DockingWindowManager("test", (List<Image>) null, null);
|
DockingWindowManager dwm = new DockingWindowManager(tool, (List<Image>) null, null);
|
||||||
|
|
||||||
ComponentProvider providerA = addProvider(dwm, "A", "a", RIGHT, STACK);
|
ComponentProvider providerA = addProvider(dwm, "A", "a", RIGHT, STACK);
|
||||||
ComponentProvider providerAB = addProvider(dwm, "AB", "a.b", BOTTOM, STACK);
|
ComponentProvider providerAB = addProvider(dwm, "AB", "a.b", BOTTOM, STACK);
|
||||||
|
@ -143,7 +142,7 @@ public class DockingWindowManagerTest extends AbstractDockingTest {
|
||||||
//
|
//
|
||||||
|
|
||||||
// note: the positions specified here are for default positions, not intragroup positions
|
// note: the positions specified here are for default positions, not intragroup positions
|
||||||
DockingWindowManager dwm = new DockingWindowManager("test", (List<Image>) null, null);
|
DockingWindowManager dwm = new DockingWindowManager(tool, (List<Image>) null, null);
|
||||||
|
|
||||||
ComponentProvider providerA = addProvider(dwm, "A", "a", RIGHT, BOTTOM);
|
ComponentProvider providerA = addProvider(dwm, "A", "a", RIGHT, BOTTOM);
|
||||||
ComponentProvider providerAB = addProvider(dwm, "AB", "a.b", BOTTOM, TOP);
|
ComponentProvider providerAB = addProvider(dwm, "AB", "a.b", BOTTOM, TOP);
|
||||||
|
@ -181,8 +180,7 @@ public class DockingWindowManagerTest extends AbstractDockingTest {
|
||||||
// Test that, for unrelated groups, the layout info stored in XML is re-used when providers
|
// Test that, for unrelated groups, the layout info stored in XML is re-used when providers
|
||||||
// are shown after that XML is restored--even if the window positioning changes
|
// are shown after that XML is restored--even if the window positioning changes
|
||||||
//
|
//
|
||||||
final DockingWindowManager dwm1 =
|
final DockingWindowManager dwm1 = new DockingWindowManager(tool, (List<Image>) null, null);
|
||||||
new DockingWindowManager("test", (List<Image>) null, null);
|
|
||||||
|
|
||||||
ComponentProvider providerA = addProvider(dwm1, "A", "a", RIGHT);
|
ComponentProvider providerA = addProvider(dwm1, "A", "a", RIGHT);
|
||||||
ComponentProvider providerB = addProvider(dwm1, "B", "b", BOTTOM);
|
ComponentProvider providerB = addProvider(dwm1, "B", "b", BOTTOM);
|
||||||
|
@ -217,7 +215,7 @@ public class DockingWindowManagerTest extends AbstractDockingTest {
|
||||||
// Test that, for related groups, the layout info stored in XML is re-used when providers
|
// Test that, for related groups, the layout info stored in XML is re-used when providers
|
||||||
// are shown after that XML is restored--even if the window positioning changes
|
// are shown after that XML is restored--even if the window positioning changes
|
||||||
//
|
//
|
||||||
DockingWindowManager dwm1 = new DockingWindowManager("test", (List<Image>) null, null);
|
DockingWindowManager dwm1 = new DockingWindowManager(tool, (List<Image>) null, null);
|
||||||
|
|
||||||
ComponentProvider providerA = addProvider(dwm1, "A", "a", RIGHT);
|
ComponentProvider providerA = addProvider(dwm1, "A", "a", RIGHT);
|
||||||
ComponentProvider providerAB = addProvider(dwm1, "AB", "a.b", BOTTOM);
|
ComponentProvider providerAB = addProvider(dwm1, "AB", "a.b", BOTTOM);
|
||||||
|
@ -253,7 +251,7 @@ public class DockingWindowManagerTest extends AbstractDockingTest {
|
||||||
// and that a subgroup 'a.b' will open relative to the parent. **Make sure that this
|
// and that a subgroup 'a.b' will open relative to the parent. **Make sure that this
|
||||||
// works when the parent is the first provider open.
|
// works when the parent is the first provider open.
|
||||||
//
|
//
|
||||||
DockingWindowManager dwm = new DockingWindowManager("test", (List<Image>) null, null);
|
DockingWindowManager dwm = new DockingWindowManager(tool, (List<Image>) null, null);
|
||||||
|
|
||||||
ComponentProvider providerA = addProvider(dwm, "A", "a", TOP, RIGHT);
|
ComponentProvider providerA = addProvider(dwm, "A", "a", TOP, RIGHT);
|
||||||
ComponentProvider providerAB = addProvider(dwm, "AB", "a.b", RIGHT, BOTTOM);
|
ComponentProvider providerAB = addProvider(dwm, "AB", "a.b", RIGHT, BOTTOM);
|
||||||
|
@ -270,7 +268,7 @@ public class DockingWindowManagerTest extends AbstractDockingTest {
|
||||||
// and that a subgroup 'a.b' will open relative to the parent. **Make sure that this
|
// and that a subgroup 'a.b' will open relative to the parent. **Make sure that this
|
||||||
// works when the subgroup is the first provider open.
|
// works when the subgroup is the first provider open.
|
||||||
//
|
//
|
||||||
DockingWindowManager dwm = new DockingWindowManager("test", (List<Image>) null, null);
|
DockingWindowManager dwm = new DockingWindowManager(tool, (List<Image>) null, null);
|
||||||
|
|
||||||
ComponentProvider providerAB = addProvider(dwm, "AB", "a.b", RIGHT, BOTTOM);
|
ComponentProvider providerAB = addProvider(dwm, "AB", "a.b", RIGHT, BOTTOM);
|
||||||
ComponentProvider providerA = addProvider(dwm, "A", "a", TOP, RIGHT);
|
ComponentProvider providerA = addProvider(dwm, "A", "a", TOP, RIGHT);
|
||||||
|
@ -288,7 +286,7 @@ public class DockingWindowManagerTest extends AbstractDockingTest {
|
||||||
// Test that two providers that don't share an owner (the plugin) can share a group and
|
// Test that two providers that don't share an owner (the plugin) can share a group and
|
||||||
// open relative to each other.
|
// open relative to each other.
|
||||||
//
|
//
|
||||||
DockingWindowManager dwm = new DockingWindowManager("test", (List<Image>) null, null);
|
DockingWindowManager dwm = new DockingWindowManager(tool, (List<Image>) null, null);
|
||||||
|
|
||||||
ComponentProvider p1 = addProvider(dwm, "Owner_1", "Name_1", "group", TOP, TOP);
|
ComponentProvider p1 = addProvider(dwm, "Owner_1", "Name_1", "group", TOP, TOP);
|
||||||
ComponentProvider p2 = addProvider(dwm, "Owner_2", "Name_2", "group", BOTTOM, RIGHT);
|
ComponentProvider p2 = addProvider(dwm, "Owner_2", "Name_2", "group", BOTTOM, RIGHT);
|
||||||
|
@ -337,7 +335,7 @@ public class DockingWindowManagerTest extends AbstractDockingTest {
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DockingWindowManager dwm = new DockingWindowManager("test", (List<Image>) null, null);
|
DockingWindowManager dwm = new DockingWindowManager(tool, (List<Image>) null, null);
|
||||||
|
|
||||||
ComponentProvider pA = addProvider(dwm, "Owner_1", "A", "a", LEFT, LEFT);
|
ComponentProvider pA = addProvider(dwm, "Owner_1", "A", "a", LEFT, LEFT);
|
||||||
ComponentProvider pB = addProvider(dwm, "Owner_2", "B", "b", RIGHT, RIGHT);
|
ComponentProvider pB = addProvider(dwm, "Owner_2", "B", "b", RIGHT, RIGHT);
|
||||||
|
@ -410,7 +408,7 @@ public class DockingWindowManagerTest extends AbstractDockingTest {
|
||||||
|
|
||||||
private DockingWindowManager createNewDockingWindowManagerFromXML(final Element element) {
|
private DockingWindowManager createNewDockingWindowManagerFromXML(final Element element) {
|
||||||
final DockingWindowManager dwm2 =
|
final DockingWindowManager dwm2 =
|
||||||
new DockingWindowManager("text2", (List<Image>) null, null);
|
new DockingWindowManager(new DummyTool("Tool2"), (List<Image>) null, null);
|
||||||
|
|
||||||
runSwing(() -> {
|
runSwing(() -> {
|
||||||
dwm2.setVisible(true);
|
dwm2.setVisible(true);
|
||||||
|
|
|
@ -18,12 +18,15 @@ package docking.action;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
|
|
||||||
import docking.*;
|
import docking.*;
|
||||||
|
import docking.actions.KeyEntryDialog;
|
||||||
|
import docking.actions.ToolActions;
|
||||||
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
||||||
import ghidra.app.plugin.core.data.DataPlugin;
|
import ghidra.app.plugin.core.data.DataPlugin;
|
||||||
import ghidra.app.plugin.core.function.FunctionPlugin;
|
import ghidra.app.plugin.core.function.FunctionPlugin;
|
||||||
|
@ -185,20 +188,26 @@ public class KeyEntryDialogTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public DockingAction getKeyBindingAction() {
|
public DockingAction getKeyBindingAction() {
|
||||||
DockingWindowManager dwm = DockingWindowManager.getInstance(tool.getToolFrame());
|
|
||||||
ActionToGuiMapper dockingActionManager =
|
ToolActions toolActions = tool.getToolActions();
|
||||||
(ActionToGuiMapper) getInstanceField("actionManager", dwm);
|
KeyBindingsManager kbm =
|
||||||
return (DockingAction) getInstanceField("keyBindingsAction", dockingActionManager);
|
(KeyBindingsManager) getInstanceField("keyBindingsManager", toolActions);
|
||||||
|
Map<KeyStroke, DockingKeyBindingAction> dockingKeyMap =
|
||||||
|
(Map<KeyStroke, DockingKeyBindingAction>) getInstanceField("dockingKeyMap", kbm);
|
||||||
|
KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_F4, 0);
|
||||||
|
DockingKeyBindingAction dockingAction = dockingKeyMap.get(ks);
|
||||||
|
DockingAction f4Action = (DockingAction) getInstanceField("docakbleAction", dockingAction);
|
||||||
|
return f4Action;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showDialog(final DockingAction actionToEdit) throws Exception {
|
private void showDialog(final DockingAction actionToEdit) throws Exception {
|
||||||
final DockingAction keyBindingAction = getKeyBindingAction();
|
DockingAction keyBindingAction = getKeyBindingAction();
|
||||||
executeOnSwingWithoutBlocking(() -> {
|
executeOnSwingWithoutBlocking(() -> {
|
||||||
DockingWindowManager.setMouseOverAction(actionToEdit);
|
DockingWindowManager.setMouseOverAction(actionToEdit);
|
||||||
performAction(keyBindingAction, false);
|
performAction(keyBindingAction, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
keyEntryDialog = waitForDialogComponent(tool.getToolFrame(), KeyEntryDialog.class, 2000);
|
keyEntryDialog = waitForDialogComponent(KeyEntryDialog.class);
|
||||||
assertNotNull(keyEntryDialog);
|
assertNotNull(keyEntryDialog);
|
||||||
|
|
||||||
collisionPane = (JTextPane) getInstanceField("collisionPane", keyEntryDialog);
|
collisionPane = (JTextPane) getInstanceField("collisionPane", keyEntryDialog);
|
||||||
|
|
|
@ -30,10 +30,12 @@ import org.junit.Test;
|
||||||
import docking.DockingWindowManager;
|
import docking.DockingWindowManager;
|
||||||
import docking.test.AbstractDockingTest;
|
import docking.test.AbstractDockingTest;
|
||||||
import docking.widgets.textfield.IntegerTextField;
|
import docking.widgets.textfield.IntegerTextField;
|
||||||
|
import ghidra.test.DummyTool;
|
||||||
|
|
||||||
public class NumberInputDialogTest extends AbstractDockingTest {
|
public class NumberInputDialogTest extends AbstractDockingTest {
|
||||||
|
|
||||||
private DockingWindowManager dwm = new DockingWindowManager("test", (List<Image>) null, null);
|
private DockingWindowManager dwm =
|
||||||
|
new DockingWindowManager(new DummyTool(), (List<Image>) null, null);
|
||||||
private NumberInputDialog dialog;
|
private NumberInputDialog dialog;
|
||||||
private JButton okButton;
|
private JButton okButton;
|
||||||
private JTextField textField;
|
private JTextField textField;
|
||||||
|
|
|
@ -28,6 +28,7 @@ import docking.widgets.filter.*;
|
||||||
import docking.widgets.table.model.DirData;
|
import docking.widgets.table.model.DirData;
|
||||||
import docking.widgets.table.model.TestDataModel;
|
import docking.widgets.table.model.TestDataModel;
|
||||||
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
||||||
|
import ghidra.test.DummyTool;
|
||||||
import ghidra.util.table.GhidraTable;
|
import ghidra.util.table.GhidraTable;
|
||||||
|
|
||||||
public class GhidraTableFilterTest extends AbstractGhidraHeadedIntegrationTest {
|
public class GhidraTableFilterTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
@ -50,7 +51,7 @@ public class GhidraTableFilterTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
filteredModel = filterPanel.getTableFilterModel();
|
filteredModel = filterPanel.getTableFilterModel();
|
||||||
table.setAutoLookupColumn(4);
|
table.setAutoLookupColumn(4);
|
||||||
|
|
||||||
winMgr = new DockingWindowManager("Tests", null, null);
|
winMgr = new DockingWindowManager(new DummyTool(), null, null);
|
||||||
winMgr.addComponent(new TestTableComponentProvider());
|
winMgr.addComponent(new TestTableComponentProvider());
|
||||||
winMgr.setVisible(true);
|
winMgr.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -718,7 +718,7 @@ public class BookmarkPluginTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showBookmarkProvider() throws Exception {
|
private void showBookmarkProvider() throws Exception {
|
||||||
DockingActionIf action = getAction(plugin, "Show Bookmarks");
|
DockingActionIf action = getAction(plugin, "Bookmarks");
|
||||||
performAction(action, true);
|
performAction(action, true);
|
||||||
table = plugin.getBookmarkTable();
|
table = plugin.getBookmarkTable();
|
||||||
waitForTable();
|
waitForTable();
|
||||||
|
|
|
@ -46,7 +46,6 @@ import ghidra.framework.plugintool.PluginTool;
|
||||||
import ghidra.program.database.ProgramBuilder;
|
import ghidra.program.database.ProgramBuilder;
|
||||||
import ghidra.program.database.ProgramDB;
|
import ghidra.program.database.ProgramDB;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.address.AddressFactory;
|
|
||||||
import ghidra.program.model.data.DataType;
|
import ghidra.program.model.data.DataType;
|
||||||
import ghidra.program.model.data.PointerDataType;
|
import ghidra.program.model.data.PointerDataType;
|
||||||
import ghidra.program.model.listing.Function;
|
import ghidra.program.model.listing.Function;
|
||||||
|
@ -62,7 +61,6 @@ public class CallTreePluginTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
private TestEnv env;
|
private TestEnv env;
|
||||||
private CodeBrowserPlugin codeBrowserPlugin;
|
private CodeBrowserPlugin codeBrowserPlugin;
|
||||||
private PluginTool tool;
|
private PluginTool tool;
|
||||||
private ProgramDB program;
|
|
||||||
private CallTreePlugin callTreePlugin;
|
private CallTreePlugin callTreePlugin;
|
||||||
private CallTreeProvider provider;
|
private CallTreeProvider provider;
|
||||||
private List<CallTreeProvider> providers;
|
private List<CallTreeProvider> providers;
|
||||||
|
@ -70,14 +68,10 @@ public class CallTreePluginTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
private GTree incomingTree;
|
private GTree incomingTree;
|
||||||
private GTree outgoingTree;
|
private GTree outgoingTree;
|
||||||
|
|
||||||
private DockingAction showProviderAction;
|
private ProgramBuilder builder;
|
||||||
|
private ProgramDB program;
|
||||||
|
|
||||||
private GoToService goToService;
|
private GoToService goToService;
|
||||||
private AddressFactory addressFactory;
|
|
||||||
|
|
||||||
public CallTreePluginTest() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
// cast to list
|
// cast to list
|
||||||
|
@ -91,7 +85,6 @@ public class CallTreePluginTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
callTreePlugin = env.getPlugin(CallTreePlugin.class);
|
callTreePlugin = env.getPlugin(CallTreePlugin.class);
|
||||||
providers = (List<CallTreeProvider>) getInstanceField("providers", callTreePlugin);
|
providers = (List<CallTreeProvider>) getInstanceField("providers", callTreePlugin);
|
||||||
showProviderAction = (DockingAction) getInstanceField("showProviderAction", callTreePlugin);
|
|
||||||
|
|
||||||
GoToServicePlugin goToPlugin = env.getPlugin(GoToServicePlugin.class);
|
GoToServicePlugin goToPlugin = env.getPlugin(GoToServicePlugin.class);
|
||||||
goToService = (GoToService) invokeInstanceMethod("getGotoService", goToPlugin);
|
goToService = (GoToService) invokeInstanceMethod("getGotoService", goToPlugin);
|
||||||
|
@ -100,20 +93,18 @@ public class CallTreePluginTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
env.showTool();
|
env.showTool();
|
||||||
|
|
||||||
program = createProgram();
|
program = createProgram();
|
||||||
addressFactory = program.getAddressFactory();
|
|
||||||
ProgramManager pm = tool.getService(ProgramManager.class);
|
ProgramManager pm = tool.getService(ProgramManager.class);
|
||||||
pm.openProgram(program.getDomainFile());
|
pm.openProgram(program.getDomainFile());
|
||||||
|
|
||||||
// setup a good start location
|
// setup a good start location
|
||||||
goTo(addr("5000"));
|
goTo(addr("5000"));
|
||||||
|
|
||||||
provider = getProvider();
|
provider = callTreePlugin.getPrimaryProvider();
|
||||||
|
tool.showComponentProvider(provider, true);
|
||||||
incomingTree = (GTree) getInstanceField("incomingTree", provider);
|
incomingTree = (GTree) getInstanceField("incomingTree", provider);
|
||||||
outgoingTree = (GTree) getInstanceField("outgoingTree", provider);
|
outgoingTree = (GTree) getInstanceField("outgoingTree", provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
ProgramBuilder builder;
|
|
||||||
|
|
||||||
private ProgramDB createProgram() throws Exception {
|
private ProgramDB createProgram() throws Exception {
|
||||||
|
|
||||||
builder = new ProgramBuilder("Call Trees", ProgramBuilder._TOY);
|
builder = new ProgramBuilder("Call Trees", ProgramBuilder._TOY);
|
||||||
|
@ -385,21 +376,21 @@ public class CallTreePluginTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
assertNotNull("Provider did not update its information when made visible",
|
assertNotNull("Provider did not update its information when made visible",
|
||||||
providerFunction());
|
providerFunction());
|
||||||
|
|
||||||
final ToggleDockingAction navigateIncomingLoctionsAction =
|
ToggleDockingAction navigateIncomingLoctionsAction =
|
||||||
(ToggleDockingAction) getAction("Navigation Incoming Location Changes");
|
(ToggleDockingAction) getAction("Navigation Incoming Location Changes");
|
||||||
assertTrue(!navigateIncomingLoctionsAction.isSelected());
|
setToggleActionSelected(navigateIncomingLoctionsAction, provider.getActionContext(null),
|
||||||
|
false);
|
||||||
|
|
||||||
assertEquals("Provider's location does not match that of the listing.", currentFunction(),
|
assertEquals("Provider's location does not match that of the listing.", currentFunction(),
|
||||||
providerFunction());
|
providerFunction());
|
||||||
|
|
||||||
goTo(addr("0x6000"));
|
goTo(addr("0x6000"));
|
||||||
|
|
||||||
assertTrue("Provider's location matches that of the listing when not following " +
|
assertNotEquals("Provider's location matches that of the listing when not following " +
|
||||||
"location changes.", !currentFunction().equals(providerFunction()));
|
"location changes", currentFunction(), providerFunction());
|
||||||
|
|
||||||
performAction(navigateIncomingLoctionsAction, true);
|
performAction(navigateIncomingLoctionsAction, true);
|
||||||
|
|
||||||
assertEquals("Provider's location does not match that of the listing.", currentFunction(),
|
assertEquals("Provider's location does not match that of the listing", currentFunction(),
|
||||||
providerFunction());
|
providerFunction());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -779,21 +770,6 @@ public class CallTreePluginTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
return functionManager.getFunctionAt(address);
|
return functionManager.getFunctionAt(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CallTreeProvider getProvider() {
|
|
||||||
final AtomicReference<CallTreeProvider> ref = new AtomicReference<>();
|
|
||||||
|
|
||||||
// run in swing, as two threads are accessing/manipulating a variable
|
|
||||||
runSwing(() -> {
|
|
||||||
if (providers.size() == 0) {
|
|
||||||
ref.set(showProvider());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ref.set(providers.get(0));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return ref.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
private CallTreeProvider getProvider(final String address) {
|
private CallTreeProvider getProvider(final String address) {
|
||||||
final CallTreeProvider[] providerBox = new CallTreeProvider[1];
|
final CallTreeProvider[] providerBox = new CallTreeProvider[1];
|
||||||
|
|
||||||
|
@ -939,13 +915,13 @@ public class CallTreePluginTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fullyExpandIncomingNode(GTreeNode node) {
|
private void fullyExpandIncomingNode(GTreeNode node) {
|
||||||
DockingActionIf expandAction = getAction(callTreePlugin, "Fully Expand Selected Nodes");
|
DockingActionIf expandAction = getLocalAction(provider, "Fully Expand Selected Nodes");
|
||||||
performAction(expandAction, new ActionContext(provider, incomingTree), false);
|
performAction(expandAction, new ActionContext(provider, incomingTree), false);
|
||||||
waitForTree(node.getTree());
|
waitForTree(node.getTree());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fullyExpandOutgoingNode(GTreeNode node) {
|
private void fullyExpandOutgoingNode(GTreeNode node) {
|
||||||
DockingActionIf expandAction = getAction(callTreePlugin, "Fully Expand Selected Nodes");
|
DockingActionIf expandAction = getLocalAction(provider, "Fully Expand Selected Nodes");
|
||||||
performAction(expandAction, new ActionContext(provider, outgoingTree), false);
|
performAction(expandAction, new ActionContext(provider, outgoingTree), false);
|
||||||
waitForTree(node.getTree());
|
waitForTree(node.getTree());
|
||||||
}
|
}
|
||||||
|
@ -1054,11 +1030,11 @@ public class CallTreePluginTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
String name = child.getName();
|
String name = child.getName();
|
||||||
Integer integer = map.get(name);
|
Integer integer = map.get(name);
|
||||||
if (integer == null) {
|
if (integer == null) {
|
||||||
integer = new Integer(0);
|
integer = 0;
|
||||||
}
|
}
|
||||||
int asInt = integer;
|
int asInt = integer;
|
||||||
asInt++;
|
asInt++;
|
||||||
map.put(name, new Integer(asInt));
|
map.put(name, asInt);
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
@ -1088,10 +1064,7 @@ public class CallTreePluginTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private DockingActionIf getAction(String actionName) {
|
private DockingActionIf getAction(String actionName) {
|
||||||
// make sure there is a provider from which to get actions
|
DockingActionIf action = getLocalAction(provider, actionName);
|
||||||
getProvider();
|
|
||||||
|
|
||||||
DockingActionIf action = getAction(tool, "CallTreePlugin", actionName);
|
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1121,20 +1094,14 @@ public class CallTreePluginTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows and returns a provider for the current address.
|
|
||||||
*/
|
|
||||||
private CallTreeProvider showProvider() {
|
|
||||||
performAction(showProviderAction, true);
|
|
||||||
return getProvider();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows and returns a provider for the specified address.
|
* Shows and returns a provider for the specified address.
|
||||||
*/
|
*/
|
||||||
private CallTreeProvider showProvider(String address) {
|
private CallTreeProvider showProvider(String address) {
|
||||||
goTo(addr(address));
|
goTo(addr(address));
|
||||||
performAction(showProviderAction, true);
|
|
||||||
|
DockingAction action = callTreePlugin.getShowCallTreeFromMenuAction();
|
||||||
|
performAction(action);
|
||||||
return getProvider(address);
|
return getProvider(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,9 @@ public class CodeBrowserScreenMovementTest extends AbstractProgramBasedTest {
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
|
|
||||||
|
// warning: this test is sensitive to size and layout of the visible component providers;
|
||||||
|
// any layout changes may affect the values being tested below
|
||||||
|
|
||||||
initialize();
|
initialize();
|
||||||
|
|
||||||
fp = codeBrowser.getFieldPanel();
|
fp = codeBrowser.getFieldPanel();
|
||||||
|
@ -115,6 +118,9 @@ public class CodeBrowserScreenMovementTest extends AbstractProgramBasedTest {
|
||||||
@Test
|
@Test
|
||||||
public void testBasicControls() throws Exception {
|
public void testBasicControls() throws Exception {
|
||||||
|
|
||||||
|
// warning: this test is sensitive to size and layout of the visible component providers;
|
||||||
|
// any layout changes may affect the values being tested below
|
||||||
|
|
||||||
fp = codeBrowser.getFieldPanel();
|
fp = codeBrowser.getFieldPanel();
|
||||||
ListingPanel panel = codeBrowser.getListingPanel();
|
ListingPanel panel = codeBrowser.getListingPanel();
|
||||||
JScrollBar scrollbar = panel.getVerticalScrollBar();
|
JScrollBar scrollbar = panel.getVerticalScrollBar();
|
||||||
|
|
|
@ -68,7 +68,7 @@ public class ExpandCollapseDataActionsTest extends AbstractGhidraHeadedIntegrati
|
||||||
pm.openProgram(program.getDomainFile());
|
pm.openProgram(program.getDomainFile());
|
||||||
addrFactory = program.getAddressFactory();
|
addrFactory = program.getAddressFactory();
|
||||||
env.showTool();
|
env.showTool();
|
||||||
provider = (CodeViewerProvider) tool.getComponentProvider("CodeBrowserPlugin");
|
provider = (CodeViewerProvider) tool.getComponentProvider("Listing");
|
||||||
listingModel = provider.getListingPanel().getListingModel();
|
listingModel = provider.getListingPanel().getListingModel();
|
||||||
CodeBrowserPlugin plugin = getPlugin(tool, CodeBrowserPlugin.class);
|
CodeBrowserPlugin plugin = getPlugin(tool, CodeBrowserPlugin.class);
|
||||||
toggleExpand = getAction(plugin, "Toggle Expand/Collapse Data");
|
toggleExpand = getAction(plugin, "Toggle Expand/Collapse Data");
|
||||||
|
|
|
@ -62,7 +62,7 @@ public class StructureEditorArchiveTest extends AbstractStructureEditorTest {
|
||||||
tool.addPlugin(DataTypeManagerPlugin.class.getName());
|
tool.addPlugin(DataTypeManagerPlugin.class.getName());
|
||||||
dtmService = tool.getService(DataTypeManagerService.class);
|
dtmService = tool.getService(DataTypeManagerService.class);
|
||||||
plugin = (DataTypeManagerPlugin) dtmService;
|
plugin = (DataTypeManagerPlugin) dtmService;
|
||||||
manageDts = getAction(plugin, "Data Type Manager");
|
manageDts = getAction(plugin, "DataTypes Provider");
|
||||||
DataTypesProvider dataTypesProvider = plugin.getProvider();
|
DataTypesProvider dataTypesProvider = plugin.getProvider();
|
||||||
dtTree = dataTypesProvider.getGTree();
|
dtTree = dataTypesProvider.getGTree();
|
||||||
|
|
||||||
|
|
|
@ -55,14 +55,6 @@ public class ArchiveRemappedHeadedTest extends AbstractGhidraHeadedIntegrationTe
|
||||||
private File vs12ArchiveFile;
|
private File vs12ArchiveFile;
|
||||||
private File vs9ArchiveFile;
|
private File vs9ArchiveFile;
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor for ArchiveRemappedTest.
|
|
||||||
* @param testName
|
|
||||||
*/
|
|
||||||
public ArchiveRemappedHeadedTest() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
|
|
||||||
|
@ -97,10 +89,9 @@ public class ArchiveRemappedHeadedTest extends AbstractGhidraHeadedIntegrationTe
|
||||||
|
|
||||||
env.showTool();
|
env.showTool();
|
||||||
|
|
||||||
tool.showComponentProvider(provider, true);
|
|
||||||
waitForPostedSwingRunnables();
|
|
||||||
|
|
||||||
provider = plugin.getProvider();
|
provider = plugin.getProvider();
|
||||||
|
tool.showComponentProvider(provider, true);
|
||||||
|
|
||||||
tree = provider.getGTree();
|
tree = provider.getGTree();
|
||||||
waitForTree(tree);
|
waitForTree(tree);
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ public class MemoryMapPluginTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testActionEnabled() {
|
public void testActionEnabled() {
|
||||||
DockingActionIf action = getAction(plugin, "View Memory Map");
|
DockingActionIf action = getAction(plugin, "Memory Map");
|
||||||
assertTrue(action.isEnabled());
|
assertTrue(action.isEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ public class MemoryMapPluginTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
|
Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
|
||||||
for (DockingActionIf action : actions) {
|
for (DockingActionIf action : actions) {
|
||||||
if (action.getName().equals("Add Block") || action.getName().equals("Set Image Base") ||
|
if (action.getName().equals("Add Block") || action.getName().equals("Set Image Base") ||
|
||||||
action.getName().equals("View Memory Map")) {
|
action.getName().equals("Memory Map")) {
|
||||||
assertTrue(action.isEnabledForContext(provider.getActionContext(null)));
|
assertTrue(action.isEnabledForContext(provider.getActionContext(null)));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -116,7 +116,7 @@ public class MemoryMapPluginTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
assertEquals(0, table.getModel().getRowCount());
|
assertEquals(0, table.getModel().getRowCount());
|
||||||
Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
|
Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
|
||||||
for (DockingActionIf action : actions) {
|
for (DockingActionIf action : actions) {
|
||||||
if (!action.getName().equals("View Memory Map")) {
|
if (!action.getName().equals("Memory Map")) {
|
||||||
assertTrue(!action.isEnabledForContext(provider.getActionContext(null)));
|
assertTrue(!action.isEnabledForContext(provider.getActionContext(null)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -297,7 +297,7 @@ public class MemoryMapPluginTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private void showProvider() {
|
private void showProvider() {
|
||||||
DockingActionIf action = getAction(plugin, "View Memory Map");
|
DockingActionIf action = getAction(plugin, "Memory Map");
|
||||||
performAction(action, true);
|
performAction(action, true);
|
||||||
provider = plugin.getMemoryMapProvider();
|
provider = plugin.getMemoryMapProvider();
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue