mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-02-18 16:40:08 +00:00
GT-3430 - Key Bindings - Updated the Function Call Trees Plugin's
actions key bindings so users can set the bindings separately
This commit is contained in:
parent
cbe5b9e9ca
commit
74b67be5ed
@ -1049,7 +1049,6 @@ src/main/resources/images/functions.gif||GHIDRA||||END|
|
||||
src/main/resources/images/go-down.tango.16.png||Tango Icons - Public Domain|||tango icon set|END|
|
||||
src/main/resources/images/go-home.png||Tango Icons - Public Domain|||Tango|END|
|
||||
src/main/resources/images/go-up.tango.16.png||Tango Icons - Public Domain|||tango icon set|END|
|
||||
src/main/resources/images/help-browser.png||Tango Icons - Public Domain|||tango icon set|END|
|
||||
src/main/resources/images/help-hint.png||Oxygen Icons - LGPL 3.0|||renamed from help-hing.png|END|
|
||||
src/main/resources/images/hexData.png||GHIDRA||||END|
|
||||
src/main/resources/images/house.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END|
|
||||
|
@ -374,7 +374,7 @@
|
||||
</BLOCKQUOTE>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<H2><A name="View_Check_Outs"></A>View Checkouts</H2>
|
||||
<H2><A name="View_Checkouts"></A>View Checkouts</H2>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<P>To view a list of who has a file checked out, right mouse click on the file in the Ghidra
|
||||
|
@ -21,7 +21,8 @@ import java.util.List;
|
||||
import javax.swing.Icon;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.action.*;
|
||||
import docking.action.DockingAction;
|
||||
import docking.action.MenuData;
|
||||
import ghidra.app.CorePluginPackage;
|
||||
import ghidra.app.context.ListingActionContext;
|
||||
import ghidra.app.plugin.PluginCategoryNames;
|
||||
@ -125,9 +126,9 @@ public class CallTreePlugin extends ProgramPlugin {
|
||||
private void createActions() {
|
||||
|
||||
// use the name of the provider so that the shared key binding data will get used
|
||||
String actionName = CallTreeProvider.TITLE;
|
||||
String actionName = "Static Function Call Trees";
|
||||
showCallTreeFromMenuAction =
|
||||
new DockingAction(actionName, getName(), KeyBindingType.SHARED) {
|
||||
new DockingAction(actionName, getName()) {
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
showOrCreateNewCallTree(currentLocation);
|
||||
@ -143,6 +144,8 @@ public class CallTreePlugin extends ProgramPlugin {
|
||||
new String[] { "References", "Show Call Trees" }, PROVIDER_ICON, "ShowReferencesTo"));
|
||||
showCallTreeFromMenuAction.setHelpLocation(
|
||||
new HelpLocation("CallTreePlugin", "Call_Tree_Plugin"));
|
||||
showCallTreeFromMenuAction.setDescription("Shows the Function Call Trees window for the " +
|
||||
"item under the cursor. The new window will not change along with the Listing cursor.");
|
||||
tool.addAction(showCallTreeFromMenuAction);
|
||||
}
|
||||
|
||||
|
@ -604,7 +604,7 @@ public class CallTreeProvider extends ComponentProviderAdapter implements Domain
|
||||
// Show new call tree action
|
||||
//
|
||||
DockingAction newCallTree =
|
||||
new DockingAction("Show Call Tree For Function", plugin.getName()) {
|
||||
new DockingAction("Show Call Trees For Function", plugin.getName()) {
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
GTree gTree = (GTree) context.getContextObject();
|
||||
@ -671,6 +671,8 @@ public class CallTreeProvider extends ComponentProviderAdapter implements Domain
|
||||
"Call_Tree_Context_Action_Show_Call_Tree_For_Function"));
|
||||
newCallTree.setPopupMenuData(new MenuData(new String[] { "Show Call Tree For Function" },
|
||||
CallTreePlugin.PROVIDER_ICON, newTreeMenu));
|
||||
newCallTree.setDescription("Show the Function Call Tree window for the function " +
|
||||
"selected in the call tree");
|
||||
tool.addLocalAction(this, newCallTree);
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,6 @@ package ghidra.app.plugin.core.decompile.actions;
|
||||
import docking.action.MenuData;
|
||||
import ghidra.app.decompiler.component.*;
|
||||
import ghidra.app.plugin.core.decompile.DecompilerActionContext;
|
||||
import ghidra.app.util.HelpTopics;
|
||||
import ghidra.util.HelpLocation;
|
||||
|
||||
/**
|
||||
@ -35,7 +34,7 @@ public class RemoveAllSecondaryHighlightsAction extends AbstractDecompilerAction
|
||||
|
||||
setPopupMenuData(new MenuData(
|
||||
new String[] { "Secondary Highlight", "Remove All Highlights" }, "Decompile"));
|
||||
setHelpLocation(new HelpLocation(HelpTopics.SELECTION, getName()));
|
||||
setHelpLocation(new HelpLocation("DecompilePlugin", getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -19,7 +19,6 @@ import docking.action.MenuData;
|
||||
import ghidra.app.decompiler.ClangToken;
|
||||
import ghidra.app.decompiler.component.*;
|
||||
import ghidra.app.plugin.core.decompile.DecompilerActionContext;
|
||||
import ghidra.app.util.HelpTopics;
|
||||
import ghidra.util.HelpLocation;
|
||||
|
||||
/**
|
||||
@ -36,7 +35,7 @@ public class RemoveSecondaryHighlightAction extends AbstractDecompilerAction {
|
||||
|
||||
setPopupMenuData(
|
||||
new MenuData(new String[] { "Secondary Highlight", "Remove Highlight" }, "Decompile"));
|
||||
setHelpLocation(new HelpLocation(HelpTopics.SELECTION, getName()));
|
||||
setHelpLocation(new HelpLocation("DecompilePlugin", getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -145,6 +145,20 @@ public class SharedStubKeyBindingAction extends DockingAction implements Options
|
||||
return StringUtils.join(owners, ", ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
|
||||
Set<DockingActionIf> actions = clientActions.keySet();
|
||||
for (DockingActionIf action : actions) {
|
||||
String description = action.getDescription();
|
||||
if (!StringUtils.isBlank(description)) {
|
||||
return description;
|
||||
}
|
||||
}
|
||||
|
||||
return super.getDescription();
|
||||
}
|
||||
|
||||
private KeyStroke validateActionsHaveTheSameDefaultKeyStroke(DockingActionIf newAction) {
|
||||
|
||||
// this value may be null
|
||||
|
@ -49,6 +49,7 @@ src/main/resources/images/face-monkey16.png||Tango Icons - Public Domain|||origi
|
||||
src/main/resources/images/flag.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
|
||||
src/main/resources/images/greenDragon16.png||GHIDRA||||END|
|
||||
src/main/resources/images/greenDragon24.png||GHIDRA||||END|
|
||||
src/main/resources/images/help-browser.png||Tango Icons - Public Domain|||tango icon set|END|
|
||||
src/main/resources/images/internet-web-browser16.png||Tango Icons - Public Domain|||originally internet-web-browser.png from tango|END|
|
||||
src/main/resources/images/kgpg.png||Nuvola Icons - LGPL 2.1|||Nuvola icon set|END|
|
||||
src/main/resources/images/mergemgr16.gif||GHIDRA||||END|
|
||||
|
@ -35,6 +35,9 @@ public class Icons {
|
||||
|
||||
public static final ImageIcon EMPTY_ICON = ResourceManager.loadImage("images/EmptyIcon16.gif");
|
||||
|
||||
public static final ImageIcon HELP_ICON =
|
||||
ResourceManager.loadImage("images/help-browser.png");
|
||||
|
||||
public static final ImageIcon ADD_ICON = ResourceManager.loadImage("images/Plus2.png");
|
||||
|
||||
public static final ImageIcon COLLAPSE_ALL_ICON =
|
||||
@ -82,7 +85,7 @@ public class Icons {
|
||||
new DotDotDotIcon(ResourceManager.loadImage("images/Disk.png")));
|
||||
|
||||
public static final ImageIcon MAKE_SELECTION_ICON =
|
||||
ResourceManager.getImageIcon(ResourceManager.loadImage("images/text_align_justify.png"));
|
||||
ResourceManager.loadImage("images/text_align_justify.png");
|
||||
|
||||
// Not necessarily re-usable, but this is needed for the help system; these should
|
||||
// probably be moved to the client that uses them, while updating the
|
||||
|
Before Width: | Height: | Size: 932 B After Width: | Height: | Size: 932 B |
@ -32,9 +32,10 @@ import docking.KeyEntryTextField;
|
||||
import docking.action.DockingActionIf;
|
||||
import docking.action.KeyBindingData;
|
||||
import docking.actions.KeyBindingUtils;
|
||||
import docking.help.Help;
|
||||
import docking.help.HelpService;
|
||||
import docking.tool.util.DockingToolConstants;
|
||||
import docking.widgets.MultiLineLabel;
|
||||
import docking.widgets.OptionDialog;
|
||||
import docking.widgets.*;
|
||||
import docking.widgets.label.GIconLabel;
|
||||
import docking.widgets.table.*;
|
||||
import ghidra.framework.options.Options;
|
||||
@ -44,6 +45,7 @@ import ghidra.util.*;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.layout.PairLayout;
|
||||
import ghidra.util.layout.VerticalLayout;
|
||||
import resources.Icons;
|
||||
import resources.ResourceManager;
|
||||
|
||||
/**
|
||||
@ -56,6 +58,7 @@ public class KeyBindingsPanel extends JPanel {
|
||||
private final static int ACTION_NAME = 0;
|
||||
private final static int KEY_BINDING = 1;
|
||||
private final static int PLUGIN_NAME = 2;
|
||||
|
||||
private static final int FONT_SIZE = 11;
|
||||
|
||||
private JTextPane statusLabel;
|
||||
@ -79,6 +82,7 @@ public class KeyBindingsPanel extends JPanel {
|
||||
private boolean firingTableDataChanged;
|
||||
private PropertyChangeListener propertyChangeListener;
|
||||
private GTableFilterPanel<DockingActionIf> tableFilterPanel;
|
||||
private EmptyBorderButton helpButton;
|
||||
|
||||
public KeyBindingsPanel(PluginTool tool, Options options) {
|
||||
this.tool = tool;
|
||||
@ -203,6 +207,7 @@ public class KeyBindingsPanel extends JPanel {
|
||||
JScrollPane sp = new JScrollPane(actionTable);
|
||||
actionTable.setPreferredScrollableViewportSize(new Dimension(400, 100));
|
||||
actionTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
actionTable.setHTMLRenderingEnabled(true);
|
||||
|
||||
adjustTableColumns();
|
||||
|
||||
@ -231,7 +236,7 @@ public class KeyBindingsPanel extends JPanel {
|
||||
statusLabel = new JTextPane();
|
||||
statusLabel.setEnabled(false);
|
||||
DockingUtils.setTransparent(statusLabel);
|
||||
statusLabel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
|
||||
statusLabel.setBorder(BorderFactory.createEmptyBorder(5, 10, 0, 5));
|
||||
statusLabel.setContentType("text/html"); // render any HTML we find in descriptions
|
||||
|
||||
// make sure the label gets enough space
|
||||
@ -240,9 +245,27 @@ public class KeyBindingsPanel extends JPanel {
|
||||
Font f = new Font("SansSerif", Font.PLAIN, FONT_SIZE);
|
||||
statusLabel.setFont(f);
|
||||
|
||||
helpButton = new EmptyBorderButton(Icons.HELP_ICON);
|
||||
helpButton.setEnabled(false);
|
||||
helpButton.addActionListener(e -> {
|
||||
DockingActionIf action = getSelectedAction();
|
||||
HelpService hs = Help.getHelpService();
|
||||
hs.showHelp(action, false, KeyBindingsPanel.this);
|
||||
});
|
||||
|
||||
JPanel helpButtonPanel = new JPanel();
|
||||
helpButtonPanel.setLayout(new BoxLayout(helpButtonPanel, BoxLayout.PAGE_AXIS));
|
||||
helpButtonPanel.add(helpButton);
|
||||
helpButtonPanel.add(Box.createVerticalGlue());
|
||||
|
||||
JPanel lowerStatusPanel = new JPanel();
|
||||
lowerStatusPanel.setLayout(new BoxLayout(lowerStatusPanel, BoxLayout.X_AXIS));
|
||||
lowerStatusPanel.add(helpButtonPanel);
|
||||
lowerStatusPanel.add(statusLabel);
|
||||
|
||||
JPanel panel = new JPanel(new VerticalLayout(5));
|
||||
panel.add(keyPanel);
|
||||
panel.add(statusLabel);
|
||||
panel.add(lowerStatusPanel);
|
||||
return panel;
|
||||
}
|
||||
|
||||
@ -260,9 +283,9 @@ public class KeyBindingsPanel extends JPanel {
|
||||
// the content of the left-hand side label
|
||||
MultiLineLabel mlabel =
|
||||
new MultiLineLabel("To add or change a key binding, select an action\n" +
|
||||
" and type any key combination.\n" +
|
||||
"and type any key combination\n \n" +
|
||||
"To remove a key binding, select an action and\n" +
|
||||
"press <Enter> or <Backspace>.");
|
||||
"press <Enter> or <Backspace>");
|
||||
JPanel labelPanel = new JPanel();
|
||||
labelPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 0));
|
||||
BoxLayout bl = new BoxLayout(labelPanel, BoxLayout.X_AXIS);
|
||||
@ -451,13 +474,21 @@ public class KeyBindingsPanel extends JPanel {
|
||||
unappliedChanges = changes;
|
||||
}
|
||||
|
||||
private String getSelectedAction() {
|
||||
private DockingActionIf getSelectedAction() {
|
||||
if (selectionModel.isSelectionEmpty()) {
|
||||
return null;
|
||||
}
|
||||
int selectedRow = actionTable.getSelectedRow();
|
||||
int modelRow = tableFilterPanel.getModelRow(selectedRow);
|
||||
return tableActions.get(modelRow).getFullName();
|
||||
return tableActions.get(modelRow);
|
||||
}
|
||||
|
||||
private String getSelectedActionName() {
|
||||
DockingActionIf action = getSelectedAction();
|
||||
if (action == null) {
|
||||
return null;
|
||||
}
|
||||
return action.getFullName();
|
||||
}
|
||||
|
||||
private void addToKeyMap(KeyStroke ks, String actionName) {
|
||||
@ -580,7 +611,7 @@ public class KeyBindingsPanel extends JPanel {
|
||||
return;
|
||||
}
|
||||
|
||||
String selectedActionName = getSelectedAction();
|
||||
String selectedActionName = getSelectedActionName();
|
||||
if (selectedActionName != null) {
|
||||
if (processKeyStroke(selectedActionName, ks)) {
|
||||
String keyStrokeText = KeyEntryTextField.parseKeyStroke(ks);
|
||||
@ -645,11 +676,14 @@ public class KeyBindingsPanel extends JPanel {
|
||||
return;
|
||||
}
|
||||
|
||||
String fullActionName = getSelectedAction();
|
||||
helpButton.setEnabled(false);
|
||||
String fullActionName = getSelectedActionName();
|
||||
if (fullActionName == null) {
|
||||
statusLabel.setText("");
|
||||
return;
|
||||
}
|
||||
|
||||
helpButton.setEnabled(true);
|
||||
KeyStroke ks = keyStrokesByFullName.get(fullActionName);
|
||||
String ksName = "";
|
||||
clearInfoPanel();
|
||||
@ -672,12 +706,14 @@ public class KeyBindingsPanel extends JPanel {
|
||||
if (description == null || description.trim().isEmpty()) {
|
||||
description = action.getName();
|
||||
}
|
||||
|
||||
statusLabel.setText("<html>" + HTMLUtilities.escapeHTML(description));
|
||||
}
|
||||
}
|
||||
|
||||
private class KeyBindingsTableModel extends AbstractSortedTableModel<DockingActionIf> {
|
||||
private final String[] columnNames = { "Action Name", "KeyBinding", "Plugin Name" };
|
||||
private final String[] columnNames =
|
||||
{ "Action Name", "KeyBinding", "Plugin Name" };
|
||||
|
||||
KeyBindingsTableModel() {
|
||||
super(0);
|
||||
@ -694,7 +730,6 @@ public class KeyBindingsPanel extends JPanel {
|
||||
switch (columnIndex) {
|
||||
case ACTION_NAME:
|
||||
return action.getName();
|
||||
|
||||
case KEY_BINDING:
|
||||
KeyStroke ks = keyStrokesByFullName.get(action.getFullName());
|
||||
if (ks != null) {
|
||||
|
Loading…
Reference in New Issue
Block a user