mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
GT-3436 - Fixed symbol tree navigation to work on already selected node
This commit is contained in:
parent
02df944b0e
commit
14ee95c395
2 changed files with 46 additions and 27 deletions
|
@ -18,12 +18,15 @@ package ghidra.app.plugin.core.symboltree;
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.datatransfer.Clipboard;
|
import java.awt.datatransfer.Clipboard;
|
||||||
import java.awt.datatransfer.ClipboardOwner;
|
import java.awt.datatransfer.ClipboardOwner;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.tree.TreePath;
|
import javax.swing.tree.TreePath;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
|
||||||
import docking.ActionContext;
|
import docking.ActionContext;
|
||||||
import docking.action.DockingAction;
|
import docking.action.DockingAction;
|
||||||
import docking.widgets.tree.*;
|
import docking.widgets.tree.*;
|
||||||
|
@ -148,32 +151,61 @@ public class SymbolTreeProvider extends ComponentProviderAdapter {
|
||||||
SymbolGTree newTree = new SymbolGTree(rootNode, plugin);
|
SymbolGTree newTree = new SymbolGTree(rootNode, plugin);
|
||||||
|
|
||||||
newTree.addGTreeSelectionListener(e -> {
|
newTree.addGTreeSelectionListener(e -> {
|
||||||
|
|
||||||
EventOrigin origin = e.getEventOrigin();
|
EventOrigin origin = e.getEventOrigin();
|
||||||
if (origin != EventOrigin.USER_GENERATED) {
|
if (origin != EventOrigin.USER_GENERATED) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
TreePath[] paths = tree.getSelectionPaths();
|
|
||||||
Object object = paths[0].getLastPathComponent();
|
|
||||||
if (!(object instanceof SymbolNode)) {
|
|
||||||
contextChanged();
|
contextChanged();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SymbolNode node = (SymbolNode) object;
|
goToUniquelySelectedSymbol();
|
||||||
Symbol symbol = node.getSymbol();
|
|
||||||
SymbolType type = symbol.getSymbolType();
|
|
||||||
if (!type.isNamespace() || type == SymbolType.FUNCTION) {
|
|
||||||
plugin.goTo(symbol);
|
|
||||||
}
|
|
||||||
contextChanged();
|
contextChanged();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
newTree.addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mouseClicked(MouseEvent e) {
|
||||||
|
|
||||||
|
// This code serves to perform navigation in the case that the selection handler
|
||||||
|
// above does not, as is the case when the node is already selected. This code
|
||||||
|
// will get called on the mouse release, whereas the selection handler gets called
|
||||||
|
// on the mouse pressed.
|
||||||
|
// For now, just attempt to perform the goto. It may get called twice, but this
|
||||||
|
// should have no real impact on performance.
|
||||||
|
|
||||||
|
goToUniquelySelectedSymbol();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
newTree.setEditable(true);
|
newTree.setEditable(true);
|
||||||
|
|
||||||
return newTree;
|
return newTree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void goToUniquelySelectedSymbol() {
|
||||||
|
|
||||||
|
TreePath[] paths = tree.getSelectionPaths();
|
||||||
|
if (ArrayUtils.isEmpty(paths)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (paths.length > 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object object = paths[0].getLastPathComponent();
|
||||||
|
if (!(object instanceof SymbolNode)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SymbolNode node = (SymbolNode) object;
|
||||||
|
Symbol symbol = node.getSymbol();
|
||||||
|
SymbolType type = symbol.getSymbolType();
|
||||||
|
if (!type.isNamespace() || type == SymbolType.FUNCTION) {
|
||||||
|
plugin.goTo(symbol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void createActions() {
|
private void createActions() {
|
||||||
DockingAction createImportAction = new CreateLibraryAction(plugin);
|
DockingAction createImportAction = new CreateLibraryAction(plugin);
|
||||||
DockingAction setExternalProgramAction = new SetExternalProgramAction(plugin, this);
|
DockingAction setExternalProgramAction = new SetExternalProgramAction(plugin, this);
|
||||||
|
@ -367,10 +399,6 @@ public class SymbolTreeProvider extends ComponentProviderAdapter {
|
||||||
tree.refilterLater();
|
tree.refilterLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void symbolChanged(Symbol symbol, String oldName) {
|
|
||||||
addTask(new SymbolChangedTask(tree, symbol, oldName));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void symbolChanged(Symbol symbol) {
|
private void symbolChanged(Symbol symbol) {
|
||||||
addTask(new SymbolChangedTask(tree, symbol));
|
addTask(new SymbolChangedTask(tree, symbol));
|
||||||
}
|
}
|
||||||
|
@ -547,16 +575,8 @@ public class SymbolTreeProvider extends ComponentProviderAdapter {
|
||||||
|
|
||||||
private class SymbolChangedTask extends AbstactSymbolUpdateTask {
|
private class SymbolChangedTask extends AbstactSymbolUpdateTask {
|
||||||
|
|
||||||
// will not be null; may be equal to the current name
|
|
||||||
private String oldName;
|
|
||||||
|
|
||||||
SymbolChangedTask(GTree tree, Symbol symbol) {
|
SymbolChangedTask(GTree tree, Symbol symbol) {
|
||||||
this(tree, symbol, symbol.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
SymbolChangedTask(GTree tree, Symbol symbol, String oldName) {
|
|
||||||
super(tree, symbol);
|
super(tree, symbol);
|
||||||
this.oldName = Objects.requireNonNull(oldName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -638,8 +658,7 @@ public class SymbolTreeProvider extends ComponentProviderAdapter {
|
||||||
|
|
||||||
if (eventType == ChangeManager.DOCR_SYMBOL_RENAMED) {
|
if (eventType == ChangeManager.DOCR_SYMBOL_RENAMED) {
|
||||||
Symbol symbol = (Symbol) object;
|
Symbol symbol = (Symbol) object;
|
||||||
String oldName = (String) rec.getOldValue();
|
symbolChanged(symbol);
|
||||||
symbolChanged(symbol, oldName);
|
|
||||||
}
|
}
|
||||||
else if (eventType == ChangeManager.DOCR_SYMBOL_DATA_CHANGED ||
|
else if (eventType == ChangeManager.DOCR_SYMBOL_DATA_CHANGED ||
|
||||||
eventType == ChangeManager.DOCR_SYMBOL_SCOPE_CHANGED ||
|
eventType == ChangeManager.DOCR_SYMBOL_SCOPE_CHANGED ||
|
||||||
|
|
|
@ -103,7 +103,7 @@ public class GTreeSelectionModel extends DefaultTreeSelectionModel {
|
||||||
*/
|
*/
|
||||||
final public void userRemovedSelectionPath(TreePath path) {
|
final public void userRemovedSelectionPath(TreePath path) {
|
||||||
currentEventOrigin = EventOrigin.USER_GENERATED;
|
currentEventOrigin = EventOrigin.USER_GENERATED;
|
||||||
super.removeSelectionPath(path);
|
super.removeSelectionPaths(new TreePath[] { path });
|
||||||
currentEventOrigin = EventOrigin.USER_GENERATED;
|
currentEventOrigin = EventOrigin.USER_GENERATED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue