Merge remote-tracking branch 'origin/GP-1615_ghidravore_allowing_some_nodes_to_resist_filtering'

This commit is contained in:
ghidra1 2021-12-29 10:21:01 -05:00
commit cc6293a10c
15 changed files with 387 additions and 227 deletions

View file

@ -19,12 +19,13 @@ import java.util.List;
import javax.swing.tree.TreePath;
import docking.widgets.tree.GTreeNode;
import ghidra.framework.main.datatree.*;
import ghidra.framework.model.DomainFile;
import ghidra.framework.model.DomainFolder;
/**
* Common methods appropriate for both the {@link FrontEndProjectTreeContext} and the
* Common methods appropriate for both the {@link FrontEndProjectTreeContext} and the
* {@link DialogProjectTreeContext}. The project tree actions require that the contexts be
* separate even though they need many of the same methods. By extracting the methods to this
* interface, the contexts can be kept separate, but can share action code.
@ -67,4 +68,9 @@ public interface ProjectTreeContext {
*/
public TreePath[] getSelectionPaths();
/**
* Returns the node that represents the context object for this context
* @return the node
*/
public GTreeNode getContextNode();
}

View file

@ -21,6 +21,7 @@ import java.util.List;
import javax.swing.tree.TreePath;
import docking.ActionContext;
import docking.widgets.tree.GTreeNode;
import ghidra.framework.main.datatable.ProjectTreeContext;
import ghidra.framework.model.*;
@ -93,4 +94,8 @@ public class DialogProjectTreeContext extends ActionContext implements ProjectTr
return selectedFiles.size();
}
@Override
public GTreeNode getContextNode() {
return (GTreeNode) super.getContextObject();
}
}

View file

@ -20,6 +20,7 @@ import java.util.List;
import javax.swing.tree.TreePath;
import docking.ComponentProvider;
import docking.widgets.tree.GTreeNode;
import ghidra.framework.main.datatable.ProjectDataContext;
import ghidra.framework.main.datatable.ProjectTreeContext;
import ghidra.framework.model.*;
@ -56,4 +57,9 @@ public class FrontEndProjectTreeContext extends ProjectDataContext
public DataTree getTree() {
return tree;
}
@Override
public GTreeNode getContextNode() {
return (GTreeNode) super.getContextObject();
}
}

View file

@ -16,8 +16,6 @@
package ghidra.framework.main.projectdata.actions;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Icon;
@ -26,14 +24,15 @@ import docking.action.MenuData;
import docking.widgets.tree.GTreeNode;
import ghidra.framework.main.datatable.ProjectTreeContext;
import ghidra.framework.main.datatree.DataTree;
import ghidra.framework.main.datatree.DomainFileNode;
import ghidra.framework.model.DomainFile;
import ghidra.framework.model.DomainFolder;
import ghidra.util.InvalidNameException;
import ghidra.util.Swing;
import ghidra.util.exception.AssertException;
import resources.ResourceManager;
public class ProjectDataNewFolderAction<T extends ProjectTreeContext> extends ContextSpecificAction<T> {
public class ProjectDataNewFolderAction<T extends ProjectTreeContext>
extends ContextSpecificAction<T> {
private static Icon icon = ResourceManager.loadImage("images/folder_add.png");
@ -53,24 +52,14 @@ public class ProjectDataNewFolderAction<T extends ProjectTreeContext> extends Co
return (context.getFolderCount() + context.getFileCount()) == 1;
}
/**
* Create a new folder for the selected node that represents
* a folder.
*/
private void createNewFolder(T context) {
DomainFolder parentFolder = getFolder(context);
DomainFolder newFolder = createNewFolderWithDefaultName(parentFolder);
GTreeNode parent = getParentNode(context);
DataTree tree = context.getTree();
Swing.runLater(() -> {
GTreeNode node = findNodeForFolder(tree, newFolder);
if (node != null) {
tree.setEditable(true);
tree.startEditing(node.getParent(), node.getName());
}
});
tree.setEditable(true);
tree.startEditing(parent, newFolder.getName());
}
private DomainFolder createNewFolderWithDefaultName(DomainFolder parentFolder) {
@ -79,34 +68,10 @@ public class ProjectDataNewFolderAction<T extends ProjectTreeContext> extends Co
return parentFolder.createFolder(name);
}
catch (InvalidNameException | IOException e) {
throw new AssertException("Unexpected Error creating new folder: "+name, e);
throw new AssertException("Unexpected Error creating new folder: " + name, e);
}
}
/**
* Get folder path as list with top-level folder being first in the list.
* Root folder is not included in list.
* @param folder
* @param folderPathList folder path list
*/
private static final void getFolderPath(DomainFolder folder, List<String> folderPathList) {
if (folder.getParent() != null) {
// don't recurse if we are the root, don't add our 'name' to the list
getFolderPath(folder.getParent(), folderPathList);
folderPathList.add(folder.getName());
}
}
private GTreeNode findNodeForFolder(DataTree tree, DomainFolder newFolder) {
List<String> folderPathList = new ArrayList<>();
getFolderPath(newFolder, folderPathList);
GTreeNode node = tree.getModelRoot();
for (int i = 0; node != null && i < folderPathList.size(); i++) {
node = node.getChild(folderPathList.get(i));
}
return node;
}
private String getNewFolderName(DomainFolder parent) {
String baseName = "NewFolder";
String name = baseName;
@ -128,4 +93,12 @@ public class ProjectDataNewFolderAction<T extends ProjectTreeContext> extends Co
return file.getParent();
}
private GTreeNode getParentNode(T context) {
GTreeNode node = context.getContextNode();
if (node instanceof DomainFileNode) {
return ((DomainFileNode) node).getParent();
}
return node;
}
}