Merge remote-tracking branch 'origin/GT-2925-dragonmacher-window-menu-key-bindings'

This commit is contained in:
Ryan Kurtz 2019-07-15 16:12:09 -04:00
commit 10372c2e13
200 changed files with 3955 additions and 3195 deletions

View file

@ -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()

View file

@ -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);
}
} }

View file

@ -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 {

View file

@ -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>

View file

@ -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&nbsp;Arrow</B></TT>.</P> address less than the current address. The default keybinding is <TT><B>Control-Up&nbsp;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">&nbsp;and <IMG <P>After clearing the history, the <IMG src="images/left.png" border="0">&nbsp;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>

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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) {

View file

@ -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));
} }
/** /**

View file

@ -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;

View file

@ -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);

View file

@ -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;
} }

View file

@ -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);

View file

@ -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;
} }

View file

@ -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.

View file

@ -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) {

View file

@ -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() {

View file

@ -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"));

View file

@ -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(

View file

@ -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());

View file

@ -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();
} }

View file

@ -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;
} }

View file

@ -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());

View file

@ -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 =

View file

@ -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 =

View file

@ -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;

View file

@ -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
} }

View file

@ -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();
} }

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -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);
} }
} }

View file

@ -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();

View file

@ -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()

View file

@ -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;

View file

@ -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();

View file

@ -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"));

View file

@ -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() },

View file

@ -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
} }

View file

@ -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.
* *

View file

@ -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

View file

@ -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();

View file

@ -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

View file

@ -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<>();
} }

View file

@ -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();

View file

@ -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();

View file

@ -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);
}
} }

View file

@ -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();
} }
} }

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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;

View file

@ -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) };

View file

@ -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

View file

@ -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);

View file

@ -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());

View file

@ -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 };
} }
} }

View file

@ -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);

View file

@ -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);
} }
//================================================================================================== //==================================================================================================

View file

@ -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();

View file

@ -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();

View file

@ -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();
} }

View file

@ -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

View file

@ -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);

View file

@ -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);
} }

View file

@ -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);

View file

@ -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();

View file

@ -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;
} }

View file

@ -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
//================================================================================================== //==================================================================================================

View file

@ -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;

View file

@ -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);

View file

@ -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)) {

View file

@ -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);
} }

View file

@ -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);

View file

@ -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);

View file

@ -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) {

View file

@ -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<>();

View file

@ -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;
}
} }

View file

@ -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) {

View file

@ -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());

View file

@ -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";

View file

@ -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);
} }
/** /**

View file

@ -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();

View file

@ -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

View file

@ -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;

View file

@ -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);
} }

View file

@ -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;
}
} }

View file

@ -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;
}
}
}

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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);
} }

View file

@ -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();

View file

@ -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);
} }

View file

@ -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();

View file

@ -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");

View file

@ -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();

View file

@ -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);
} }

View file

@ -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