mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
Fixed open program dialog to not repeatedly load the root node
This commit is contained in:
parent
2eff37f655
commit
1d5da6dae1
9 changed files with 268 additions and 165 deletions
|
@ -4,9 +4,9 @@
|
|||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -318,7 +318,7 @@ public class FrontEndPlugin extends Plugin
|
|||
r.run();
|
||||
}
|
||||
else {
|
||||
SwingUtilities.invokeLater(r);
|
||||
Swing.runLater(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -415,12 +415,12 @@ public class FrontEndPlugin extends Plugin
|
|||
|
||||
@Override
|
||||
public void viewedProjectAdded(URL projectView) {
|
||||
SwingUtilities.invokeLater(() -> rebuildRecentMenus());
|
||||
Swing.runLater(() -> rebuildRecentMenus());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void viewedProjectRemoved(URL projectView) {
|
||||
SwingUtilities.invokeLater(() -> rebuildRecentMenus());
|
||||
Swing.runLater(() -> rebuildRecentMenus());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -536,7 +536,7 @@ public class FrontEndPlugin extends Plugin
|
|||
void selectFiles(final Set<DomainFile> files) {
|
||||
// Do this later in case any of the given files are newly created, which means that the
|
||||
// GUIs may have not yet been notified.
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
Swing.runLater(() -> {
|
||||
// there was a delete bug; make the set unmodifiable to catch this earlier
|
||||
Set<DomainFile> unmodifiableFiles = Collections.unmodifiableSet(files);
|
||||
if (dataTablePanel.isCapacityExceeded()) {
|
||||
|
@ -552,7 +552,7 @@ public class FrontEndPlugin extends Plugin
|
|||
void selectFolder(final DomainFolder folder) {
|
||||
// Do this later in case any of the given files are newly created, which means that the
|
||||
// GUIs may have not yet been notified.
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
Swing.runLater(() -> {
|
||||
projectDataPanel.showTree();
|
||||
dataTreePanel.selectDomainFolder(folder);
|
||||
});
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -20,16 +20,18 @@ import java.util.*;
|
|||
|
||||
import javax.swing.Icon;
|
||||
|
||||
import docking.widgets.tree.GTreeLazyNode;
|
||||
import docking.widgets.tree.GTreeNode;
|
||||
import docking.widgets.tree.GTreeSlowLoadingNode;
|
||||
import ghidra.framework.model.*;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import resources.ResourceManager;
|
||||
|
||||
/**
|
||||
* Class to represent a node in the Data tree.
|
||||
*/
|
||||
public class DomainFolderNode extends GTreeLazyNode implements Cuttable {
|
||||
public class DomainFolderNode extends GTreeSlowLoadingNode implements Cuttable {
|
||||
|
||||
private static final Icon ENABLED_OPEN_FOLDER = DomainFolder.OPEN_FOLDER_ICON;
|
||||
private static final Icon ENABLED_CLOSED_FOLDER = DomainFolder.CLOSED_FOLDER_ICON;
|
||||
|
@ -127,30 +129,33 @@ public class DomainFolderNode extends GTreeLazyNode implements Cuttable {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected List<GTreeNode> generateChildren() {
|
||||
public List<GTreeNode> generateChildren(TaskMonitor monitor) throws CancelledException {
|
||||
|
||||
List<GTreeNode> children = new ArrayList<>();
|
||||
if (domainFolder != null && !domainFolder.isEmpty()) {
|
||||
if (domainFolder == null || domainFolder.isEmpty()) {
|
||||
return children;
|
||||
}
|
||||
|
||||
// NOTE: isEmpty() is used to avoid multiple failed connection attempts on this folder
|
||||
// NOTE: isEmpty() is used to avoid multiple failed connection attempts on this folder
|
||||
|
||||
DomainFolder[] folders = domainFolder.getFolders();
|
||||
for (DomainFolder folder : folders) {
|
||||
children.add(new DomainFolderNode(folder, filter));
|
||||
DomainFolder[] folders = domainFolder.getFolders();
|
||||
for (DomainFolder folder : folders) {
|
||||
monitor.checkCancelled();
|
||||
children.add(new DomainFolderNode(folder, filter));
|
||||
}
|
||||
|
||||
DomainFile[] files = domainFolder.getFiles();
|
||||
for (DomainFile domainFile : files) {
|
||||
monitor.checkCancelled();
|
||||
if (domainFile.isLinkFile() && filter != null && filter.followLinkedFolders()) {
|
||||
DomainFolder folder = domainFile.followLink();
|
||||
if (folder != null) {
|
||||
children.add(new DomainFolderNode(folder, filter));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
DomainFile[] files = domainFolder.getFiles();
|
||||
for (DomainFile domainFile : files) {
|
||||
if (domainFile.isLinkFile() && filter != null && filter.followLinkedFolders()) {
|
||||
DomainFolder folder = domainFile.followLink();
|
||||
if (folder != null) {
|
||||
children.add(new DomainFolderNode(folder, filter));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (filter == null || filter.accept(domainFile)) {
|
||||
children.add(new DomainFileNode(domainFile));
|
||||
}
|
||||
if (filter == null || filter.accept(domainFile)) {
|
||||
children.add(new DomainFileNode(domainFile));
|
||||
}
|
||||
}
|
||||
Collections.sort(children);
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -27,13 +27,15 @@ import javax.swing.tree.TreeSelectionModel;
|
|||
|
||||
import docking.ActionContext;
|
||||
import docking.ComponentProvider;
|
||||
import docking.widgets.tree.GTreeNode;
|
||||
import docking.widgets.tree.*;
|
||||
import docking.widgets.tree.support.GTreeSelectionListener;
|
||||
import ghidra.framework.main.FrontEndPlugin;
|
||||
import ghidra.framework.main.FrontEndTool;
|
||||
import ghidra.framework.model.*;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.util.HelpLocation;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import help.Help;
|
||||
import help.HelpService;
|
||||
|
||||
|
@ -100,6 +102,10 @@ public class ProjectDataTreePanel extends JPanel {
|
|||
* @param projectData data that has the root folder for the project
|
||||
*/
|
||||
public void setProjectData(String projectName, ProjectData projectData) {
|
||||
if (this.projectData == projectData) {
|
||||
return; // this can happen during setup if listeners get activated
|
||||
}
|
||||
|
||||
if (this.projectData != null) {
|
||||
this.projectData.removeDomainFolderChangeListener(changeMgr);
|
||||
}
|
||||
|
@ -138,19 +144,6 @@ public class ProjectDataTreePanel extends JPanel {
|
|||
oldRoot.removeAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the root data folder (not root node in the tree which
|
||||
* shows the project name).
|
||||
*/
|
||||
public void selectRootDataFolder() {
|
||||
tree.setSelectionPath(root.getTreePath());
|
||||
}
|
||||
|
||||
public void selectDomainFolder(DomainFolder domainFolder) {
|
||||
TreePath treePath = getTreePath(domainFolder);
|
||||
tree.setSelectionPath(treePath);
|
||||
}
|
||||
|
||||
private List<TreePath> getTreePaths(Set<DomainFile> files) {
|
||||
List<TreePath> results = new ArrayList<>();
|
||||
for (DomainFile file : files) {
|
||||
|
@ -177,24 +170,25 @@ public class ProjectDataTreePanel extends JPanel {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the root data folder (not root node in the tree which shows the project name).
|
||||
*/
|
||||
public void selectRootDataFolder() {
|
||||
tree.setSelectionPath(root.getTreePath());
|
||||
}
|
||||
|
||||
public void selectDomainFolder(DomainFolder domainFolder) {
|
||||
TreePath treePath = getTreePath(domainFolder);
|
||||
tree.expandAndSelectPaths(List.of(treePath));
|
||||
}
|
||||
|
||||
public void selectDomainFiles(Set<DomainFile> files) {
|
||||
List<TreePath> treePaths = getTreePaths(files);
|
||||
tree.setSelectionPaths(treePaths);
|
||||
tree.expandAndSelectPaths(treePaths);
|
||||
}
|
||||
|
||||
public void selectDomainFile(DomainFile domainFile) {
|
||||
Iterator<GTreeNode> it = root.iterator(true);
|
||||
while (it.hasNext()) {
|
||||
GTreeNode child = it.next();
|
||||
if (child instanceof DomainFileNode) {
|
||||
DomainFile nodeFile = ((DomainFileNode) child).getDomainFile();
|
||||
if (nodeFile.equals(domainFile)) {
|
||||
tree.expandPath(child);
|
||||
tree.setSelectedNode(child);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
selectDomainFiles(Set.of(domainFile));
|
||||
}
|
||||
|
||||
public void setHelpLocation(HelpLocation helpLocation) {
|
||||
|
@ -487,11 +481,34 @@ public class ProjectDataTreePanel extends JPanel {
|
|||
* @param s node name
|
||||
*/
|
||||
public void findAndSelect(String s) {
|
||||
if (projectData.getFileCount() < MAX_PROJECT_SIZE_TO_SEARCH) {
|
||||
tree.expandTree(root);
|
||||
FindAndSelectTask task = new FindAndSelectTask(tree, s);
|
||||
tree.runTask(task);
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
// Inner Classes
|
||||
//==================================================================================================
|
||||
|
||||
private class FindAndSelectTask extends GTreeTask {
|
||||
|
||||
private String text;
|
||||
|
||||
FindAndSelectTask(GTree gTree, String text) {
|
||||
super(gTree);
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(TaskMonitor monitor) throws CancelledException {
|
||||
|
||||
if (projectData.getFileCount() > MAX_PROJECT_SIZE_TO_SEARCH) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Iterator<GTreeNode> it = root.iterator(true); it.hasNext();) {
|
||||
monitor.checkCancelled();
|
||||
GTreeNode node = it.next();
|
||||
if (node.getName().equals(s)) {
|
||||
if (node.getName().equals(text)) {
|
||||
tree.setSelectedNode(node);
|
||||
return;
|
||||
}
|
||||
|
@ -499,10 +516,6 @@ public class ProjectDataTreePanel extends JPanel {
|
|||
}
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
// Inner Classes
|
||||
//==================================================================================================
|
||||
|
||||
private class MyMouseListener extends MouseAdapter {
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue