GT-2925 - Key Bindings - Support Window Menu Provider Key Bindings -

Step 5 - cleanup of old key binding support constructor parameter; start
of cleanup of DockingActionProviderIf
This commit is contained in:
dragonmacher 2019-06-27 14:06:47 -04:00
parent ff4b3736b9
commit 115243801e
73 changed files with 574 additions and 682 deletions

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

@ -21,8 +21,7 @@ import java.util.List;
import javax.swing.Icon; import javax.swing.Icon;
import docking.ActionContext; import docking.ActionContext;
import docking.action.DockingAction; import docking.action.*;
import docking.action.MenuData;
import ghidra.app.CorePluginPackage; import ghidra.app.CorePluginPackage;
import ghidra.app.context.ListingActionContext; import ghidra.app.context.ListingActionContext;
import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.PluginCategoryNames;
@ -122,28 +121,18 @@ public class CallTreePlugin extends ProgramPlugin {
// use the name of the provider so that the shared key binding data will get used // use the name of the provider so that the shared key binding data will get used
String actionName = CallTreeProvider.TITLE; String actionName = CallTreeProvider.TITLE;
showCallTreeFromMenuAction = new DockingAction(actionName, getName()) { showCallTreeFromMenuAction =
new DockingAction(actionName, getName(), KeyBindingType.SHARED) {
@Override
public void actionPerformed(ActionContext context) {
showOrCreateNewCallTree(currentLocation);
}
@Override @Override
public void actionPerformed(ActionContext context) { public boolean isAddToPopup(ActionContext context) {
showOrCreateNewCallTree(currentLocation); return (context instanceof ListingActionContext);
} }
};
@Override
public boolean isAddToPopup(ActionContext context) {
return (context instanceof ListingActionContext);
}
@Override
public boolean isKeyBindingManaged() {
return false;
}
@Override
public boolean usesSharedKeyBinding() {
return true;
}
};
showCallTreeFromMenuAction.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"));

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

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

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

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

@ -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,13 @@ public class AddressTableDialog extends DialogComponentProvider {
} }
private void createAction() { private void createAction() {
DockingAction selectAction =
new DockingAction("Make Selection", "AsciiFinderDialog", false) { DockingAction selectAction = new MakeProgramSelectionAction(DIALOG_NAME, resultsTable) {
@Override @Override
public void actionPerformed(ActionContext context) { protected void makeSelection(ActionContext context) {
makeSelection(); doMakeSelection();
} }
}; };
selectAction.setDescription("Make a selection using selected rows");
selectAction.setEnabled(true);
Icon icon = ResourceManager.loadImage("images/text_align_justify.png");
selectAction.setPopupMenuData(new MenuData(new String[] { "Make Selection" }, icon));
selectAction.setToolBarData(new ToolBarData(icon));
selectAction.setHelpLocation(
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 +538,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

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

@ -201,7 +201,7 @@ public class FunctionWindowPlugin extends ProgramPlugin implements DomainObjectL
} }
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

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

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

@ -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,12 @@ 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 = new MakeProgramSelectionAction(getName(), referencesPanel.getTable()) {
@Override @Override
public void actionPerformed(ActionContext context) { protected void makeSelection(ActionContext context) {
makeSelection(); doMakeSelection();
}
@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,24 +15,20 @@
*/ */
package ghidra.app.plugin.core.reloc; package ghidra.app.plugin.core.reloc;
import javax.swing.ImageIcon;
import docking.ActionContext; import docking.ActionContext;
import docking.action.*; import docking.action.DockingAction;
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 +62,21 @@ 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(getName(), provider.getTable()) {
@Override @Override
public void actionPerformed(ActionContext context) { protected void makeSelection(ActionContext context) {
makeSelection(); doMakeSelection();
} }
}; };
programSelectionAction.setDescription("Make a selection using selected rows"); tool.addLocalAction(provider, selectAction);
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

@ -26,7 +26,8 @@ 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.actions.KeyBindingUtils;
import docking.widgets.table.GTable; import docking.widgets.table.GTable;
@ -629,13 +630,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);
@ -649,11 +648,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

@ -50,6 +50,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 +305,12 @@ public class StringTableProvider extends ComponentProviderAdapter implements Dom
makeCharArrayAction.setHelpLocation(makeStringHelp); makeCharArrayAction.setHelpLocation(makeStringHelp);
addLocalAction(makeCharArrayAction); addLocalAction(makeCharArrayAction);
DockingAction selectAction = DockingAction selectAction = new MakeProgramSelectionAction(plugin.getName(), table) {
new DockingAction("Make Selection", "AsciiFinderDialog", false) { @Override
@Override protected void makeSelection(ActionContext context) {
public void actionPerformed(ActionContext context) { doMakeSelection();
makeSelection(); }
} };
};
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_Strings"));
selectionNavigationAction = new SelectionNavigationAction(plugin, table); selectionNavigationAction = new SelectionNavigationAction(plugin, table);
selectionNavigationAction.setHelpLocation( selectionNavigationAction.setHelpLocation(
@ -327,7 +321,7 @@ public class StringTableProvider extends ComponentProviderAdapter implements Dom
} }
private void makeSelection() { private void doMakeSelection() {
AddressSet set = new AddressSet(); AddressSet set = new AddressSet();
addToAddressSet(set, table.getSelectedRows()); addToAddressSet(set, table.getSelectedRows());

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) {
@ -113,7 +113,7 @@ public class ViewStringsPlugin extends ProgramPlugin implements DomainObjectList
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 +133,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

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

@ -171,32 +171,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);

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

@ -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,13 @@ 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 void makeSelection(ActionContext context) {
return table.getSelectedRowCount() != 0; doMakeSelection();
} }
}; };
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,7 +173,7 @@ public class TableChooserDialog extends DialogComponentProvider
addAction(selectionNavigationAction); addAction(selectionNavigationAction);
} }
private void makeSelection() { private void doMakeSelection() {
ProgramSelection selection = table.getProgramSelection(); ProgramSelection selection = table.getProgramSelection();
if (program == null || program.isClosed() || selection.getNumAddresses() == 0) { if (program == null || program.isClosed() || selection.getNumAddresses() == 0) {
return; return;

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

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

View file

@ -34,7 +34,7 @@ public abstract class MakeProgramSelectionAction extends DockingAction {
private JTable table; private JTable table;
public MakeProgramSelectionAction(String owner, JTable table) { public MakeProgramSelectionAction(String owner, JTable table) {
super("Make Selection", owner); super("Make Selection", owner, KeyBindingType.SHARED);
this.table = table; this.table = table;
setPopupMenuData( setPopupMenuData(
@ -57,11 +57,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;

View file

@ -408,15 +408,13 @@ public class KeyBindingUtilsTest extends AbstractGhidraHeadedIntegrationTest {
Set<DockingActionIf> list = tool.getAllActions(); Set<DockingActionIf> list = tool.getAllActions();
DockingActionIf arbitraryAction = null; DockingActionIf arbitraryAction = null;
for (DockingActionIf action : list) { for (DockingActionIf action : list) {
if (action.isKeyBindingManaged() && action.getKeyBinding() == null) { if (action.getKeyBindingType().isManaged() && action.getKeyBinding() == null) {
arbitraryAction = action; arbitraryAction = action;
break; break;
} }
} }
if (arbitraryAction == null) { assertNotNull("Unable to find an action for which to set a key binding", arbitraryAction);
Assert.fail("Unable to find an action for which to set a key binding.");
}
selectRowForAction(arbitraryAction); selectRowForAction(arbitraryAction);
triggerText(keyField, keyText); triggerText(keyField, keyText);

View file

@ -104,7 +104,7 @@ public class KeyBindingsTest extends AbstractGhidraHeadedIntegrationTest {
public void testManagedKeyBindings() { public void testManagedKeyBindings() {
Set<DockingActionIf> list = tool.getAllActions(); Set<DockingActionIf> list = tool.getAllActions();
for (DockingActionIf action : list) { for (DockingActionIf action : list) {
if (action.isKeyBindingManaged()) { if (action.getKeyBindingType().isManaged()) {
assertTrue(actionInTable(action)); assertTrue(actionInTable(action));
} }
} }
@ -130,7 +130,7 @@ public class KeyBindingsTest extends AbstractGhidraHeadedIntegrationTest {
Set<DockingActionIf> list = tool.getAllActions(); Set<DockingActionIf> list = tool.getAllActions();
for (DockingActionIf action : list) { for (DockingActionIf action : list) {
KeyStroke ks = getKeyStroke(action); KeyStroke ks = getKeyStroke(action);
if (isKeyBindingManaged(action) && ks != KeyStroke.getKeyStroke(KeyEvent.VK_Z, 0)) { if (supportsKeyBindings(action) && ks != KeyStroke.getKeyStroke(KeyEvent.VK_Z, 0)) {
break; break;
} }
} }
@ -310,15 +310,15 @@ public class KeyBindingsTest extends AbstractGhidraHeadedIntegrationTest {
waitForSwing(); waitForSwing();
} }
private boolean isKeyBindingManaged(DockingActionIf action) { private boolean supportsKeyBindings(DockingActionIf action) {
return action.isKeyBindingManaged(); return action.getKeyBindingType().isManaged();
} }
private DockingActionIf getKeyBindingPluginAction() { private DockingActionIf getKeyBindingPluginAction() {
Set<DockingActionIf> list = tool.getAllActions(); Set<DockingActionIf> list = tool.getAllActions();
for (DockingActionIf action : list) { for (DockingActionIf action : list) {
KeyStroke ks = action.getKeyBinding(); KeyStroke ks = action.getKeyBinding();
if (action.isKeyBindingManaged() && ks != null && if (action.getKeyBindingType().isManaged() && ks != null &&
ks != KeyStroke.getKeyStroke(KeyEvent.VK_Z, 0)) { ks != KeyStroke.getKeyStroke(KeyEvent.VK_Z, 0)) {
return action; return action;
} }
@ -388,7 +388,7 @@ public class KeyBindingsTest extends AbstractGhidraHeadedIntegrationTest {
private void grabActionsWithoutKeybinding() { private void grabActionsWithoutKeybinding() {
Set<DockingActionIf> list = tool.getAllActions(); Set<DockingActionIf> list = tool.getAllActions();
for (DockingActionIf action : list) { for (DockingActionIf action : list) {
if (!action.isKeyBindingManaged()) { if (!action.getKeyBindingType().isManaged()) {
continue; continue;
} }
if (action.getKeyBinding() != null) { if (action.getKeyBinding() != null) {

View file

@ -379,4 +379,14 @@ public class DummyTool implements Tool {
public ToolOptions getOptions(String categoryName) { public ToolOptions getOptions(String categoryName) {
return null; return null;
} }
@Override
public void addContextListener(DockingContextListener listener) {
//do nothing
}
@Override
public void removeContextListener(DockingContextListener listener) {
//do nothing
}
} }

View file

@ -123,38 +123,36 @@ public abstract class ByteSequenceAnalyzerProvider extends DialogComponentProvid
} }
private void addSendSelectedToClipboardAction() { private void addSendSelectedToClipboardAction() {
sendSelectedToClipboardAction = sendSelectedToClipboardAction = new DockingAction("Send Selected to Clipboard", title) {
new DockingAction("Send Selected to Clipboard", title, false) { @Override
@Override public void actionPerformed(ActionContext context) {
public void actionPerformed(ActionContext context) { List<ByteSequenceRowObject> rows = byteSequenceTable.getLastSelectedObjects();
List<ByteSequenceRowObject> rows = byteSequenceTable.getLastSelectedObjects(); for (ByteSequenceRowObject row : rows) {
for (ByteSequenceRowObject row : rows) { DittedBitSequence seq = new DittedBitSequence(row.getSequence(), true);
DittedBitSequence seq = new DittedBitSequence(row.getSequence(), true); PatternInfoRowObject pattern = new PatternInfoRowObject(type, seq, cRegFilter);
PatternInfoRowObject pattern = pattern.setNote(row.getDisassembly());
new PatternInfoRowObject(type, seq, cRegFilter); plugin.addPattern(pattern);
pattern.setNote(row.getDisassembly());
plugin.addPattern(pattern);
}
plugin.updateClipboard();
} }
plugin.updateClipboard();
}
@Override @Override
public boolean isEnabledForContext(ActionContext context) { public boolean isEnabledForContext(ActionContext context) {
List<ByteSequenceRowObject> rows = byteSequenceTable.getLastSelectedObjects(); List<ByteSequenceRowObject> rows = byteSequenceTable.getLastSelectedObjects();
if (rows == null) { if (rows == null) {
return false; return false;
}
if (rows.isEmpty()) {
return false;
}
return true;
} }
if (rows.isEmpty()) {
return false;
}
return true;
}
@Override @Override
public boolean isAddToPopup(ActionContext context) { public boolean isAddToPopup(ActionContext context) {
return true; return true;
} }
}; };
ImageIcon icon = ResourceManager.loadImage("images/2rightarrow.png"); ImageIcon icon = ResourceManager.loadImage("images/2rightarrow.png");
sendSelectedToClipboardAction.setPopupMenuData( sendSelectedToClipboardAction.setPopupMenuData(
@ -168,7 +166,7 @@ public abstract class ByteSequenceAnalyzerProvider extends DialogComponentProvid
} }
private void addMergeAction() { private void addMergeAction() {
mergeAction = new DockingAction("Merge Selected Rows", title, false) { mergeAction = new DockingAction("Merge Selected Rows", title) {
@Override @Override
public void actionPerformed(ActionContext context) { public void actionPerformed(ActionContext context) {
merged = byteSequenceTable.mergeSelectedRows(); merged = byteSequenceTable.mergeSelectedRows();
@ -203,7 +201,7 @@ public abstract class ByteSequenceAnalyzerProvider extends DialogComponentProvid
} }
private void addSendMergedToClipboardAction() { private void addSendMergedToClipboardAction() {
sendMergedToClipboardAction = new DockingAction("Send Merged to Clipboard", title, false) { sendMergedToClipboardAction = new DockingAction("Send Merged to Clipboard", title) {
@Override @Override
public void actionPerformed(ActionContext context) { public void actionPerformed(ActionContext context) {
if (merged != null) { if (merged != null) {

View file

@ -78,7 +78,7 @@ public class ClosedPatternTableDialog extends DialogComponentProvider {
private JPanel createMainPanel() { private JPanel createMainPanel() {
JPanel panel = new JPanel(new BorderLayout()); JPanel panel = new JPanel(new BorderLayout());
GThreadedTablePanel<ClosedPatternRowObject> table = GThreadedTablePanel<ClosedPatternRowObject> table =
new GThreadedTablePanel<ClosedPatternRowObject>(closedPatternTableModel); new GThreadedTablePanel<>(closedPatternTableModel);
panel.add(table, BorderLayout.CENTER); panel.add(table, BorderLayout.CENTER);
return panel; return panel;
} }
@ -89,33 +89,31 @@ public class ClosedPatternTableDialog extends DialogComponentProvider {
} }
private void addClipboardAction() { private void addClipboardAction() {
sendToClipboardAction = sendToClipboardAction = new DockingAction("Send Selected Sequences to Clipboard", TITLE) {
new DockingAction("Send Selected Sequences to Clipboard", TITLE, false) {
@Override @Override
public void actionPerformed(ActionContext context) { public void actionPerformed(ActionContext context) {
List<ClosedPatternRowObject> rows = List<ClosedPatternRowObject> rows =
closedPatternTableModel.getLastSelectedObjects(); closedPatternTableModel.getLastSelectedObjects();
for (ClosedPatternRowObject row : rows) { for (ClosedPatternRowObject row : rows) {
DittedBitSequence seq = new DittedBitSequence(row.getDittedString(), true); DittedBitSequence seq = new DittedBitSequence(row.getDittedString(), true);
PatternInfoRowObject pattern = PatternInfoRowObject pattern = new PatternInfoRowObject(type, seq, cRegFilter);
new PatternInfoRowObject(type, seq, cRegFilter); plugin.addPattern(pattern);
plugin.addPattern(pattern);
}
plugin.updateClipboard();
} }
plugin.updateClipboard();
}
@Override @Override
public boolean isAddToPopup(ActionContext context) { public boolean isAddToPopup(ActionContext context) {
return true; return true;
} }
@Override @Override
public boolean isEnabledForContext(ActionContext context) { public boolean isEnabledForContext(ActionContext context) {
return (!closedPatternTableModel.getLastSelectedObjects().isEmpty()); return (!closedPatternTableModel.getLastSelectedObjects().isEmpty());
} }
}; };
ImageIcon icon = ResourceManager.loadImage("images/2rightarrow.png"); ImageIcon icon = ResourceManager.loadImage("images/2rightarrow.png");
sendToClipboardAction.setPopupMenuData( sendToClipboardAction.setPopupMenuData(
new MenuData(new String[] { "Send Selected Sequences to Clipboard" }, icon)); new MenuData(new String[] { "Send Selected Sequences to Clipboard" }, icon));

View file

@ -62,7 +62,7 @@ public class PatternMiningAnalyzerProvider extends ByteSequenceAnalyzerProvider
} }
private void addMiningAction() { private void addMiningAction() {
mineClosedPatternsAction = new DockingAction(MINE_PATTERNS_BUTTON_TEXT, title, false) { mineClosedPatternsAction = new DockingAction(MINE_PATTERNS_BUTTON_TEXT, title) {
@Override @Override
public void actionPerformed(ActionContext context) { public void actionPerformed(ActionContext context) {
List<ByteSequenceRowObject> lastSelectedObjects = List<ByteSequenceRowObject> lastSelectedObjects =

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,36 +15,33 @@
*/ */
package ghidra.app.plugin.core.decompile.actions; package ghidra.app.plugin.core.decompile.actions;
import ghidra.app.decompiler.component.DecompilerPanel;
import ghidra.app.util.HelpTopics;
import ghidra.util.HelpLocation;
import java.awt.event.InputEvent; import java.awt.event.InputEvent;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import docking.ActionContext; import docking.ActionContext;
import docking.action.DockingAction; import docking.action.DockingAction;
import docking.action.KeyBindingData; import docking.action.KeyBindingData;
import ghidra.app.decompiler.component.DecompilerPanel;
import ghidra.app.util.HelpTopics;
import ghidra.util.HelpLocation;
/** /**
* Action for adding all fields to the current format. * Action for adding all fields to the current format.
*/ */
public class SelectAllAction extends DockingAction { public class SelectAllAction extends DockingAction {
DecompilerPanel panel; DecompilerPanel panel;
public SelectAllAction(String owner, DecompilerPanel panel) { public SelectAllAction(String owner, DecompilerPanel panel) {
super("Select All", owner, false); super("Select All", owner);
this.panel = panel; this.panel = panel;
setKeyBindingData( new KeyBindingData( setKeyBindingData(new KeyBindingData(KeyEvent.VK_A, InputEvent.CTRL_DOWN_MASK));
KeyEvent.VK_A, InputEvent.CTRL_DOWN_MASK) );
setHelpLocation(new HelpLocation(HelpTopics.SELECTION, getName())); setHelpLocation(new HelpLocation(HelpTopics.SELECTION, getName()));
} }
@Override @Override
public void actionPerformed(ActionContext context) { public void actionPerformed(ActionContext context) {
panel.selectAll(); panel.selectAll();
} }
} }

View file

@ -176,6 +176,16 @@ public abstract class AbstractDockingTool implements DockingTool {
winMgr.contextChanged(provider); winMgr.contextChanged(provider);
} }
@Override
public void addContextListener(DockingContextListener listener) {
winMgr.addContextListener(listener);
}
@Override
public void removeContextListener(DockingContextListener listener) {
winMgr.removeContextListener(listener);
}
@Override @Override
public DockingWindowManager getWindowManager() { public DockingWindowManager getWindowManager() {
return winMgr; return winMgr;

View file

@ -165,7 +165,7 @@ public class ActionToGuiMapper {
/** /**
* Close all menus (includes popup menus) * Close all menus (includes popup menus)
*/ */
static void dismissMenus() { private void dismissMenus() {
MenuSelectionManager.defaultManager().clearSelectedPath(); MenuSelectionManager.defaultManager().clearSelectedPath();
} }

View file

@ -159,7 +159,8 @@ public abstract class ComponentProvider implements HelpDescriptor, ActionContext
return; return;
} }
showProviderAction = new ShowProviderAction(); boolean supportsKeyBindings = !isTransient;
showProviderAction = new ShowProviderAction(supportsKeyBindings);
} }
/** /**
@ -550,15 +551,14 @@ public abstract class ComponentProvider implements HelpDescriptor, ActionContext
4) Wire default 'close' action to keybinding 4) Wire default 'close' action to keybinding
5) Add global action for (show last provider) 5) Add global action for (show last provider)
--Navigation menu? --Navigation menu?
6) Revisit all uses of the key binding managed constructor
7) Update table popup actions to be managed
8) Update help locations
Questions: Questions:
C) How to wire universal close action (it is focus-dependent) C) How to wire universal close action (it is focus-dependent)
Fix:
-Update key binding methods to use an enum for: no management / full management / shared management
*/ */
dockingTool.getWindowManager().setIcon(this, icon); dockingTool.getWindowManager().setIcon(this, icon);
@ -775,8 +775,9 @@ public abstract class ComponentProvider implements HelpDescriptor, ActionContext
private class ShowProviderAction extends DockingAction { private class ShowProviderAction extends DockingAction {
ShowProviderAction() { ShowProviderAction(boolean supportsKeyBindings) {
super(name, owner); super(name, owner,
supportsKeyBindings ? KeyBindingType.SHARED : KeyBindingType.UNSUPPORTED);
if (isToolbarAction) { if (isToolbarAction) {
setToolBarData(new ToolBarData(icon, TOOLBAR_GROUP)); setToolBarData(new ToolBarData(icon, TOOLBAR_GROUP));
@ -796,17 +797,6 @@ public abstract class ComponentProvider implements HelpDescriptor, ActionContext
dockingTool.showComponentProvider(ComponentProvider.this, true); dockingTool.showComponentProvider(ComponentProvider.this, true);
} }
@Override
public boolean isKeyBindingManaged() {
return false;
}
@Override
public boolean usesSharedKeyBinding() {
// we do not allow transient providers to have key bindings
return !isTransient;
}
@Override @Override
protected String getInceptionFromTheFirstClassThatIsNotUs() { protected String getInceptionFromTheFirstClassThatIsNotUs() {
// overridden to show who created the provider, as that is what this action represents // overridden to show who created the provider, as that is what this action represents

View file

@ -102,7 +102,7 @@ public class DialogComponentProviderPopupActionManager {
Object source = actionContext.getSourceObject(); Object source = actionContext.getSourceObject();
if (source instanceof DockingActionProviderIf) { if (source instanceof DockingActionProviderIf) {
DockingActionProviderIf actionProvider = (DockingActionProviderIf) source; DockingActionProviderIf actionProvider = (DockingActionProviderIf) source;
List<DockingActionIf> dockingActions = actionProvider.getDockingActions(actionContext); List<DockingActionIf> dockingActions = actionProvider.getDockingActions();
for (DockingActionIf action : dockingActions) { for (DockingActionIf action : dockingActions) {
MenuData popupMenuData = action.getPopupMenuData(); MenuData popupMenuData = action.getPopupMenuData();
if (popupMenuData != null && action.isValidContext(actionContext) && if (popupMenuData != null && action.isValidContext(actionContext) &&

View file

@ -200,8 +200,8 @@ public class DockingActionProxy
} }
@Override @Override
public boolean isKeyBindingManaged() { public KeyBindingType getKeyBindingType() {
return dockingAction.isKeyBindingManaged(); return dockingAction.getKeyBindingType();
} }
@Override @Override

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,18 @@
*/ */
package docking; package docking;
import docking.action.DockingActionIf;
/**
* A listener to be notified when the tool's context changes. Normally context is used to
* manage {@link DockingActionIf} enablement directly by the system. This class allows
* clients to listen to context change as well.
*/
public interface DockingContextListener { public interface DockingContextListener {
void contextChanged(ActionContext context);
/**
* Called when the context changes
* @param context the context
*/
public void contextChanged(ActionContext context);
} }

View file

@ -209,6 +209,18 @@ public interface DockingTool {
*/ */
public void contextChanged(ComponentProvider provider); public void contextChanged(ComponentProvider provider);
/**
* Adds the given context listener to this tool
* @param listener the listener to add
*/
public void addContextListener(DockingContextListener listener);
/**
* Removes the given context listener to this tool
* @param listener the listener to add
*/
public void removeContextListener(DockingContextListener listener);
/** /**
* Returns the DockingWindowManger for this tool. * Returns the DockingWindowManger for this tool.
* @return the DockingWindowManger for this tool. * @return the DockingWindowManger for this tool.

View file

@ -2089,8 +2089,7 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
contextListeners.remove(listener); contextListeners.remove(listener);
} }
public void notifyContextListeners(ComponentPlaceholder placeHolder, void notifyContextListeners(ComponentPlaceholder placeHolder, ActionContext actionContext) {
ActionContext actionContext) {
if (placeHolder == focusedPlaceholder) { if (placeHolder == focusedPlaceholder) {
for (DockingContextListener listener : contextListeners) { for (DockingContextListener listener : contextListeners) {

View file

@ -425,7 +425,9 @@ class KeyBindingOverrideKeyEventDispatcher implements KeyEventDispatcher {
} }
KeyStroke keyStroke = KeyStroke.getKeyStrokeForEvent(event); KeyStroke keyStroke = KeyStroke.getKeyStrokeForEvent(event);
return (DockingKeyBindingAction) activeManager.getActionForKeyStroke(keyStroke); DockingKeyBindingAction bindingAction =
(DockingKeyBindingAction) activeManager.getActionForKeyStroke(keyStroke);
return bindingAction;
} }
private DockingWindowManager getActiveDockingWindowManager() { private DockingWindowManager getActiveDockingWindowManager() {

View file

@ -101,7 +101,7 @@ public class PopupActionManager implements PropertyChangeListener {
Object source = actionContext.getSourceObject(); Object source = actionContext.getSourceObject();
if (source instanceof DockingActionProviderIf) { if (source instanceof DockingActionProviderIf) {
DockingActionProviderIf actionProvider = (DockingActionProviderIf) source; DockingActionProviderIf actionProvider = (DockingActionProviderIf) source;
List<DockingActionIf> dockingActions = actionProvider.getDockingActions(actionContext); List<DockingActionIf> dockingActions = actionProvider.getDockingActions();
for (DockingActionIf action : dockingActions) { for (DockingActionIf action : dockingActions) {
MenuData popupMenuData = action.getPopupMenuData(); MenuData popupMenuData = action.getPopupMenuData();
if (popupMenuData != null && action.isValidContext(actionContext) && if (popupMenuData != null && action.isValidContext(actionContext) &&

View file

@ -50,24 +50,26 @@ class ShowComponentAction extends DockingAction implements Comparable<ShowCompon
super(truncateTitleAsNeeded(name), DockingWindowManager.DOCKING_WINDOWS_OWNER); super(truncateTitleAsNeeded(name), DockingWindowManager.DOCKING_WINDOWS_OWNER);
} }
ShowComponentAction(DockingWindowManager winMgr, ComponentPlaceholder info, String subMenuName, ShowComponentAction(DockingWindowManager winMgr, ComponentPlaceholder placeholder,
boolean isTransient) { String subMenuName, boolean isTransient) {
super(info.getProvider().getName(), DockingWindowManager.DOCKING_WINDOWS_OWNER); super(placeholder.getProvider().getName(), DockingWindowManager.DOCKING_WINDOWS_OWNER,
createKeyBindingType(isTransient, placeholder));
this.info = info; this.info = placeholder;
this.winMgr = winMgr; this.winMgr = winMgr;
this.title = truncateTitleAsNeeded(info.getTitle()); this.title = truncateTitleAsNeeded(placeholder.getTitle());
this.isTransient = isTransient; this.isTransient = isTransient;
String group = isTransient ? "Transient" : "Permanent"; String group = isTransient ? "Transient" : "Permanent";
Icon icon = info.getIcon(); Icon icon = placeholder.getIcon();
if (icon == null) { if (icon == null) {
icon = EMPTY_ICON; icon = EMPTY_ICON;
} }
if (subMenuName != null) { if (subMenuName != null) {
setMenuBarData(new MenuData( setMenuBarData(
new String[] { MENU_WINDOW, subMenuName, info.getFullTitle() }, icon, "Permanent")); new MenuData(new String[] { MENU_WINDOW, subMenuName, placeholder.getFullTitle() },
icon, "Permanent"));
winMgr.doSetMenuGroup(new String[] { MENU_WINDOW, subMenuName }, group); winMgr.doSetMenuGroup(new String[] { MENU_WINDOW, subMenuName }, group);
} }
else { else {
@ -75,7 +77,7 @@ class ShowComponentAction extends DockingAction implements Comparable<ShowCompon
} }
// keybinding data used to show the binding in the menu // keybinding data used to show the binding in the menu
ComponentProvider provider = info.getProvider(); ComponentProvider provider = placeholder.getProvider();
DockingActionIf action = provider.getShowProviderAction(); DockingActionIf action = provider.getShowProviderAction();
KeyBindingData kbData = action.getKeyBindingData(); KeyBindingData kbData = action.getKeyBindingData();
if (kbData != null) { if (kbData != null) {
@ -94,19 +96,15 @@ class ShowComponentAction extends DockingAction implements Comparable<ShowCompon
} }
} }
@Override private static KeyBindingType createKeyBindingType(boolean isTransient,
public boolean isKeyBindingManaged() { ComponentPlaceholder placeholder) {
return false;
}
@Override
public boolean usesSharedKeyBinding() {
if (isTransient) { if (isTransient) {
return false; // temporary window return KeyBindingType.UNSUPPORTED; // temporary window
} }
// 'info' is null when this action is used to 'show all' instances of a given provider // 'info' is null when this action is used to 'show all' instances of a given provider
return info != null; return placeholder == null ? KeyBindingType.UNSUPPORTED : KeyBindingType.SHARED;
} }
@Override @Override

View file

@ -96,9 +96,6 @@ public class WindowActionManager {
toolBarMgr.dispose(); toolBarMgr.dispose();
} }
/**
* Notifies the window manager that an action context update is needed.
*/
synchronized void contextChanged(ComponentPlaceholder placeHolder) { synchronized void contextChanged(ComponentPlaceholder placeHolder) {
placeHolderForScheduledActionUpdate = placeHolder; placeHolderForScheduledActionUpdate = placeHolder;

View file

@ -17,6 +17,7 @@ package docking.action;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import javax.swing.*; import javax.swing.*;
@ -63,8 +64,8 @@ public abstract class DockingAction implements DockingActionIf {
private String inceptionInformation; private String inceptionInformation;
private boolean isEnabled = true; private boolean isEnabled = true;
private boolean isKeyBindingManaged = true;
private KeyBindingType keyBindingType = KeyBindingType.INDIVIDUAL;
private KeyBindingData defaultKeyBindingData; private KeyBindingData defaultKeyBindingData;
private KeyBindingData keyBindingData; private KeyBindingData keyBindingData;
private MenuBarData menuBarData; private MenuBarData menuBarData;
@ -72,19 +73,29 @@ public abstract class DockingAction implements DockingActionIf {
private ToolBarData toolBarData; private ToolBarData toolBarData;
public DockingAction(String name, String owner) { public DockingAction(String name, String owner) {
this(name, owner, true);
}
public DockingAction(String name, String owner, boolean isKeyBindingManaged) {
this.name = name; this.name = name;
this.owner = owner; this.owner = owner;
this.isKeyBindingManaged = isKeyBindingManaged;
recordInception(); recordInception();
HelpLocation location = new HelpLocation(owner, name, inceptionInformation); HelpLocation location = new HelpLocation(owner, name, inceptionInformation);
setHelpLocation(location); setHelpLocation(location);
} }
public DockingAction(String name, String owner, KeyBindingType kbType) {
this(name, owner);
this.keyBindingType = Objects.requireNonNull(kbType);
}
public DockingAction(String name, String owner, boolean supportsKeyBindings) {
this(name, owner);
this.keyBindingType =
supportsKeyBindings ? KeyBindingType.INDIVIDUAL : KeyBindingType.UNSUPPORTED;
}
protected KeyBindingType getPreferredKeyBindingType() {
return KeyBindingType.INDIVIDUAL;
}
@Override @Override
public abstract void actionPerformed(ActionContext context); public abstract void actionPerformed(ActionContext context);
@ -98,11 +109,6 @@ public abstract class DockingAction implements DockingActionIf {
propertyListeners.remove(listener); propertyListeners.remove(listener);
} }
@Override
public boolean isKeyBindingManaged() {
return isKeyBindingManaged;
}
@Override @Override
public String getDescription() { public String getDescription() {
return description; return description;
@ -258,6 +264,11 @@ public abstract class DockingAction implements DockingActionIf {
return menuItem; return menuItem;
} }
@Override
public KeyBindingType getKeyBindingType() {
return keyBindingType;
}
@Override @Override
public KeyStroke getKeyBinding() { public KeyStroke getKeyBinding() {
return keyBindingData == null ? null : keyBindingData.getKeyBinding(); return keyBindingData == null ? null : keyBindingData.getKeyBinding();

View file

@ -23,6 +23,17 @@ import javax.swing.*;
import docking.ActionContext; import docking.ActionContext;
import docking.help.HelpDescriptor; import docking.help.HelpDescriptor;
/**
* The base interface for clients that wish to create commands to be registered with a tool.
*
* <p>An action may appear in a primary menu, a popup menu or a toolbar. Further, an action
* may have a key binding assigned.
*
* <p>The particular support for key bindings is defined by {@link KeyBindingType}. Almost all
* client actions will use the default setting of {@link KeyBindingType#INDIVIDUAL}. To control
* the level of key binding support, you can pass the desired {@link KeyBindingType} to the
* base implementation of this interface.
*/
public interface DockingActionIf extends HelpDescriptor { public interface DockingActionIf extends HelpDescriptor {
public static final String ENABLEMENT_PROPERTY = "enabled"; public static final String ENABLEMENT_PROPERTY = "enabled";
public static final String GLOBALCONTEXT_PROPERTY = "globalContext"; public static final String GLOBALCONTEXT_PROPERTY = "globalContext";
@ -248,10 +259,17 @@ public interface DockingActionIf extends HelpDescriptor {
public boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes); public boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes);
/** /**
* Returns true if this action can have its keybinding information changed by the user. * Returns this actions level of support for key binding accelerator keys
* @return true if this action can have its keybinding information changed by the user. *
* <p>Actions support key bindings by default. Some reserved actions do not support
* key bindings, while others wish to share the same key bindings with multiple, equivalent
* actions (this allows the user to set one binding that works in many different contexts).
*
* @return the key binding support
*/ */
public boolean isKeyBindingManaged(); public default KeyBindingType getKeyBindingType() {
return KeyBindingType.INDIVIDUAL;
}
/** /**
* Sets the {@link KeyBindingData} on an action to either assign a keybinding or remove it * Sets the {@link KeyBindingData} on an action to either assign a keybinding or remove it
@ -272,22 +290,4 @@ public interface DockingActionIf extends HelpDescriptor {
* @param newKeyBindingData the KeyBindingData to be used to assign this action to a keybinding * @param newKeyBindingData the KeyBindingData to be used to assign this action to a keybinding
*/ */
public void setUnvalidatedKeyBindingData(KeyBindingData newKeyBindingData); public void setUnvalidatedKeyBindingData(KeyBindingData newKeyBindingData);
/**
* Returns true if this action shares a keybinding with other actions. If this returns true,
* then this action, and any action that shares a name with this action, will be updated
* to the same key binding value whenever the key binding options change.
*
* <p>This will be false for the vast majority of actions. If you are unsure if your action
* should use a shared keybinding, then do not set this value to true.
*
* <p>This value is not meant to change over the life of the action. Thus, there is no
* <code>set</code> method to change this value. Rather, you should override this method
* to return <code>true</code> as desired.
*
* @return true to share a shared keybinding
*/
public default boolean usesSharedKeyBinding() {
return false;
}
} }

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.
@ -18,8 +17,6 @@ package docking.action;
import java.util.List; import java.util.List;
import docking.ActionContext;
/** /**
* An interface for objects (really Components) to implement that signals they provide actions * An interface for objects (really Components) to implement that signals they provide actions
* for the Docking environment. This interface will be called when the implementor is the source * for the Docking environment. This interface will be called when the implementor is the source
@ -32,9 +29,9 @@ import docking.ActionContext;
*/ */
public interface DockingActionProviderIf { public interface DockingActionProviderIf {
/** /**
* Returns actions that are compatible with the given context. * Returns actions that are compatible with the given context.
* @param context the current context of the Docking system * @return the actions
*/ */
public List<DockingActionIf> getDockingActions( ActionContext context ); public List<DockingActionIf> getDockingActions();
} }

View file

@ -0,0 +1,82 @@
/* ###
* 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.action;
/**
* Allows clients to signal their support for the assigning of key binding shortcut keys. Most
* action clients need not be concerned with this class. The default settings of
* {@link DockingAction} work correctly for almost all cases, which is to have the action
* support individual key bindings, which are managed by the system via the UI.
*
* @see DockingActionIf
*/
public enum KeyBindingType {
//@formatter:off
/**
* Indicates the setting of key bindings through the UI is not supported
*/
UNSUPPORTED,
/**
* Supports the assignment of key bindings via the UI. Setting a key binding on an action
* with this type will not affect any other action.
*/
INDIVIDUAL,
/**
* When the key binding is set via the UI, this action, and any action that shares a
* name with this action, will be updated to the same key binding value whenever the key
* binding options change.
*
* <p>Most actions will not be shared. If you are unsure if your action
* should use a shared keybinding, then do not do so.
*/
SHARED;
//@formatter:on
/**
* Returns true if this type supports key bindings. This is a convenience method for
* checking that this type is not {@link #UNSUPPORTED}.
* @return true if key bindings are supported
*/
public boolean supportsKeyBindings() {
return this != UNSUPPORTED;
}
/**
* Convenience method for checking if this type is the {@link #SHARED} type
* @return true if shared
*/
public boolean isShared() {
return this == SHARED;
}
/**
* A convenience method for clients to check whether this key binding type should be
* managed directly by the system.
*
* <p>Shared actions are not managed directly by the system, but are instead managed through
* a proxy action.
*
* @return true if managed directly by the system; false if key binding are not supported
* or are managed through a proxy
*/
public boolean isManaged() {
return this == INDIVIDUAL;
}
}

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.
@ -29,14 +28,16 @@ public abstract class ToggleDockingAction extends DockingAction implements Toggl
super(name, owner); super(name, owner);
} }
public ToggleDockingAction(String name, String owner, boolean isKeybindingManaged) { public ToggleDockingAction(String name, String owner, boolean supportsKeyBindings) {
super(name, owner, isKeybindingManaged); super(name, owner, supportsKeyBindings);
} }
@Override
public boolean isSelected() { public boolean isSelected() {
return isSelected; return isSelected;
} }
@Override
public void setSelected(boolean newValue) { public void setSelected(boolean newValue) {
isSelected = newValue; isSelected = newValue;
firePropertyChanged(SELECTED_STATE_PROPERTY, !isSelected, isSelected); firePropertyChanged(SELECTED_STATE_PROPERTY, !isSelected, isSelected);

View file

@ -49,7 +49,7 @@ public class KeyBindingAction extends DockingAction {
action = maybeGetToolLevelAction(action); action = maybeGetToolLevelAction(action);
if (!action.isKeyBindingManaged()) { if (!action.getKeyBindingType().supportsKeyBindings()) {
Component parent = windowManager.getActiveComponent(); Component parent = windowManager.getActiveComponent();
Msg.showInfo(getClass(), parent, "Unable to Set Keybinding", Msg.showInfo(getClass(), parent, "Unable to Set Keybinding",
"Action \"" + getActionName(action) + "\" is not keybinding managed and thus a " + "Action \"" + getActionName(action) + "\" is not keybinding managed and thus a " +
@ -68,15 +68,15 @@ public class KeyBindingAction extends DockingAction {
* @return A tool-level action if one is found; otherwise, the original action * @return A tool-level action if one is found; otherwise, the original action
*/ */
private DockingActionIf maybeGetToolLevelAction(DockingActionIf dockingAction) { private DockingActionIf maybeGetToolLevelAction(DockingActionIf dockingAction) {
if (dockingAction.isKeyBindingManaged()) {
return dockingAction;
}
// It is not key binding managed, which means that it may be a shared key binding if (dockingAction.getKeyBindingType().isShared()) {
String actionName = dockingAction.getName();
DockingActionIf sharedAction = toolActions.getSharedStubKeyBindingAction(actionName); // It is not key binding managed, which means that it may be a shared key binding
if (sharedAction != null) { String actionName = dockingAction.getName();
return sharedAction; DockingActionIf sharedAction = toolActions.getSharedStubKeyBindingAction(actionName);
if (sharedAction != null) {
return sharedAction;
}
} }
return dockingAction; return dockingAction;

View file

@ -345,7 +345,7 @@ public class KeyBindingUtils {
/** /**
* A utility method to get all key binding actions. This method will remove duplicate * A utility method to get all key binding actions. This method will remove duplicate
* actions and will only return actions that are {@link DockingActionIf#isKeyBindingManaged()} * actions and will only return actions that support {@link KeyBindingType key bindings}.
* *
* @param tool the tool containing the actions * @param tool the tool containing the actions
* @return the actions mapped by their full name (e.g., 'Name (OwnerName)') * @return the actions mapped by their full name (e.g., 'Name (OwnerName)')
@ -371,7 +371,7 @@ public class KeyBindingUtils {
/** /**
* A utility method to get all key binding actions that have the given owner. * A utility method to get all key binding actions that have the given owner.
* This method will remove duplicate actions and will only return actions * This method will remove duplicate actions and will only return actions
* that are {@link DockingActionIf#isKeyBindingManaged()} * that support {@link KeyBindingType key bindings}.
* *
* @param tool the tool containing the actions * @param tool the tool containing the actions
* @param owner the action owner name * @param owner the action owner name
@ -718,9 +718,9 @@ public class KeyBindingUtils {
//================================================================================================== //==================================================================================================
private static boolean isIgnored(DockingActionIf action) { private static boolean isIgnored(DockingActionIf action) {
// not keybinding managed; a shared keybinding implies that this action should not be in // a shared keybinding implies that this action should not be in
// the UI, as there will be a single proxy in place of all actions sharing that binding // the UI, as there will be a single proxy in place of all actions sharing that binding
return !action.isKeyBindingManaged() || action.usesSharedKeyBinding(); return action.getKeyBindingType().isShared();
} }
private static KeyStroke getKeyStroke(KeyBindingData data) { private static KeyStroke getKeyStroke(KeyBindingData data) {

View file

@ -22,7 +22,8 @@ import java.util.List;
import javax.swing.*; import javax.swing.*;
import javax.swing.text.*; import javax.swing.text.*;
import docking.*; import docking.DialogComponentProvider;
import docking.KeyEntryTextField;
import docking.action.*; import docking.action.*;
import docking.widgets.label.GIconLabel; import docking.widgets.label.GIconLabel;
import ghidra.util.HelpLocation; import ghidra.util.HelpLocation;
@ -157,21 +158,7 @@ public class KeyEntryDialog extends DialogComponentProvider {
return; return;
} }
KeyBindingData kbData = new KeyBindingData(newKeyStroke); action.setUnvalidatedKeyBindingData(new KeyBindingData(newKeyStroke));
if (action instanceof SharedStubKeyBindingAction) {
action.setUnvalidatedKeyBindingData(kbData);
}
else {
Set<DockingActionIf> allActions = toolActions.getAllActions();
Set<DockingActionIf> actions =
KeyBindingUtils.getActions(allActions, action.getOwner(), action.getName());
for (DockingActionIf element : actions) {
if (element.isKeyBindingManaged()) {
element.setUnvalidatedKeyBindingData(kbData);
}
}
}
toolActions.keyBindingsChanged(); toolActions.keyBindingsChanged();
@ -248,11 +235,6 @@ public class KeyEntryDialog extends DialogComponentProvider {
} }
private boolean shouldAddAction(DockingActionIf dockableAction) { private boolean shouldAddAction(DockingActionIf dockableAction) {
if (dockableAction.isKeyBindingManaged()) { return dockableAction.getKeyBindingType().isManaged();
return true;
}
// shared key bindings are handled specially
return !dockableAction.usesSharedKeyBinding();
} }
} }

View file

@ -22,8 +22,12 @@ import java.util.*;
import javax.swing.Action; import javax.swing.Action;
import javax.swing.KeyStroke; import javax.swing.KeyStroke;
import org.apache.commons.collections4.IteratorUtils;
import org.apache.commons.collections4.Predicate;
import org.apache.commons.collections4.map.LazyMap; import org.apache.commons.collections4.map.LazyMap;
import com.google.common.collect.Iterators;
import docking.*; import docking.*;
import docking.action.*; import docking.action.*;
import docking.tool.util.DockingToolConstants; import docking.tool.util.DockingToolConstants;
@ -113,12 +117,13 @@ public class ToolActions implements PropertyChangeListener {
private void setKeyBindingOption(DockingActionIf action) { private void setKeyBindingOption(DockingActionIf action) {
if (action.usesSharedKeyBinding()) { KeyBindingType type = action.getKeyBindingType();
installSharedKeyBinding(action); if (!type.supportsKeyBindings()) {
return; return;
} }
if (!action.isKeyBindingManaged()) { if (type.isShared()) {
installSharedKeyBinding(action);
return; return;
} }
@ -227,25 +232,47 @@ public class ToolActions implements PropertyChangeListener {
return result; return result;
} }
private Iterator<DockingActionIf> getAllActionsIterator() {
// chain all items together, rather than copy the data
Iterator<DockingActionIf> iterator = IteratorUtils.emptyIterator();
Collection<Map<String, Set<DockingActionIf>>> maps = actionsByNameByOwner.values();
for (Map<String, Set<DockingActionIf>> actionsByName : maps) {
for (Set<DockingActionIf> actions : actionsByName.values()) {
Iterator<DockingActionIf> next = actions.iterator();
// Note: do not use apache commons here--the code below degrades exponentially
//iterator = IteratorUtils.chainedIterator(iterator, next);
iterator = Iterators.concat(iterator, next);
}
}
return Iterators.concat(iterator, sharedActionMap.values().iterator());
}
/** /**
* Get the keybindings for each action so that they are still registered as being used; * Get the keybindings for each action so that they are still registered as being used;
* otherwise the options will be removed because they are noted as not being used. * otherwise the options will be removed because they are noted as not being used.
*/ */
public synchronized void restoreKeyBindings() { public synchronized void restoreKeyBindings() {
keyBindingOptions = dockingTool.getOptions(DockingToolConstants.KEY_BINDINGS); keyBindingOptions = dockingTool.getOptions(DockingToolConstants.KEY_BINDINGS);
Set<DockingActionIf> actions = getAllActions();
for (DockingActionIf action : actions) { Iterator<DockingActionIf> it = getKeyBindingActionsIterator();
if (!action.isKeyBindingManaged()) { for (DockingActionIf action : CollectionUtils.asIterable(it)) {
continue;
}
KeyStroke ks = action.getKeyBinding(); KeyStroke ks = action.getKeyBinding();
KeyStroke newKs = keyBindingOptions.getKeyStroke(action.getFullName(), ks); KeyStroke newKs = keyBindingOptions.getKeyStroke(action.getFullName(), ks);
if (ks != newKs) { if (!Objects.equals(ks, newKs)) {
action.setUnvalidatedKeyBindingData(new KeyBindingData(newKs)); action.setUnvalidatedKeyBindingData(new KeyBindingData(newKs));
} }
} }
} }
// return only actions that allow key bindings
private Iterator<DockingActionIf> getKeyBindingActionsIterator() {
Predicate<DockingActionIf> filter = a -> a.getKeyBindingType() == KeyBindingType.INDIVIDUAL;
return IteratorUtils.filteredIterator(getAllActionsIterator(), filter);
}
/** /**
* Remove an action that works specifically with a component provider. * Remove an action that works specifically with a component provider.
* @param provider provider associated with the action * @param provider provider associated with the action
@ -272,11 +299,13 @@ public class ToolActions implements PropertyChangeListener {
private void removeAction(DockingActionIf action) { private void removeAction(DockingActionIf action) {
getActionStorage(action).remove(action); getActionStorage(action).remove(action);
if (action.usesSharedKeyBinding()) { if (!action.getKeyBindingType().isShared()) {
SharedStubKeyBindingAction stub = sharedActionMap.get(action.getName()); return;
if (stub != null) { }
stub.removeClientAction(action);
} SharedStubKeyBindingAction stub = sharedActionMap.get(action.getName());
if (stub != null) {
stub.removeClientAction(action);
} }
} }
@ -293,7 +322,7 @@ public class ToolActions implements PropertyChangeListener {
} }
DockingAction action = (DockingAction) evt.getSource(); DockingAction action = (DockingAction) evt.getSource();
if (!action.isKeyBindingManaged()) { if (!action.getKeyBindingType().isManaged()) {
// this reads unusually, but we need to notify the tool to rebuild its 'Window' menu // this reads unusually, but we need to notify the tool to rebuild its 'Window' menu
// in the case that this action is one of the tool's special actions // in the case that this action is one of the tool's special actions
keyBindingsChanged(); keyBindingsChanged();

View file

@ -15,9 +15,9 @@
*/ */
package docking.widgets.table; package docking.widgets.table;
import static docking.DockingUtils.*; import static docking.DockingUtils.CONTROL_KEY_MODIFIER_MASK;
import static docking.action.MenuData.*; import static docking.action.MenuData.NO_MNEMONIC;
import static java.awt.event.InputEvent.*; import static java.awt.event.InputEvent.SHIFT_DOWN_MASK;
import java.awt.*; import java.awt.*;
import java.awt.event.*; import java.awt.event.*;
@ -509,23 +509,14 @@ public class GTable extends JTable implements KeyStrokeConsumer, DockingActionPr
return autoLookupKeyStrokeConsumer.isKeyConsumed(keyStroke); return autoLookupKeyStrokeConsumer.isKeyConsumed(keyStroke);
} }
/**
* {@inheritDoc}
*/
@Override @Override
public List<DockingActionIf> getDockingActions(ActionContext context) { public List<DockingActionIf> getDockingActions() {
Object sourceObject = context.getSourceObject();
if (sourceObject != this) {
// we are only interested in providing actions when we are the source of the event
return Collections.emptyList();
}
return getDefaultDockingActions(); return getDefaultDockingActions();
} }
/** /**
* Returns the default actions of this table. Normally, the Docking Windows systems uses * Returns the default actions of this table. Normally, the Docking Windows systems uses
* {@link #getDockingActions(ActionContext)} to get the correct actions to show. However, * {@link #getDockingActions()} to get the correct actions to show. However,
* there are some cases where clients override what appears when you click on a table (such * there are some cases where clients override what appears when you click on a table (such
* as in {@link DialogComponentProvider}s. For those clients that are creating their own * as in {@link DialogComponentProvider}s. For those clients that are creating their own
* action building, they need a way to get the default actions, hence this method. * action building, they need a way to get the default actions, hence this method.
@ -1178,7 +1169,8 @@ public class GTable extends JTable implements KeyStrokeConsumer, DockingActionPr
int subGroupIndex = 1; // order by insertion int subGroupIndex = 1; // order by insertion
String owner = getClass().getSimpleName(); String owner = getClass().getSimpleName();
copyAction = new DockingAction("Table Data Copy", owner, false) { owner = "GTable";
copyAction = new DockingAction("Table Data Copy", owner, KeyBindingType.SHARED) {
@Override @Override
public void actionPerformed(ActionContext context) { public void actionPerformed(ActionContext context) {
copying = true; copying = true;
@ -1209,7 +1201,7 @@ public class GTable extends JTable implements KeyStrokeConsumer, DockingActionPr
//@formatter:on //@formatter:on
copyCurrentColumnAction = copyCurrentColumnAction =
new DockingAction("Table Data Copy Current Column", owner, false) { new DockingAction("Table Data Copy Current Column", owner, KeyBindingType.SHARED) {
@Override @Override
public void actionPerformed(ActionContext context) { public void actionPerformed(ActionContext context) {
@ -1246,17 +1238,18 @@ public class GTable extends JTable implements KeyStrokeConsumer, DockingActionPr
copyCurrentColumnAction.setHelpLocation(new HelpLocation("Tables", "Copy_Current_Column")); copyCurrentColumnAction.setHelpLocation(new HelpLocation("Tables", "Copy_Current_Column"));
//@formatter:on //@formatter:on
copyColumnsAction = new DockingAction("Table Data Copy by Columns", owner, false) { copyColumnsAction =
@Override new DockingAction("Table Data Copy by Columns", owner, KeyBindingType.SHARED) {
public void actionPerformed(ActionContext context) { @Override
int[] userColumns = promptUserForColumns(); public void actionPerformed(ActionContext context) {
if (userColumns == null) { int[] userColumns = promptUserForColumns();
return; // cancelled if (userColumns == null) {
} return; // cancelled
}
copyColumns(userColumns); copyColumns(userColumns);
} }
}; };
//@formatter:off //@formatter:off
copyColumnsAction.setPopupMenuData(new MenuData( copyColumnsAction.setPopupMenuData(new MenuData(
new String[] { "Copy", "Copy Columns..." }, new String[] { "Copy", "Copy Columns..." },
@ -1269,7 +1262,7 @@ public class GTable extends JTable implements KeyStrokeConsumer, DockingActionPr
copyColumnsAction.setHelpLocation(new HelpLocation("Tables", "Copy_Columns")); copyColumnsAction.setHelpLocation(new HelpLocation("Tables", "Copy_Columns"));
//@formatter:on //@formatter:on
exportAction = new DockingAction("Table Data CSV Export", owner, false) { exportAction = new DockingAction("Table Data CSV Export", owner, KeyBindingType.SHARED) {
@Override @Override
public void actionPerformed(ActionContext context) { public void actionPerformed(ActionContext context) {
File file = chooseExportFile(); File file = chooseExportFile();
@ -1291,7 +1284,7 @@ public class GTable extends JTable implements KeyStrokeConsumer, DockingActionPr
//@formatter:on //@formatter:on
exportColumnsAction = exportColumnsAction =
new DockingAction("Table Data CSV Export (by Columns)", owner, false) { new DockingAction("Table Data CSV Export (by Columns)", owner, KeyBindingType.SHARED) {
@Override @Override
public void actionPerformed(ActionContext context) { public void actionPerformed(ActionContext context) {
int[] userColumns = promptUserForColumns(); int[] userColumns = promptUserForColumns();
@ -1323,7 +1316,7 @@ public class GTable extends JTable implements KeyStrokeConsumer, DockingActionPr
exportColumnsAction.setHelpLocation(new HelpLocation("Tables", "ExportCSV_Columns")); exportColumnsAction.setHelpLocation(new HelpLocation("Tables", "ExportCSV_Columns"));
//@formatter:on //@formatter:on
selectAllAction = new DockingAction("Table Select All", owner, false) { selectAllAction = new DockingAction("Table Select All", owner, KeyBindingType.SHARED) {
@Override @Override
public void actionPerformed(ActionContext context) { public void actionPerformed(ActionContext context) {
selectAll(); selectAll();

View file

@ -356,7 +356,7 @@ public class SharedKeyBindingDockingActionTest extends AbstractDockingTest {
//================================================================================================== //==================================================================================================
private void assertSharedStubInTool() { private void assertSharedStubInTool() {
ToolActions actionManager = (ToolActions) getInstanceField("actionMgr", tool); ToolActions actionManager = (ToolActions) getInstanceField("toolActions", tool);
DockingActionIf action = actionManager.getSharedStubKeyBindingAction(SHARED_NAME); DockingActionIf action = actionManager.getSharedStubKeyBindingAction(SHARED_NAME);
assertNotNull("Shared action stub is not in the tool", action); assertNotNull("Shared action stub is not in the tool", action);
} }
@ -426,16 +426,8 @@ public class SharedKeyBindingDockingActionTest extends AbstractDockingTest {
private class TestAction extends DockingAction { private class TestAction extends DockingAction {
public TestAction(String owner, KeyStroke ks) { public TestAction(String owner, KeyStroke ks) {
super(SHARED_NAME, owner); super(SHARED_NAME, owner, KeyBindingType.SHARED);
setKeyBindingData(new KeyBindingData(ks));
if (ks != null) {
setKeyBindingData(new KeyBindingData(ks));
}
}
@Override
public boolean usesSharedKeyBinding() {
return true;
} }
@Override @Override

View file

@ -490,7 +490,10 @@ public class ProjectDataTablePanel extends JPanel {
} }
@Override @Override
public List<DockingActionIf> getDockingActions(ActionContext context) { public List<DockingActionIf> getDockingActions() {
// TODO we should at least add the 'copy' action
// the table's default actions aren't that useful in the Front End // the table's default actions aren't that useful in the Front End
return Collections.emptyList(); return Collections.emptyList();
} }

View file

@ -133,7 +133,7 @@ public class VersionHistoryDialog extends DialogComponentProvider
} }
@Override @Override
public List<DockingActionIf> getDockingActions(ActionContext context) { public List<DockingActionIf> getDockingActions() {
return versionPanel.getDockingActions(context); return versionPanel.getDockingActions();
} }
} }

View file

@ -402,7 +402,7 @@ public class VersionHistoryPanel extends JPanel implements Draggable {
provider.addAction(new DeleteAction()); provider.addAction(new DeleteAction());
} }
public List<DockingActionIf> getDockingActions(ActionContext currentContext) { public List<DockingActionIf> getDockingActions() {
List<DockingActionIf> list = new ArrayList<>(table.getDefaultDockingActions()); List<DockingActionIf> list = new ArrayList<>(table.getDefaultDockingActions());
Project project = tool.getProject(); Project project = tool.getProject();
ToolChest toolChest = project.getLocalToolChest(); ToolChest toolChest = project.getLocalToolChest();

View file

@ -1464,17 +1464,6 @@ public abstract class PluginTool extends AbstractDockingTool
DockingWindowManager.showDialog(getToolFrame(), dialogComponent, centeredOnComponent); DockingWindowManager.showDialog(getToolFrame(), dialogComponent, centeredOnComponent);
} }
/**
* Returns the ComponentProvider with the given name. If more than one provider exists with the name,
* one will be returned, but it could be any one of them.
* @param name the name of the provider to return.
* @return a provider with the given name, or null if no providers with that name exist.
*/
@Override
public ComponentProvider getComponentProvider(String name) {
return winMgr.getComponentProvider(name);
}
public Window getActiveWindow() { public Window getActiveWindow() {
return winMgr.getActiveWindow(); return winMgr.getActiveWindow();
} }
@ -1483,19 +1472,6 @@ public abstract class PluginTool extends AbstractDockingTool
return winMgr.getActiveComponentProvider(); return winMgr.getActiveComponentProvider();
} }
@Override
public void contextChanged(ComponentProvider provider) {
winMgr.contextChanged(provider);
}
public void addContextListener(DockingContextListener listener) {
winMgr.addContextListener(listener);
}
public void removeContextListener(DockingContextListener listener) {
winMgr.removeContextListener(listener);
}
public void refreshKeybindings() { public void refreshKeybindings() {
toolActions.restoreKeyBindings(); toolActions.restoreKeyBindings();
} }