mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 19:42:36 +02:00
Merge remote-tracking branch
'origin/GP-3812-dragonmacher-symbol-tree-collapse-all' (Closes #5731)
This commit is contained in:
commit
1b4368d0fa
5 changed files with 227 additions and 24 deletions
|
@ -19,12 +19,13 @@ import docking.Tool;
|
|||
import docking.action.DockingActionIf;
|
||||
import docking.tool.ToolConstants;
|
||||
import docking.widgets.table.GTable;
|
||||
import docking.widgets.tree.GTree;
|
||||
|
||||
/**
|
||||
* A place used to hold {@link DockingActionIf}s that are meant to be used by components. Some
|
||||
* components do not have access to the tool that is required to register their actions. This
|
||||
* class helps those components by enabling the installation of shared actions for those
|
||||
* components.
|
||||
* class helps those components by enabling the installation of shared actions for those
|
||||
* components.
|
||||
*/
|
||||
public class SharedActionRegistry {
|
||||
|
||||
|
@ -35,5 +36,7 @@ public class SharedActionRegistry {
|
|||
*/
|
||||
public static void installSharedActions(Tool tool, ToolActions toolActions) {
|
||||
GTable.createSharedActions(tool, toolActions, ToolConstants.SHARED_OWNER);
|
||||
|
||||
GTree.createSharedActions(tool, toolActions, ToolConstants.SHARED_OWNER);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,13 +15,13 @@
|
|||
*/
|
||||
package docking.widgets.tree;
|
||||
|
||||
import static docking.action.MenuData.*;
|
||||
import static docking.widgets.tree.support.GTreeSelectionEvent.EventOrigin.*;
|
||||
import static ghidra.util.SystemUtilities.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.dnd.Autoscroll;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.event.*;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
@ -36,8 +36,10 @@ import javax.swing.tree.*;
|
|||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import docking.DockingWindowManager;
|
||||
import docking.*;
|
||||
import docking.action.*;
|
||||
import docking.actions.KeyBindingUtils;
|
||||
import docking.actions.ToolActions;
|
||||
import docking.widgets.JTreeMouseListenerDelegate;
|
||||
import docking.widgets.filter.FilterTextField;
|
||||
import docking.widgets.table.AutoscrollAdapter;
|
||||
|
@ -51,6 +53,7 @@ import ghidra.util.*;
|
|||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.*;
|
||||
import ghidra.util.worker.PriorityWorker;
|
||||
import resources.Icons;
|
||||
|
||||
/**
|
||||
* Class for creating a JTree that supports filtering, threading, and a progress bar.
|
||||
|
@ -1394,6 +1397,16 @@ public class GTree extends JPanel implements BusyListener {
|
|||
node.fireNodeChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* A method that subclasses can override to signal that they wish not to have this tree's
|
||||
* built-in popup actions. Subclasses will almost never need to override this method.
|
||||
*
|
||||
* @return true if popup actions are supported
|
||||
*/
|
||||
protected boolean supportsPopupActions() {
|
||||
return true;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
// Inner Classes
|
||||
//==================================================================================================
|
||||
|
@ -1440,11 +1453,15 @@ public class GTree extends JPanel implements BusyListener {
|
|||
this.scrollableUnitIncrementOverride = increment;
|
||||
}
|
||||
|
||||
GTree getGTree() {
|
||||
return GTree.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getToolTipText(MouseEvent event) {
|
||||
// Use the GTree's method so clients can override the behavior; provide the
|
||||
// default method below so we they can get the default behavior when needed.
|
||||
return GTree.this.getToolTipText(event);
|
||||
return getGTree().getToolTipText(event);
|
||||
}
|
||||
|
||||
public String getDefaultToolTipText(MouseEvent event) {
|
||||
|
@ -1463,7 +1480,7 @@ public class GTree extends JPanel implements BusyListener {
|
|||
|
||||
@Override
|
||||
public boolean isPathEditable(TreePath path) {
|
||||
return GTree.this.isPathEditable(path);
|
||||
return getGTree().isPathEditable(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1568,10 +1585,173 @@ public class GTree extends JPanel implements BusyListener {
|
|||
}
|
||||
}
|
||||
|
||||
private abstract static class GTreeAction extends DockingAction
|
||||
implements ComponentBasedDockingAction {
|
||||
|
||||
GTreeAction(String name, String owner) {
|
||||
super(name, owner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAddToPopup(ActionContext context) {
|
||||
if (!isEnabledForContext(context)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GTree gTree = getTree(context);
|
||||
return gTree.supportsPopupActions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledForContext(ActionContext context) {
|
||||
return getTree(context) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidComponentContext(ActionContext context) {
|
||||
return getTree(context) != null;
|
||||
}
|
||||
|
||||
protected GTree getTree(ActionContext context) {
|
||||
Component c = context.getSourceComponent();
|
||||
if (c instanceof GTree) {
|
||||
return (GTree) c;
|
||||
}
|
||||
if (c instanceof AutoScrollTree) {
|
||||
return ((AutoScrollTree) c).getGTree();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
// Static Methods
|
||||
//==================================================================================================
|
||||
|
||||
public static void createSharedActions(Tool tool, ToolActions toolActions, String owner) {
|
||||
|
||||
String actionMenuGroup = "zzzTreeGroup";
|
||||
tool.setMenuGroup(new String[] { "Collapse" }, actionMenuGroup, "1");
|
||||
tool.setMenuGroup(new String[] { "Expand" }, actionMenuGroup, "2");
|
||||
|
||||
int subGroupIndex = 1; // order by insertion
|
||||
GTreeAction collapseAction = new GTreeAction("Tree Collapse Node", owner) {
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
GTree gTree = getTree(context);
|
||||
List<GTreeNode> nodes = gTree.getSelectedNodes();
|
||||
for (GTreeNode node : nodes) {
|
||||
gTree.collapseAll(node);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledForContext(ActionContext context) {
|
||||
|
||||
if (!super.isEnabledForContext(context)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GTree gTree = getTree(context);
|
||||
List<GTreeNode> nodes = gTree.getSelectedNodes();
|
||||
return !nodes.isEmpty();
|
||||
}
|
||||
};
|
||||
//@formatter:off
|
||||
collapseAction.setPopupMenuData(new MenuData(
|
||||
new String[] { "Collapse" },
|
||||
Icons.COLLAPSE_ALL_ICON,
|
||||
actionMenuGroup, NO_MNEMONIC,
|
||||
Integer.toString(subGroupIndex++)
|
||||
)
|
||||
);
|
||||
collapseAction.setKeyBindingData(new KeyBindingData(KeyEvent.VK_UP, InputEvent.ALT_DOWN_MASK));
|
||||
collapseAction.setHelpLocation(new HelpLocation("Trees", "Collapse"));
|
||||
//@formatter:on
|
||||
|
||||
GTreeAction expandAction = new GTreeAction("Tree Expand Node", owner) {
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
GTree gTree = getTree(context);
|
||||
List<GTreeNode> nodes = gTree.getSelectedNodes();
|
||||
for (GTreeNode node : nodes) {
|
||||
gTree.expandTree(node);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledForContext(ActionContext context) {
|
||||
|
||||
if (!super.isEnabledForContext(context)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GTree gTree = getTree(context);
|
||||
List<GTreeNode> nodes = gTree.getSelectedNodes();
|
||||
return !nodes.isEmpty();
|
||||
}
|
||||
};
|
||||
//@formatter:off
|
||||
expandAction.setPopupMenuData(new MenuData(
|
||||
new String[] { "Exapnd" },
|
||||
Icons.EXPAND_ALL_ICON,
|
||||
actionMenuGroup, NO_MNEMONIC,
|
||||
Integer.toString(subGroupIndex++)
|
||||
)
|
||||
);
|
||||
expandAction.setKeyBindingData(new KeyBindingData(KeyEvent.VK_DOWN, InputEvent.ALT_DOWN_MASK));
|
||||
expandAction.setHelpLocation(new HelpLocation("Trees", "Expand"));
|
||||
//@formatter:on
|
||||
|
||||
GTreeAction collapseTreeAction = new GTreeAction("Tree Collapse All", owner) {
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
GTree gTree = getTree(context);
|
||||
GTreeNode root = gTree.getViewRoot();
|
||||
gTree.collapseAll(root);
|
||||
}
|
||||
};
|
||||
//@formatter:off
|
||||
collapseTreeAction.setPopupMenuData(new MenuData(
|
||||
new String[] { "Collapse Tree" },
|
||||
null,
|
||||
actionMenuGroup, NO_MNEMONIC,
|
||||
Integer.toString(subGroupIndex++)
|
||||
)
|
||||
);
|
||||
collapseTreeAction.setHelpLocation(new HelpLocation("Trees", "Collapse_Tree"));
|
||||
//@formatter:on
|
||||
|
||||
GTreeAction expandTreeAction = new GTreeAction("Tree Expand All", owner) {
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
GTree gTree = getTree(context);
|
||||
gTree.expandAll();
|
||||
}
|
||||
};
|
||||
//@formatter:off
|
||||
expandTreeAction.setPopupMenuData(new MenuData(
|
||||
new String[] { "Expand Tree" },
|
||||
null,
|
||||
actionMenuGroup, NO_MNEMONIC,
|
||||
Integer.toString(subGroupIndex++)
|
||||
)
|
||||
);
|
||||
expandTreeAction.setHelpLocation(new HelpLocation("Trees", "Expand_Tree"));
|
||||
//@formatter:on
|
||||
|
||||
// these actions are self-explanatory and do need help
|
||||
collapseAction.markHelpUnnecessary();
|
||||
expandAction.markHelpUnnecessary();
|
||||
collapseTreeAction.markHelpUnnecessary();
|
||||
expandTreeAction.markHelpUnnecessary();
|
||||
|
||||
toolActions.addGlobalAction(collapseAction);
|
||||
toolActions.addGlobalAction(expandAction);
|
||||
toolActions.addGlobalAction(collapseTreeAction);
|
||||
toolActions.addGlobalAction(expandTreeAction);
|
||||
}
|
||||
|
||||
private static String generateFilterPreferenceKey() {
|
||||
Throwable throwable = new Throwable();
|
||||
StackTraceElement[] stackTrace = throwable.getStackTrace();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue