mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 17:11:11 -09:00
GP-1445 fixing issue with renaming a datatype that has the same name as a category at the same level
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,10 +15,6 @@
|
||||
*/
|
||||
package ghidra.app.plugin.core.datamgr.actions;
|
||||
|
||||
import ghidra.app.plugin.core.datamgr.DataTypeManagerPlugin;
|
||||
import ghidra.app.plugin.core.datamgr.DataTypesActionContext;
|
||||
import ghidra.app.plugin.core.datamgr.tree.*;
|
||||
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
import docking.ActionContext;
|
||||
@@ -27,6 +22,9 @@ import docking.action.DockingAction;
|
||||
import docking.action.MenuData;
|
||||
import docking.widgets.tree.GTree;
|
||||
import docking.widgets.tree.GTreeNode;
|
||||
import ghidra.app.plugin.core.datamgr.DataTypeManagerPlugin;
|
||||
import ghidra.app.plugin.core.datamgr.DataTypesActionContext;
|
||||
import ghidra.app.plugin.core.datamgr.tree.*;
|
||||
|
||||
public class RenameAction extends DockingAction {
|
||||
|
||||
@@ -76,7 +74,7 @@ public class RenameAction extends DockingAction {
|
||||
void rename(final DataTypeArchiveGTree tree) {
|
||||
TreePath path = tree.getSelectionPath();
|
||||
final GTreeNode node = (GTreeNode) path.getLastPathComponent();
|
||||
tree.startEditing(node.getParent(), node.getName());
|
||||
tree.startEditing(node);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,14 +15,13 @@
|
||||
*/
|
||||
package ghidra.app.plugin.core.symboltree.actions;
|
||||
|
||||
import ghidra.app.plugin.core.symboltree.SymbolTreeActionContext;
|
||||
import ghidra.app.plugin.core.symboltree.SymbolTreePlugin;
|
||||
import ghidra.app.plugin.core.symboltree.nodes.SymbolNode;
|
||||
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
import docking.action.MenuData;
|
||||
import docking.widgets.tree.GTreeNode;
|
||||
import ghidra.app.plugin.core.symboltree.SymbolTreeActionContext;
|
||||
import ghidra.app.plugin.core.symboltree.SymbolTreePlugin;
|
||||
import ghidra.app.plugin.core.symboltree.nodes.SymbolNode;
|
||||
|
||||
public class RenameAction extends SymbolTreeContextAction {
|
||||
|
||||
@@ -47,7 +45,7 @@ public class RenameAction extends SymbolTreeContextAction {
|
||||
public void actionPerformed(SymbolTreeActionContext context) {
|
||||
TreePath[] selectionPaths = context.getSelectedSymbolTreePaths();
|
||||
GTreeNode node = (GTreeNode) selectionPaths[0].getLastPathComponent();
|
||||
context.getSymbolTree().startEditing(node.getParent(), node.getName());
|
||||
context.getSymbolTree().startEditing(node);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -377,6 +377,45 @@ public class DataTypeManagerPluginTest extends AbstractGhidraHeadedIntegrationTe
|
||||
assertNotNull(programNode.getChild(newCategoryName));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRenameDataTypeWithSameNameAsCategory() throws Exception {
|
||||
// select a category
|
||||
expandNode(programNode);
|
||||
String miscNodeName = "MISC";
|
||||
final CategoryNode miscNode = (CategoryNode) programNode.getChild(miscNodeName);
|
||||
assertNotNull(miscNode);
|
||||
StructureDataType struct = new StructureDataType("MISC", 0);
|
||||
struct.add(new DWordDataType());
|
||||
builder.addDataType(struct);
|
||||
waitForTree();
|
||||
DataType resolved = program.getDataTypeManager().resolve(struct, null);
|
||||
DataTypeNode node = programNode.getNode(resolved);
|
||||
selectNode(node);
|
||||
|
||||
final DockingActionIf action = getAction(plugin, "Rename");
|
||||
assertTrue(action.isEnabledForContext(treeContext));
|
||||
|
||||
// select "Rename" action
|
||||
final String newDatatypeName = "ItWorked";
|
||||
DataTypeTestUtils.performAction(action, tree);
|
||||
waitForTree();
|
||||
runSwing(() -> {
|
||||
int rowForPath = jTree.getRowForPath(miscNode.getTreePath());
|
||||
|
||||
DefaultTreeCellEditor cellEditor = (DefaultTreeCellEditor) tree.getCellEditor();
|
||||
Container container = (Container) cellEditor.getTreeCellEditorComponent(jTree, miscNode,
|
||||
true, true, true, rowForPath);
|
||||
JTextField textField = (JTextField) container.getComponent(0);
|
||||
|
||||
textField.setText(newDatatypeName);
|
||||
jTree.stopEditing();
|
||||
});
|
||||
waitForProgram();
|
||||
waitForTree();
|
||||
|
||||
assertEquals("ItWorked", resolved.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRenameCategoryDuplicate() throws Exception {
|
||||
expandNode(programNode);
|
||||
|
||||
@@ -943,13 +943,12 @@ public class GTree extends JPanel implements BusyListener {
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the node with the given name, in the given parent, be edited. <b>This
|
||||
* operation (as with many others on this tree) is asynchronous.</b> This request will be
|
||||
* buffered as needed to wait for the given node to be added to the parent, up to a timeout
|
||||
* period.
|
||||
* Requests that the node with the given name, in the given parent, be edited. This
|
||||
* operation is asynchronous. This request will be buffered as needed to wait for
|
||||
* the given node to be added to the parent, up to a timeout period.
|
||||
*
|
||||
* @param parent the parent node
|
||||
* @param childName the child node name
|
||||
* @param childName the name of the child to edit
|
||||
*/
|
||||
public void startEditing(GTreeNode parent, final String childName) {
|
||||
|
||||
@@ -972,6 +971,21 @@ public class GTree extends JPanel implements BusyListener {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the node be edited. This operation is asynchronous.
|
||||
*
|
||||
* @param child the node to edit
|
||||
*/
|
||||
public void startEditing(GTreeNode child) {
|
||||
|
||||
// we call this here, even though the JTree will do this for us, so that we will trigger
|
||||
// a load call before this task is run, in case lazy nodes are involved in this tree,
|
||||
// which must be loaded before we can edit
|
||||
expandPath(child.getParent());
|
||||
|
||||
runTask(new GTreeStartEditingTask(GTree.this, tree, child));
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void addMouseListener(MouseListener listener) {
|
||||
mouseListenerDelegate.addMouseListener(listener);
|
||||
|
||||
@@ -36,6 +36,7 @@ public class GTreeStartEditingTask extends GTreeTask {
|
||||
|
||||
private final GTreeNode parent;
|
||||
private final String childName;
|
||||
private GTreeNode editNode;
|
||||
|
||||
public GTreeStartEditingTask(GTree gTree, JTree jTree, GTreeNode parent, String childName) {
|
||||
super(gTree);
|
||||
@@ -43,6 +44,13 @@ public class GTreeStartEditingTask extends GTreeTask {
|
||||
this.childName = childName;
|
||||
}
|
||||
|
||||
public GTreeStartEditingTask(GTree gTree, JTree jTree, GTreeNode editNode) {
|
||||
super(gTree);
|
||||
this.parent = editNode.getParent();
|
||||
this.childName = editNode.getName();
|
||||
this.editNode = editNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final TaskMonitor monitor) throws CancelledException {
|
||||
runOnSwingThread(() -> {
|
||||
@@ -66,10 +74,12 @@ public class GTreeStartEditingTask extends GTreeTask {
|
||||
return;
|
||||
}
|
||||
|
||||
GTreeNode editNode = parent.getChild(childName);
|
||||
if (editNode == null) {
|
||||
Msg.debug(this, "Can't find node \"" + childName + "\" to edit.");
|
||||
return;
|
||||
editNode = parent.getChild(childName);
|
||||
if (editNode == null) {
|
||||
Msg.debug(this, "Can't find node \"" + childName + "\" to edit.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
TreePath path = editNode.getTreePath();
|
||||
|
||||
@@ -66,7 +66,7 @@ public class ProjectDataRenameAction extends FrontendProjectTreeAction {
|
||||
DataTree tree = (DataTree) component;
|
||||
GTreeNode node = (GTreeNode) context.getContextObject();
|
||||
tree.setEditable(true);
|
||||
tree.startEditing(node.getParent(), node.getName());
|
||||
tree.startEditing(node);
|
||||
}
|
||||
else if (component instanceof GTable) {
|
||||
GTable table = (GTable) component;
|
||||
|
||||
Reference in New Issue
Block a user