mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-10-23 05:31:02 +00:00
Merge remote-tracking branch 'origin/GP-4583_ghidragon_fixing_open_versioned_file_dialog--SQUASHED' into Ghidra_11.1
This commit is contained in:
commit
bb122d85e0
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package ghidra.app.plugin.core.debug.gui.modules;
|
||||
|
||||
import static ghidra.framework.main.DataTreeDialogType.*;
|
||||
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.File;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
|
@ -1190,7 +1192,7 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
|
|||
|
||||
DomainFileFilter filter = df -> Program.class.isAssignableFrom(df.getDomainObjectClass());
|
||||
|
||||
return new DataTreeDialog(null, "Map Module to Program", DataTreeDialog.OPEN, filter);
|
||||
return new DataTreeDialog(null, "Map Module to Program", OPEN, filter);
|
||||
}
|
||||
|
||||
public DomainFile askProgram(Program program) {
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package ghidra.app.plugin.core.debug.service.tracemgr;
|
||||
|
||||
import static ghidra.framework.main.DataTreeDialogType.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.net.ConnectException;
|
||||
|
@ -430,7 +432,7 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
|
|||
}
|
||||
};
|
||||
|
||||
return new DataTreeDialog(null, OpenTraceAction.NAME, DataTreeDialog.OPEN, filter);
|
||||
return new DataTreeDialog(null, OpenTraceAction.NAME, OPEN, filter);
|
||||
}
|
||||
|
||||
public DomainFile askTrace(Trace trace) {
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package ghidra.machinelearning.functionfinding;
|
||||
|
||||
import static ghidra.framework.main.DataTreeDialogType.*;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -483,10 +485,11 @@ public class FunctionStartRFParamsDialog extends ReusableDialogComponentProvider
|
|||
}
|
||||
|
||||
private void searchOtherProgram(RandomForestRowObject modelRow) {
|
||||
DataTreeDialog dtd = new DataTreeDialog(null, "Select Program", DataTreeDialog.OPEN, f -> {
|
||||
Class<?> c = f.getDomainObjectClass();
|
||||
return Program.class.isAssignableFrom(c);
|
||||
});
|
||||
DataTreeDialog dtd =
|
||||
new DataTreeDialog(null, "Select Program", OPEN, f -> {
|
||||
Class<?> c = f.getDomainObjectClass();
|
||||
return Program.class.isAssignableFrom(c);
|
||||
});
|
||||
dtd.show();
|
||||
DomainFile dFile = dtd.getDomainFile();
|
||||
if (dFile == null) {
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import static ghidra.framework.main.DataTreeDialogType.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
@ -137,7 +139,7 @@ public class FixLangId extends GhidraScript {
|
|||
|
||||
public DomainFile askProgramFile(String title) {
|
||||
final DomainFile[] domainFile = new DomainFile[] { null };
|
||||
final DataTreeDialog dtd = new DataTreeDialog(null, title, DataTreeDialog.OPEN);
|
||||
final DataTreeDialog dtd = new DataTreeDialog(null, title, OPEN);
|
||||
dtd.addOkActionListener(e -> {
|
||||
dtd.close();
|
||||
domainFile[0] = dtd.getDomainFile();
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package ghidra.app.plugin.core.analysis;
|
||||
|
||||
import static ghidra.framework.main.DataTreeDialogType.*;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.beans.PropertyEditorSupport;
|
||||
|
@ -126,7 +128,7 @@ public class ProjectPathChooserEditor extends PropertyEditorSupport {
|
|||
private void displayFileChooser() {
|
||||
AtomicReference<String> result = new AtomicReference<>();
|
||||
DataTreeDialog dataTreeDialog =
|
||||
new DataTreeDialog(this, title, DataTreeDialog.OPEN, filter);
|
||||
new DataTreeDialog(this, title, OPEN, filter);
|
||||
dataTreeDialog.addOkActionListener(e -> {
|
||||
dataTreeDialog.close();
|
||||
DomainFile df = dataTreeDialog.getDomainFile();
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package ghidra.app.plugin.core.datamgr.archive;
|
||||
|
||||
import static ghidra.framework.main.DataTreeDialogType.*;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.*;
|
||||
|
@ -31,6 +33,7 @@ import ghidra.app.plugin.core.datamgr.util.DataTypeArchiveUtility;
|
|||
import ghidra.app.util.HelpTopics;
|
||||
import ghidra.framework.client.*;
|
||||
import ghidra.framework.main.DataTreeDialog;
|
||||
import ghidra.framework.main.DataTreeDialogType;
|
||||
import ghidra.framework.model.*;
|
||||
import ghidra.framework.options.SaveState;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
|
@ -1410,7 +1413,7 @@ public class DataTypeManagerHandler {
|
|||
|
||||
private DataTreeDialog getSaveDialog() {
|
||||
DataTreeDialog dialog =
|
||||
new DataTreeDialog(null, "Save As", DataTreeDialog.SAVE, createArchiveFileFilter);
|
||||
new DataTreeDialog(null, "Save As", SAVE, createArchiveFileFilter);
|
||||
|
||||
ActionListener listener = event -> {
|
||||
DomainFolder folder = dialog.getDomainFolder();
|
||||
|
@ -1442,7 +1445,7 @@ public class DataTypeManagerHandler {
|
|||
private CreateDataTypeArchiveDataTreeDialog getCreateDialog() {
|
||||
|
||||
CreateDataTypeArchiveDataTreeDialog dialog = new CreateDataTypeArchiveDataTreeDialog(null,
|
||||
"Create", DataTreeDialog.CREATE, createArchiveFileFilter);
|
||||
"Create", CREATE, createArchiveFileFilter);
|
||||
|
||||
ActionListener listener = event -> {
|
||||
DomainFolder folder = dialog.getDomainFolder();
|
||||
|
@ -1498,7 +1501,7 @@ public class DataTypeManagerHandler {
|
|||
|
||||
private DataTypeArchiveDB dataTypeArchiveDB;
|
||||
|
||||
CreateDataTypeArchiveDataTreeDialog(Component parent, String title, int type,
|
||||
CreateDataTypeArchiveDataTreeDialog(Component parent, String title, DataTreeDialogType type,
|
||||
DomainFileFilter filter) {
|
||||
super(parent, title, type, filter);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package ghidra.app.plugin.core.gotoquery;
|
||||
|
||||
import static ghidra.framework.main.DataTreeDialogType.*;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -437,7 +439,7 @@ public class GoToHelper {
|
|||
}
|
||||
|
||||
DataTreeDialog dialog = new DataTreeDialog(null,
|
||||
"Choose External Program (" + extProgName + ")", DataTreeDialog.OPEN);
|
||||
"Choose External Program (" + extProgName + ")", OPEN);
|
||||
dialog.setSearchText(extProgName);
|
||||
dialog.setHelpLocation(new HelpLocation("ReferencesPlugin", "ChooseExternalProgram"));
|
||||
tool.showDialog(dialog);
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package ghidra.app.plugin.core.progmgr;
|
||||
|
||||
import static ghidra.framework.main.DataTreeDialogType.*;
|
||||
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.IOException;
|
||||
import java.rmi.ConnectException;
|
||||
|
@ -442,7 +444,7 @@ class ProgramSaveManager {
|
|||
|
||||
private DataTreeDialog getSaveDialog() {
|
||||
DataTreeDialog dialog =
|
||||
new DataTreeDialog(null, "Save As", DataTreeDialog.SAVE, domainFileFilter);
|
||||
new DataTreeDialog(null, "Save As", SAVE, domainFileFilter);
|
||||
|
||||
ActionListener listener = event -> {
|
||||
DomainFolder folder = dialog.getDomainFolder();
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package ghidra.app.plugin.core.references;
|
||||
|
||||
import static ghidra.framework.main.DataTreeDialogType.*;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.*;
|
||||
|
@ -186,7 +188,7 @@ class EditExternalReferencePanel extends EditReferencePanel {
|
|||
*/
|
||||
private void popupProgramChooser() {
|
||||
DataTreeDialog d =
|
||||
new DataTreeDialog(this.getParent(), "Choose External Program", DataTreeDialog.OPEN);
|
||||
new DataTreeDialog(this.getParent(), "Choose External Program", OPEN);
|
||||
final DataTreeDialog dialog = d;
|
||||
d.addOkActionListener(new ActionListener() {
|
||||
@Override
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package ghidra.app.plugin.core.references;
|
||||
|
||||
import static ghidra.framework.main.DataTreeDialogType.*;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.*;
|
||||
|
@ -236,7 +238,7 @@ public class ExternalReferencesProvider extends ComponentProviderAdapter {
|
|||
List<String> selectedExternalNames = getSelectedExternalNames();
|
||||
String externalName = selectedExternalNames.get(0); // must be exactly one for us to be enabled.
|
||||
DataTreeDialog dialog = new DataTreeDialog(mainPanel,
|
||||
"Choose External Program (" + externalName + ")", DataTreeDialog.OPEN);
|
||||
"Choose External Program (" + externalName + ")", OPEN);
|
||||
|
||||
dialog.setSearchText(externalName);
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package ghidra.app.plugin.core.symboltree;
|
||||
|
||||
import static ghidra.framework.main.DataTreeDialogType.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.util.Arrays;
|
||||
|
@ -269,7 +271,7 @@ class EditExternalLocationPanel extends JPanel {
|
|||
*/
|
||||
private void popupProgramChooser() {
|
||||
DataTreeDialog d =
|
||||
new DataTreeDialog(this.getParent(), "Choose External Program", DataTreeDialog.OPEN);
|
||||
new DataTreeDialog(this.getParent(), "Choose External Program", OPEN);
|
||||
final DataTreeDialog dialog = d;
|
||||
d.addOkActionListener(e -> {
|
||||
DomainFile df = dialog.getDomainFile();
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package ghidra.app.plugin.core.symboltree.actions;
|
||||
|
||||
import static ghidra.framework.main.DataTreeDialogType.*;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
@ -81,7 +83,7 @@ public class SetExternalProgramAction extends SymbolTreeContextAction {
|
|||
final String externalLibraryPath = externalManager.getExternalLibraryPath(externalName);
|
||||
|
||||
final DataTreeDialog dialog = new DataTreeDialog(provider.getComponent(),
|
||||
"Choose External Program (" + externalName + ")", DataTreeDialog.OPEN);
|
||||
"Choose External Program (" + externalName + ")", OPEN);
|
||||
|
||||
dialog.setSearchText(externalName);
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package ghidra.app.script;
|
||||
|
||||
import static ghidra.framework.main.DataTreeDialogType.*;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.io.*;
|
||||
import java.rmi.ConnectException;
|
||||
|
@ -2304,7 +2306,7 @@ public abstract class GhidraScript extends FlatProgramAPI {
|
|||
|
||||
DomainFolder choice = doAsk(Program.class, title, "", existingValue, lastValue -> {
|
||||
|
||||
DataTreeDialog dtd = new DataTreeDialog(null, title, DataTreeDialog.CHOOSE_FOLDER);
|
||||
DataTreeDialog dtd = new DataTreeDialog(null, title, CHOOSE_FOLDER);
|
||||
dtd.show();
|
||||
if (dtd.wasCancelled()) {
|
||||
throw new CancelledException();
|
||||
|
@ -2834,7 +2836,7 @@ public abstract class GhidraScript extends FlatProgramAPI {
|
|||
if (!isRunningHeadless()) {
|
||||
choice = doAsk(Program.class, title, "", choice, lastValue -> {
|
||||
|
||||
DataTreeDialog dtd = new DataTreeDialog(null, title, DataTreeDialog.OPEN);
|
||||
DataTreeDialog dtd = new DataTreeDialog(null, title, OPEN);
|
||||
dtd.show();
|
||||
if (dtd.wasCancelled()) {
|
||||
return null;
|
||||
|
@ -2939,7 +2941,7 @@ public abstract class GhidraScript extends FlatProgramAPI {
|
|||
String message = "";
|
||||
DomainFile choice = doAsk(DomainFile.class, title, message, existingValue, lastValue -> {
|
||||
|
||||
DataTreeDialog dtd = new DataTreeDialog(null, title, DataTreeDialog.OPEN);
|
||||
DataTreeDialog dtd = new DataTreeDialog(null, title, OPEN);
|
||||
dtd.show();
|
||||
if (dtd.wasCancelled()) {
|
||||
throw new CancelledException();
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package ghidra.app.util;
|
||||
|
||||
import static ghidra.framework.main.DataTreeDialogType.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
@ -276,7 +278,7 @@ public class OptionsEditorPanel extends JPanel {
|
|||
JButton button = new BrowseButton();
|
||||
button.addActionListener(e -> {
|
||||
DataTreeDialog dataTreeDialog =
|
||||
new DataTreeDialog(this, "Choose a project folder", DataTreeDialog.CHOOSE_FOLDER);
|
||||
new DataTreeDialog(this, "Choose a project folder", CHOOSE_FOLDER);
|
||||
String folderPath = lastFolderPath.isBlank() ? "/" : lastFolderPath;
|
||||
dataTreeDialog.setSelectedFolder(project.getProjectData().getFolder(folderPath));
|
||||
dataTreeDialog.showComponent();
|
||||
|
|
|
@ -22,6 +22,7 @@ import javax.swing.*;
|
|||
|
||||
import docking.widgets.button.BrowseButton;
|
||||
import ghidra.framework.main.DataTreeDialog;
|
||||
import ghidra.framework.main.DataTreeDialogType;
|
||||
import ghidra.framework.model.*;
|
||||
import ghidra.framework.store.FileSystem;
|
||||
|
||||
|
@ -33,10 +34,11 @@ abstract class AbstractProjectBrowserPanel extends JPanel {
|
|||
protected JTextField textField;
|
||||
private JButton browseButton;
|
||||
private DomainFolder startFolder;
|
||||
private int type;
|
||||
private DataTreeDialogType type;
|
||||
protected DomainFileFilter filter = null;
|
||||
|
||||
AbstractProjectBrowserPanel(int type, Project project, String name, String startPath) {
|
||||
AbstractProjectBrowserPanel(DataTreeDialogType type, Project project, String name,
|
||||
String startPath) {
|
||||
super(new BorderLayout());
|
||||
this.type = type;
|
||||
this.project = Objects.requireNonNull(project);
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package ghidra.features.base.values;
|
||||
|
||||
import static ghidra.framework.main.DataTreeDialogType.*;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JTextField;
|
||||
|
||||
|
@ -168,7 +170,7 @@ public class ProjectFileValue extends AbstractValue<DomainFile> {
|
|||
|
||||
ProjectFileBrowserPanel(Project project, String name, String startPath,
|
||||
Class<? extends DomainObject> projectFileClass) {
|
||||
super(DataTreeDialog.OPEN, project, name, startPath);
|
||||
super(OPEN, project, name, startPath);
|
||||
filter = df -> projectFileClass.isAssignableFrom(df.getDomainObjectClass());
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package ghidra.features.base.values;
|
||||
|
||||
import static ghidra.framework.main.DataTreeDialogType.*;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JTextField;
|
||||
|
||||
|
@ -123,7 +125,7 @@ public class ProjectFolderValue extends AbstractValue<DomainFolder> {
|
|||
class ProjectFolderBrowserPanel extends AbstractProjectBrowserPanel {
|
||||
|
||||
ProjectFolderBrowserPanel(Project project, String name, String startPath) {
|
||||
super(DataTreeDialog.CHOOSE_FOLDER, project, name, startPath);
|
||||
super(CHOOSE_FOLDER, project, name, startPath);
|
||||
}
|
||||
|
||||
void setDomainFolder(DomainFolder value) {
|
||||
|
|
|
@ -0,0 +1,602 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.framework.main;
|
||||
|
||||
import static ghidra.framework.main.DataTreeDialogType.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.TitledBorder;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
|
||||
import docking.*;
|
||||
import docking.event.mouse.GMouseListenerAdapter;
|
||||
import docking.widgets.combobox.GComboBox;
|
||||
import docking.widgets.label.GDLabel;
|
||||
import docking.widgets.label.GLabel;
|
||||
import docking.widgets.tree.support.GTreeSelectionEvent;
|
||||
import docking.widgets.tree.support.GTreeSelectionListener;
|
||||
import ghidra.framework.main.datatree.DialogProjectTreeContext;
|
||||
import ghidra.framework.main.datatree.ProjectDataTreePanel;
|
||||
import ghidra.framework.main.projectdata.actions.*;
|
||||
import ghidra.framework.model.*;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.Swing;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.layout.PairLayout;
|
||||
|
||||
/**
|
||||
* Base dialog for choosing DomainFiles. Provides and manages the base data tree panel. Subclasses
|
||||
* should call the buildDataTreePanel() when they are constructing their main panels. They should
|
||||
* also call the initializeFocusedComponent() method so that default focus for the dialog is in
|
||||
* the text field if it is enabled or otherwise the focus should be the tree.
|
||||
*/
|
||||
public abstract class AbstractDataTreeDialog extends DialogComponentProvider
|
||||
implements GTreeSelectionListener, ActionListener {
|
||||
|
||||
protected final static int WIDTH = 350;
|
||||
protected final static int HEIGHT = 500;
|
||||
|
||||
protected ProjectDataTreePanel treePanel;
|
||||
|
||||
private JComboBox<String> projectComboBox; // used for open data
|
||||
private ProjectLocator[] projectLocators;
|
||||
private DomainFileFilter filter;
|
||||
private JTextField nameField;
|
||||
private JLabel folderNameLabel;
|
||||
private ActionListener okActionListener;
|
||||
private DomainFolder domainFolder;
|
||||
private DomainFile domainFile;
|
||||
private DataTreeDialogType type;
|
||||
private Component parent;
|
||||
|
||||
private String searchString;
|
||||
private boolean cancelled = false;
|
||||
|
||||
private ProjectDataExpandAction<DialogProjectTreeContext> expandAction;
|
||||
private ProjectDataCollapseAction<DialogProjectTreeContext> collapseAction;
|
||||
private ProjectDataNewFolderAction<DialogProjectTreeContext> newFolderAction;
|
||||
|
||||
private Integer treeSelectionMode;
|
||||
private final Project project;
|
||||
|
||||
/**
|
||||
* Construct a new DataTreeDialog for the given project.
|
||||
*
|
||||
* @param parent dialog's parent
|
||||
* @param title title to use
|
||||
* @param type specify OPEN, SAVE, CHOOSE_FOLDER, or CHOOSE_USER_FOLDER
|
||||
* @param filter filter used to control what is displayed in the data tree
|
||||
* @param project the project to browse
|
||||
* @throws IllegalArgumentException if invalid type is specified
|
||||
*/
|
||||
protected AbstractDataTreeDialog(Component parent, String title, DataTreeDialogType type,
|
||||
DomainFileFilter filter, Project project) {
|
||||
super(title, true, true, true, false);
|
||||
|
||||
this.project = project;
|
||||
this.parent = parent;
|
||||
this.type = type;
|
||||
this.filter = filter;
|
||||
|
||||
initializeButtons();
|
||||
rootPanel.setPreferredSize(new Dimension(WIDTH, HEIGHT));
|
||||
|
||||
createActions();
|
||||
}
|
||||
|
||||
protected void initializeFocusedComponent() {
|
||||
Component focusComponent = nameField;
|
||||
if (!nameField.isEditable()) {
|
||||
focusComponent = treePanel.getFilterField();
|
||||
}
|
||||
setFocusComponent(focusComponent);
|
||||
}
|
||||
|
||||
public void setTreeSelectionMode(int mode) {
|
||||
if (treePanel != null) {
|
||||
treePanel.getTreeSelectionModel().setSelectionMode(mode);
|
||||
}
|
||||
treeSelectionMode = mode;
|
||||
}
|
||||
|
||||
private void initializeButtons() {
|
||||
addOKButton();
|
||||
addCancelButton();
|
||||
|
||||
if (type == SAVE) {
|
||||
okButton.setText("Save");
|
||||
okButton.setMnemonic('S');
|
||||
}
|
||||
else if (type == CREATE) {
|
||||
okButton.setText("Create");
|
||||
okButton.setMnemonic('C');
|
||||
}
|
||||
setOkEnabled(false);
|
||||
|
||||
}
|
||||
|
||||
private void createActions() {
|
||||
String owner = "DataTreeDialogActions";
|
||||
|
||||
String groupName = "Cut/copy/paste/new";
|
||||
newFolderAction = new DialogProjectDataNewFolderAction(owner, groupName);
|
||||
|
||||
groupName = "Expand/Collapse";
|
||||
expandAction = new DialogProjectDataExpandAction(owner, groupName);
|
||||
collapseAction = new DialogProjectDataCollapseAction(owner, groupName);
|
||||
|
||||
addAction(newFolderAction);
|
||||
addAction(expandAction);
|
||||
addAction(collapseAction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add action listener that is called when the OK button is hit.
|
||||
* @param l listener to add
|
||||
*/
|
||||
public void addOkActionListener(ActionListener l) {
|
||||
okActionListener = l;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionContext getActionContext(MouseEvent event) {
|
||||
if (treePanel == null) {
|
||||
// must have been closed; some kind of timing issue
|
||||
return super.getActionContext(event);
|
||||
}
|
||||
return treePanel.getActionContext(null, event);
|
||||
}
|
||||
|
||||
public void show() {
|
||||
DockingWindowManager.showDialog(parent, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows this dialog. The preferred show method is {@link #show()}, as it is the preferred
|
||||
* nomenclature.
|
||||
*/
|
||||
public void showComponent() {
|
||||
show();
|
||||
}
|
||||
|
||||
public String getNameText() {
|
||||
return nameField.getText();
|
||||
}
|
||||
|
||||
public void setNameText(String name) {
|
||||
nameField.setText(name.trim());
|
||||
nameField.selectAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a domain folder as the initially selected folder when the dialog is first shown.
|
||||
*
|
||||
* @param folder {@link DomainFolder} to select when showing the dialog
|
||||
*/
|
||||
public void setSelectedFolder(DomainFolder folder) {
|
||||
if (folder != null) {
|
||||
treePanel.selectDomainFolder(folder);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the selected domain file.
|
||||
* @return null if there was no domain file selected
|
||||
*/
|
||||
public DomainFile getDomainFile() {
|
||||
|
||||
if (domainFile != null) {
|
||||
return domainFile;
|
||||
}
|
||||
|
||||
if (cancelled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (treePanel != null) {
|
||||
domainFile = treePanel.getSelectedDomainFile();
|
||||
}
|
||||
return domainFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the selected folder.
|
||||
* @return null if there was no domain folder selected
|
||||
*/
|
||||
public DomainFolder getDomainFolder() {
|
||||
if (cancelled) {
|
||||
return null;
|
||||
}
|
||||
if (domainFolder == null) {
|
||||
domainFolder = treePanel.getSelectedDomainFolder();
|
||||
}
|
||||
return domainFolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* TreeSelectionListener method that is called whenever the value of the selection changes.
|
||||
* @param e the event that characterizes the change.
|
||||
*/
|
||||
@Override
|
||||
public void valueChanged(GTreeSelectionEvent e) {
|
||||
clearStatusText();
|
||||
|
||||
if (type == CHOOSE_FOLDER) {
|
||||
domainFolder = treePanel.getSelectedDomainFolder();
|
||||
if (domainFolder != null) {
|
||||
DomainFolder folderParent = domainFolder.getParent();
|
||||
if (folderParent != null) {
|
||||
folderNameLabel.setText(folderParent.getPathname());
|
||||
}
|
||||
else {
|
||||
folderNameLabel.setText(" ");
|
||||
}
|
||||
|
||||
nameField.setText(domainFolder.getName());
|
||||
}
|
||||
else {
|
||||
domainFile = treePanel.getSelectedDomainFile();
|
||||
if (domainFile != null) {
|
||||
domainFolder = domainFile.getParent();
|
||||
DomainFolder grandParent = domainFolder.getParent();
|
||||
if (grandParent != null) {
|
||||
folderNameLabel.setText(grandParent.getPathname());
|
||||
}
|
||||
else {
|
||||
folderNameLabel.setText("");
|
||||
}
|
||||
|
||||
nameField.setText(domainFolder.getName());
|
||||
}
|
||||
else {
|
||||
domainFolder = project.getProjectData().getRootFolder();
|
||||
folderNameLabel.setText(domainFolder.getPathname());
|
||||
nameField.setText(domainFolder.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
domainFile = treePanel.getSelectedDomainFile();
|
||||
if (domainFile != null) {
|
||||
folderNameLabel.setText(domainFile.getParent().getPathname());
|
||||
nameField.setText(domainFile.getName());
|
||||
domainFolder = domainFile.getParent();
|
||||
}
|
||||
else {
|
||||
domainFolder = treePanel.getSelectedDomainFolder();
|
||||
if (domainFolder == null) {
|
||||
domainFolder = project.getProjectData().getRootFolder();
|
||||
}
|
||||
|
||||
folderNameLabel.setText(domainFolder.getPathname());
|
||||
if (nameField.isEditable()) {
|
||||
if (nameField.getText().length() > 0) {
|
||||
nameField.selectAll();
|
||||
}
|
||||
}
|
||||
else {
|
||||
nameField.setText("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String text = nameField.getText();
|
||||
setOkEnabled((text != null) && !text.isEmpty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
int index = projectComboBox.getSelectedIndex();
|
||||
if (index < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
ProjectLocator projectLocator = projectLocators[index];
|
||||
ProjectData pd = project.getProjectData(projectLocator);
|
||||
String projectName = projectLocator.getName();
|
||||
if (pd == null) {
|
||||
Msg.showError(this, getComponent(), "Error Getting Project Data",
|
||||
"Could not get project data for " + projectName);
|
||||
}
|
||||
else {
|
||||
treePanel.setProjectData(projectName, pd);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the root folder in the tree.
|
||||
*/
|
||||
public void selectRootDataFolder() {
|
||||
Swing.runLater(() -> treePanel.selectRootDataFolder());
|
||||
}
|
||||
|
||||
/**
|
||||
* Select a folder in the tree.
|
||||
* @param folder the folder to select
|
||||
*/
|
||||
public void selectFolder(DomainFolder folder) {
|
||||
Swing.runLater(() -> treePanel.selectDomainFolder(folder));
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the node that corresponds to the given domain file.
|
||||
* @param file the file
|
||||
*/
|
||||
public void selectDomainFile(DomainFile file) {
|
||||
Swing.runLater(() -> treePanel.selectDomainFile(file));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
super.close();
|
||||
removeWorkPanel();
|
||||
if (treePanel != null) {
|
||||
treePanel.dispose();
|
||||
}
|
||||
treePanel = null;
|
||||
}
|
||||
|
||||
protected JPanel buildDataTreePanel() {
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new BorderLayout());
|
||||
|
||||
JPanel namePanel = createNamePanel();
|
||||
|
||||
// data tree panel must be created before the combo box
|
||||
JPanel dataTreePanel = createDataTreePanel();
|
||||
ProjectData pd = project.getProjectData();
|
||||
treePanel.setProjectData(project.getName(), pd);
|
||||
treePanel.selectRootDataFolder();
|
||||
|
||||
if (type == OPEN) {
|
||||
JPanel comboPanel = createComboBoxPanel();
|
||||
|
||||
panel.add(comboPanel, BorderLayout.NORTH);
|
||||
populateProjectModel();
|
||||
}
|
||||
|
||||
panel.add(dataTreePanel, BorderLayout.CENTER);
|
||||
panel.add(namePanel, BorderLayout.SOUTH);
|
||||
|
||||
// can't add tree listeners until everything is built
|
||||
addTreeListeners();
|
||||
return panel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void okCallback() {
|
||||
cancelled = false;
|
||||
|
||||
if (okActionListener == null) {
|
||||
close();
|
||||
return;
|
||||
}
|
||||
okActionListener.actionPerformed(new ActionEvent(okButton, 0, okButton.getActionCommand()));
|
||||
}
|
||||
|
||||
public boolean wasCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void cancelCallback() {
|
||||
cancelled = true;
|
||||
close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the data tree panel.
|
||||
*/
|
||||
private JPanel createDataTreePanel() {
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new BorderLayout());
|
||||
ProjectData pd = project.getProjectData();
|
||||
|
||||
treePanel = new ProjectDataTreePanel(project.getName(), true, // is for the active project
|
||||
null, filter);
|
||||
if (treeSelectionMode != null) {
|
||||
treePanel.getTreeSelectionModel().setSelectionMode(treeSelectionMode);
|
||||
}
|
||||
treePanel.setProjectData(project.getName(), pd);
|
||||
treePanel.addTreeSelectionListener(this);
|
||||
treePanel.setPreferredTreePanelSize(new Dimension(150, 150));
|
||||
|
||||
// don't put the filter in the dialog when the user can/must type a name, as it's confusing
|
||||
boolean userChoosesName = (type == SAVE) || (type == CREATE);
|
||||
treePanel.setTreeFilterEnabled(!userChoosesName);
|
||||
|
||||
panel.add(treePanel, BorderLayout.CENTER);
|
||||
return panel;
|
||||
}
|
||||
|
||||
protected void addTreeListeners() {
|
||||
if (type == OPEN) {
|
||||
|
||||
treePanel.addTreeMouseListener(new GMouseListenerAdapter() {
|
||||
@Override
|
||||
public void doubleClickTriggered(MouseEvent e) {
|
||||
if (okButton.isEnabled()) {
|
||||
okCallback();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the combo box panel that shows list of project names that
|
||||
* are currently open, including the active project.
|
||||
*/
|
||||
private JPanel createComboBoxPanel() {
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new BorderLayout());
|
||||
panel.setBorder(new TitledBorder("Current Projects"));
|
||||
projectComboBox = new GComboBox<>();
|
||||
DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>();
|
||||
projectComboBox.setModel(model);
|
||||
model.addElement("defaultProject");
|
||||
panel.add(projectComboBox, BorderLayout.CENTER);
|
||||
projectComboBox.addActionListener(this);
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
private JPanel createNamePanel() {
|
||||
|
||||
JPanel outerPanel = new JPanel();
|
||||
outerPanel.setLayout(new BorderLayout(5, 0));
|
||||
|
||||
nameField = new JTextField(12);
|
||||
nameField.getDocument().addDocumentListener(new DocumentListener() {
|
||||
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
update();
|
||||
}
|
||||
|
||||
private void update() {
|
||||
String text = nameField.getText();
|
||||
|
||||
switch (type) {
|
||||
case OPEN:
|
||||
// handled by valueChanged()
|
||||
break;
|
||||
case SAVE:
|
||||
if (text == null || text.isEmpty()) {
|
||||
DomainFile file = treePanel.getSelectedDomainFile();
|
||||
okButton.setEnabled(file != null);
|
||||
}
|
||||
break;
|
||||
case CREATE:
|
||||
if (text == null || text.isEmpty()) {
|
||||
DomainFile file = treePanel.getSelectedDomainFile();
|
||||
okButton.setEnabled(file != null);
|
||||
}
|
||||
break;
|
||||
case CHOOSE_FOLDER:
|
||||
// handled by valueChanged()
|
||||
break;
|
||||
default:
|
||||
throw new AssertException("Must handle new type!: " + type);
|
||||
}
|
||||
|
||||
setOkEnabled((text != null) && !text.isEmpty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
update();
|
||||
}
|
||||
});
|
||||
|
||||
boolean userChoosesName = (type == SAVE) || (type == CREATE);
|
||||
nameField.setEditable(userChoosesName);
|
||||
nameField.setEnabled(userChoosesName);
|
||||
|
||||
JPanel namePanel = new JPanel(new PairLayout(2, 5, 100));
|
||||
|
||||
if (!userChoosesName) {
|
||||
namePanel.setBorder(BorderFactory.createEmptyBorder(20, 5, 5, 5));
|
||||
}
|
||||
namePanel.add(new GLabel("Folder Path:", SwingConstants.RIGHT));
|
||||
|
||||
folderNameLabel = new GDLabel(" ");
|
||||
namePanel.add(folderNameLabel);
|
||||
|
||||
namePanel.add(
|
||||
new GLabel(type == CHOOSE_FOLDER ? "Folder Name:" : "Name:", SwingConstants.RIGHT));
|
||||
namePanel.add(nameField);
|
||||
|
||||
outerPanel.add(namePanel, BorderLayout.CENTER);
|
||||
|
||||
FieldKeyListener l = new FieldKeyListener();
|
||||
nameField.addKeyListener(l);
|
||||
nameField.addActionListener(e -> okCallback());
|
||||
|
||||
return outerPanel;
|
||||
}
|
||||
|
||||
private void populateProjectModel() {
|
||||
ProjectLocator[] views = project.getProjectViews();
|
||||
|
||||
projectLocators = new ProjectLocator[views.length + 1];
|
||||
// make the current project the first in the list
|
||||
projectLocators[0] = project.getProjectLocator();
|
||||
for (int i = 0; i < views.length; i++) {
|
||||
projectLocators[i + 1] = views[i];
|
||||
}
|
||||
|
||||
// populate the combo box
|
||||
DefaultComboBoxModel<String> model =
|
||||
(DefaultComboBoxModel<String>) projectComboBox.getModel();
|
||||
model.removeAllElements();
|
||||
|
||||
Set<String> map = new HashSet<>();
|
||||
for (ProjectLocator projectLocator : projectLocators) {
|
||||
String name = projectLocator.getName();
|
||||
if (map.contains(name)) {
|
||||
model.addElement(name + " (" + projectLocator.getLocation() + ")");
|
||||
}
|
||||
else {
|
||||
map.add(name);
|
||||
model.addElement(name);
|
||||
}
|
||||
}
|
||||
map = null;
|
||||
}
|
||||
|
||||
public void setSearchText(String s) {
|
||||
if (searchString != null) {
|
||||
treePanel.findAndSelect(s);
|
||||
}
|
||||
}
|
||||
|
||||
protected static DomainFileFilter getDefaultFilter(DataTreeDialogType type) {
|
||||
if (type == CHOOSE_FOLDER || type == OPEN) {
|
||||
// return filter which forces folder selection and allow navigation into linked-folders
|
||||
return new DomainFileFilter() {
|
||||
|
||||
@Override
|
||||
public boolean accept(DomainFile df) {
|
||||
return true; // show all files (legacy behavior)
|
||||
}
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private class FieldKeyListener extends KeyAdapter {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
clearStatusText();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -15,85 +15,26 @@
|
|||
*/
|
||||
package ghidra.framework.main;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.awt.Component;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.TitledBorder;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
|
||||
import docking.*;
|
||||
import docking.event.mouse.GMouseListenerAdapter;
|
||||
import docking.widgets.combobox.GComboBox;
|
||||
import docking.widgets.label.GDLabel;
|
||||
import docking.widgets.label.GLabel;
|
||||
import docking.widgets.tree.support.GTreeSelectionEvent;
|
||||
import docking.widgets.tree.support.GTreeSelectionListener;
|
||||
import ghidra.framework.main.datatree.DialogProjectTreeContext;
|
||||
import ghidra.framework.main.datatree.ProjectDataTreePanel;
|
||||
import ghidra.framework.main.projectdata.actions.*;
|
||||
import ghidra.framework.model.*;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.Swing;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.layout.PairLayout;
|
||||
import ghidra.framework.model.DomainFileFilter;
|
||||
import ghidra.framework.model.Project;
|
||||
|
||||
/**
|
||||
* Dialog to open or save domain data items to a new location or name.
|
||||
*/
|
||||
public class DataTreeDialog extends DialogComponentProvider
|
||||
implements GTreeSelectionListener, ActionListener {
|
||||
public class DataTreeDialog extends AbstractDataTreeDialog {
|
||||
|
||||
/**
|
||||
* Dialog type for opening domain data files.
|
||||
*/
|
||||
public final static int OPEN = 0;
|
||||
/**
|
||||
* Dialog type for saving domain data files.
|
||||
*/
|
||||
public final static int SAVE = 1;
|
||||
/**
|
||||
* Dialog type for choosing a user folder.
|
||||
*/
|
||||
public final static int CHOOSE_FOLDER = 2;
|
||||
/**
|
||||
* Dialog type for creating domain data files.
|
||||
*/
|
||||
public final static int CREATE = 3;
|
||||
|
||||
protected final static int WIDTH = 350;
|
||||
protected final static int HEIGHT = 500;
|
||||
|
||||
protected ProjectDataTreePanel treePanel;
|
||||
|
||||
private JComboBox<String> projectComboBox; // used for open data
|
||||
private ProjectLocator[] projectLocators;
|
||||
private DomainFileFilter filter;
|
||||
private JTextField nameField;
|
||||
private JLabel folderNameLabel;
|
||||
private ActionListener okActionListener;
|
||||
private DomainFolder domainFolder;
|
||||
private DomainFile domainFile;
|
||||
private int type;
|
||||
private Component parent;
|
||||
|
||||
private String searchString;
|
||||
private boolean cancelled = false;
|
||||
|
||||
private ProjectDataExpandAction<DialogProjectTreeContext> expandAction;
|
||||
private ProjectDataCollapseAction<DialogProjectTreeContext> collapseAction;
|
||||
private ProjectDataNewFolderAction<DialogProjectTreeContext> newFolderAction;
|
||||
|
||||
private Integer treeSelectionMode;
|
||||
private final Project project;
|
||||
// These are here for backwards compatibility with legacy code
|
||||
public final static DataTreeDialogType OPEN = DataTreeDialogType.OPEN;
|
||||
public final static DataTreeDialogType SAVE = DataTreeDialogType.SAVE;
|
||||
public final static DataTreeDialogType CHOOSE_FOLDER = DataTreeDialogType.CHOOSE_FOLDER;
|
||||
public final static DataTreeDialogType CREATE = DataTreeDialogType.CREATE;
|
||||
|
||||
/**
|
||||
* Construct a new DataTreeDialog for the active project. This chooser will show all project
|
||||
* files. Following linked-folders will only be allowed if a type of {@link #CHOOSE_FOLDER}
|
||||
* or {@link #OPEN} is specified. If different behavior is required a filter should
|
||||
* files. Following linked-folders will only be allowed if a type of CHOOSE_FOLDER
|
||||
* or OPEN is specified. If different behavior is required a filter should
|
||||
* be specified using the other constructor.
|
||||
*
|
||||
* @param parent dialog's parent
|
||||
|
@ -101,8 +42,8 @@ public class DataTreeDialog extends DialogComponentProvider
|
|||
* @param type specify OPEN, SAVE, CHOOSE_FOLDER, CHOOSE_USER_FOLDER, or CREATE
|
||||
* @throws IllegalArgumentException if invalid type is specified
|
||||
*/
|
||||
public DataTreeDialog(Component parent, String title, int type) {
|
||||
this(parent, title, type, getDefaultFilter(type), AppInfo.getActiveProject());
|
||||
public DataTreeDialog(Component parent, String title, DataTreeDialogType type) {
|
||||
this(parent, title, type, getDefaultFilter(type));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -110,11 +51,12 @@ public class DataTreeDialog extends DialogComponentProvider
|
|||
*
|
||||
* @param parent dialog's parent
|
||||
* @param title title to use
|
||||
* @param type specify OPEN, SAVE, CHOOSE_FOLDER, or CHOOSE_USER_FOLDER
|
||||
* @param type specify OPEN, SAVE, CHOOSE_FOLDER, or CREATE
|
||||
* @param filter filter used to control what is displayed in the data tree
|
||||
* @throws IllegalArgumentException if invalid type is specified
|
||||
*/
|
||||
public DataTreeDialog(Component parent, String title, int type, DomainFileFilter filter) {
|
||||
public DataTreeDialog(Component parent, String title, DataTreeDialogType type,
|
||||
DomainFileFilter filter) {
|
||||
this(parent, title, type, filter, AppInfo.getActiveProject());
|
||||
}
|
||||
|
||||
|
@ -123,527 +65,17 @@ public class DataTreeDialog extends DialogComponentProvider
|
|||
*
|
||||
* @param parent dialog's parent
|
||||
* @param title title to use
|
||||
* @param type specify OPEN, SAVE, CHOOSE_FOLDER, or CHOOSE_USER_FOLDER
|
||||
* @param type specify OPEN, SAVE, CHOOSE_FOLDER, or CREATE
|
||||
* @param filter filter used to control what is displayed in the data tree
|
||||
* @param project the project to browse
|
||||
* @throws IllegalArgumentException if invalid type is specified
|
||||
*/
|
||||
public DataTreeDialog(Component parent, String title, int type, DomainFileFilter filter,
|
||||
Project project) {
|
||||
super(title, true, true, true, false);
|
||||
|
||||
if (type < 0 || type > CREATE) {
|
||||
throw new IllegalArgumentException("Invalid type specified: " + type);
|
||||
}
|
||||
|
||||
this.project = project;
|
||||
this.parent = parent;
|
||||
this.type = type;
|
||||
this.filter = filter;
|
||||
|
||||
addWorkPanel(buildMainPanel());
|
||||
initializeButtons();
|
||||
rootPanel.setPreferredSize(new Dimension(WIDTH, HEIGHT));
|
||||
public DataTreeDialog(Component parent, String title, DataTreeDialogType type,
|
||||
DomainFileFilter filter, Project project) {
|
||||
super(parent, title, type, filter, project);
|
||||
|
||||
addWorkPanel(buildDataTreePanel());
|
||||
initializeFocusedComponent();
|
||||
|
||||
createActions();
|
||||
}
|
||||
|
||||
private void initializeFocusedComponent() {
|
||||
Component focusComponent = nameField;
|
||||
if (!nameField.isEditable()) {
|
||||
focusComponent = treePanel.getFilterField();
|
||||
}
|
||||
setFocusComponent(focusComponent);
|
||||
}
|
||||
|
||||
public void setTreeSelectionMode(int mode) {
|
||||
if (treePanel != null) {
|
||||
treePanel.getTreeSelectionModel().setSelectionMode(mode);
|
||||
}
|
||||
treeSelectionMode = mode;
|
||||
}
|
||||
|
||||
private void initializeButtons() {
|
||||
addOKButton();
|
||||
addCancelButton();
|
||||
|
||||
if (type == SAVE) {
|
||||
okButton.setText("Save");
|
||||
okButton.setMnemonic('S');
|
||||
}
|
||||
else if (type == CREATE) {
|
||||
okButton.setText("Create");
|
||||
okButton.setMnemonic('C');
|
||||
}
|
||||
setOkEnabled(false);
|
||||
|
||||
}
|
||||
|
||||
private void createActions() {
|
||||
String owner = "DataTreeDialogActions";
|
||||
|
||||
String groupName = "Cut/copy/paste/new";
|
||||
newFolderAction = new DialogProjectDataNewFolderAction(owner, groupName);
|
||||
|
||||
groupName = "Expand/Collapse";
|
||||
expandAction = new DialogProjectDataExpandAction(owner, groupName);
|
||||
collapseAction = new DialogProjectDataCollapseAction(owner, groupName);
|
||||
|
||||
addAction(newFolderAction);
|
||||
addAction(expandAction);
|
||||
addAction(collapseAction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add action listener that is called when the OK button is hit.
|
||||
* @param l listener to add
|
||||
*/
|
||||
public void addOkActionListener(ActionListener l) {
|
||||
okActionListener = l;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionContext getActionContext(MouseEvent event) {
|
||||
if (treePanel == null) {
|
||||
// must have been closed; some kind of timing issue
|
||||
return super.getActionContext(event);
|
||||
}
|
||||
return treePanel.getActionContext(null, event);
|
||||
}
|
||||
|
||||
public void show() {
|
||||
DockingWindowManager.showDialog(parent, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows this dialog. The preferred show method is {@link #show()}, as it is the preferred
|
||||
* nomenclature.
|
||||
*/
|
||||
public void showComponent() {
|
||||
show();
|
||||
}
|
||||
|
||||
public String getNameText() {
|
||||
return nameField.getText();
|
||||
}
|
||||
|
||||
public void setNameText(String name) {
|
||||
nameField.setText(name.trim());
|
||||
nameField.selectAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a domain folder as the initially selected folder when the dialog is first shown.
|
||||
*
|
||||
* @param folder {@link DomainFolder} to select when showing the dialog
|
||||
*/
|
||||
public void setSelectedFolder(DomainFolder folder) {
|
||||
if (folder != null) {
|
||||
treePanel.selectDomainFolder(folder);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the selected domain file.
|
||||
* @return null if there was no domain file selected
|
||||
*/
|
||||
public DomainFile getDomainFile() {
|
||||
|
||||
if (domainFile != null) {
|
||||
return domainFile;
|
||||
}
|
||||
|
||||
if (cancelled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (treePanel != null) {
|
||||
domainFile = treePanel.getSelectedDomainFile();
|
||||
}
|
||||
return domainFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the selected folder.
|
||||
* @return null if there was no domain folder selected
|
||||
*/
|
||||
public DomainFolder getDomainFolder() {
|
||||
if (cancelled) {
|
||||
return null;
|
||||
}
|
||||
if (domainFolder == null) {
|
||||
domainFolder = treePanel.getSelectedDomainFolder();
|
||||
}
|
||||
return domainFolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* TreeSelectionListener method that is called whenever the value of the selection changes.
|
||||
* @param e the event that characterizes the change.
|
||||
*/
|
||||
@Override
|
||||
public void valueChanged(GTreeSelectionEvent e) {
|
||||
clearStatusText();
|
||||
|
||||
if (type == CHOOSE_FOLDER) {
|
||||
domainFolder = treePanel.getSelectedDomainFolder();
|
||||
if (domainFolder != null) {
|
||||
DomainFolder folderParent = domainFolder.getParent();
|
||||
if (folderParent != null) {
|
||||
folderNameLabel.setText(folderParent.getPathname());
|
||||
}
|
||||
else {
|
||||
folderNameLabel.setText(" ");
|
||||
}
|
||||
|
||||
nameField.setText(domainFolder.getName());
|
||||
}
|
||||
else {
|
||||
domainFile = treePanel.getSelectedDomainFile();
|
||||
if (domainFile != null) {
|
||||
domainFolder = domainFile.getParent();
|
||||
DomainFolder grandParent = domainFolder.getParent();
|
||||
if (grandParent != null) {
|
||||
folderNameLabel.setText(grandParent.getPathname());
|
||||
}
|
||||
else {
|
||||
folderNameLabel.setText("");
|
||||
}
|
||||
|
||||
nameField.setText(domainFolder.getName());
|
||||
}
|
||||
else {
|
||||
domainFolder = project.getProjectData().getRootFolder();
|
||||
folderNameLabel.setText(domainFolder.getPathname());
|
||||
nameField.setText(domainFolder.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
domainFile = treePanel.getSelectedDomainFile();
|
||||
if (domainFile != null) {
|
||||
folderNameLabel.setText(domainFile.getParent().getPathname());
|
||||
nameField.setText(domainFile.getName());
|
||||
domainFolder = domainFile.getParent();
|
||||
}
|
||||
else {
|
||||
domainFolder = treePanel.getSelectedDomainFolder();
|
||||
if (domainFolder == null) {
|
||||
domainFolder = project.getProjectData().getRootFolder();
|
||||
}
|
||||
|
||||
folderNameLabel.setText(domainFolder.getPathname());
|
||||
if (nameField.isEditable()) {
|
||||
if (nameField.getText().length() > 0) {
|
||||
nameField.selectAll();
|
||||
}
|
||||
}
|
||||
else {
|
||||
nameField.setText("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String text = nameField.getText();
|
||||
setOkEnabled((text != null) && !text.isEmpty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
int index = projectComboBox.getSelectedIndex();
|
||||
if (index < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
ProjectLocator projectLocator = projectLocators[index];
|
||||
ProjectData pd = project.getProjectData(projectLocator);
|
||||
String projectName = projectLocator.getName();
|
||||
if (pd == null) {
|
||||
Msg.showError(this, getComponent(), "Error Getting Project Data",
|
||||
"Could not get project data for " + projectName);
|
||||
}
|
||||
else {
|
||||
treePanel.setProjectData(projectName, pd);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the root folder in the tree.
|
||||
*/
|
||||
public void selectRootDataFolder() {
|
||||
Swing.runLater(() -> treePanel.selectRootDataFolder());
|
||||
}
|
||||
|
||||
/**
|
||||
* Select a folder in the tree.
|
||||
* @param folder the folder to select
|
||||
*/
|
||||
public void selectFolder(DomainFolder folder) {
|
||||
Swing.runLater(() -> treePanel.selectDomainFolder(folder));
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the node that corresponds to the given domain file.
|
||||
* @param file the file
|
||||
*/
|
||||
public void selectDomainFile(DomainFile file) {
|
||||
Swing.runLater(() -> treePanel.selectDomainFile(file));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
super.close();
|
||||
removeWorkPanel();
|
||||
if (treePanel != null) {
|
||||
treePanel.dispose();
|
||||
}
|
||||
treePanel = null;
|
||||
}
|
||||
|
||||
protected JPanel buildMainPanel() {
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new BorderLayout());
|
||||
|
||||
JPanel namePanel = createNamePanel();
|
||||
|
||||
// data tree panel must be created before the combo box
|
||||
JPanel dataTreePanel = createDataTreePanel();
|
||||
ProjectData pd = project.getProjectData();
|
||||
treePanel.setProjectData(project.getName(), pd);
|
||||
treePanel.selectRootDataFolder();
|
||||
|
||||
if (type == OPEN) {
|
||||
JPanel comboPanel = createComboBoxPanel();
|
||||
|
||||
panel.add(comboPanel, BorderLayout.NORTH);
|
||||
populateProjectModel();
|
||||
}
|
||||
|
||||
panel.add(dataTreePanel, BorderLayout.CENTER);
|
||||
panel.add(namePanel, BorderLayout.SOUTH);
|
||||
|
||||
// can't add tree listeners until everything is built
|
||||
addTreeListeners();
|
||||
return panel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void okCallback() {
|
||||
cancelled = false;
|
||||
|
||||
if (okActionListener == null) {
|
||||
close();
|
||||
return;
|
||||
}
|
||||
okActionListener.actionPerformed(new ActionEvent(okButton, 0, okButton.getActionCommand()));
|
||||
}
|
||||
|
||||
public boolean wasCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void cancelCallback() {
|
||||
cancelled = true;
|
||||
close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the data tree panel.
|
||||
*/
|
||||
private JPanel createDataTreePanel() {
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new BorderLayout());
|
||||
ProjectData pd = project.getProjectData();
|
||||
|
||||
treePanel = new ProjectDataTreePanel(project.getName(), true, // is for the active project
|
||||
null, filter);
|
||||
if (treeSelectionMode != null) {
|
||||
treePanel.getTreeSelectionModel().setSelectionMode(treeSelectionMode);
|
||||
}
|
||||
treePanel.setProjectData(project.getName(), pd);
|
||||
treePanel.addTreeSelectionListener(this);
|
||||
treePanel.setPreferredTreePanelSize(new Dimension(150, 150));
|
||||
|
||||
// don't put the filter in the dialog when the user can/must type a name, as it's confusing
|
||||
boolean userChoosesName = (type == SAVE) || (type == CREATE);
|
||||
treePanel.setTreeFilterEnabled(!userChoosesName);
|
||||
|
||||
panel.add(treePanel, BorderLayout.CENTER);
|
||||
return panel;
|
||||
}
|
||||
|
||||
protected void addTreeListeners() {
|
||||
if (type == OPEN) {
|
||||
|
||||
treePanel.addTreeMouseListener(new GMouseListenerAdapter() {
|
||||
@Override
|
||||
public void doubleClickTriggered(MouseEvent e) {
|
||||
if (okButton.isEnabled()) {
|
||||
okCallback();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the combo box panel that shows list of project names that
|
||||
* are currently open, including the active project.
|
||||
*/
|
||||
private JPanel createComboBoxPanel() {
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new BorderLayout());
|
||||
panel.setBorder(new TitledBorder("Current Projects"));
|
||||
projectComboBox = new GComboBox<>();
|
||||
DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>();
|
||||
projectComboBox.setModel(model);
|
||||
model.addElement("defaultProject");
|
||||
panel.add(projectComboBox, BorderLayout.CENTER);
|
||||
projectComboBox.addActionListener(this);
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
private JPanel createNamePanel() {
|
||||
|
||||
JPanel outerPanel = new JPanel();
|
||||
outerPanel.setLayout(new BorderLayout(5, 0));
|
||||
|
||||
nameField = new JTextField(12);
|
||||
nameField.getDocument().addDocumentListener(new DocumentListener() {
|
||||
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
update();
|
||||
}
|
||||
|
||||
private void update() {
|
||||
String text = nameField.getText();
|
||||
|
||||
switch (type) {
|
||||
case OPEN:
|
||||
// handled by valueChanged()
|
||||
break;
|
||||
case SAVE:
|
||||
if (text == null || text.isEmpty()) {
|
||||
DomainFile file = treePanel.getSelectedDomainFile();
|
||||
okButton.setEnabled(file != null);
|
||||
}
|
||||
break;
|
||||
case CREATE:
|
||||
if (text == null || text.isEmpty()) {
|
||||
DomainFile file = treePanel.getSelectedDomainFile();
|
||||
okButton.setEnabled(file != null);
|
||||
}
|
||||
break;
|
||||
case CHOOSE_FOLDER:
|
||||
// handled by valueChanged()
|
||||
break;
|
||||
default:
|
||||
throw new AssertException("Must handle new type!: " + type);
|
||||
}
|
||||
|
||||
setOkEnabled((text != null) && !text.isEmpty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
update();
|
||||
}
|
||||
});
|
||||
|
||||
boolean userChoosesName = (type == SAVE) || (type == CREATE);
|
||||
nameField.setEditable(userChoosesName);
|
||||
nameField.setEnabled(userChoosesName);
|
||||
|
||||
JPanel namePanel = new JPanel(new PairLayout(2, 5, 100));
|
||||
|
||||
if (!userChoosesName) {
|
||||
namePanel.setBorder(BorderFactory.createEmptyBorder(20, 5, 5, 5));
|
||||
}
|
||||
namePanel.add(new GLabel("Folder Path:", SwingConstants.RIGHT));
|
||||
|
||||
folderNameLabel = new GDLabel(" ");
|
||||
namePanel.add(folderNameLabel);
|
||||
|
||||
namePanel.add(
|
||||
new GLabel(type == CHOOSE_FOLDER ? "Folder Name:" : "Name:", SwingConstants.RIGHT));
|
||||
namePanel.add(nameField);
|
||||
|
||||
outerPanel.add(namePanel, BorderLayout.CENTER);
|
||||
|
||||
FieldKeyListener l = new FieldKeyListener();
|
||||
nameField.addKeyListener(l);
|
||||
nameField.addActionListener(e -> okCallback());
|
||||
|
||||
return outerPanel;
|
||||
}
|
||||
|
||||
private void populateProjectModel() {
|
||||
ProjectLocator[] views = project.getProjectViews();
|
||||
|
||||
projectLocators = new ProjectLocator[views.length + 1];
|
||||
// make the current project the first in the list
|
||||
projectLocators[0] = project.getProjectLocator();
|
||||
for (int i = 0; i < views.length; i++) {
|
||||
projectLocators[i + 1] = views[i];
|
||||
}
|
||||
|
||||
// populate the combo box
|
||||
DefaultComboBoxModel<String> model =
|
||||
(DefaultComboBoxModel<String>) projectComboBox.getModel();
|
||||
model.removeAllElements();
|
||||
|
||||
Set<String> map = new HashSet<>();
|
||||
for (ProjectLocator projectLocator : projectLocators) {
|
||||
String name = projectLocator.getName();
|
||||
if (map.contains(name)) {
|
||||
model.addElement(name + " (" + projectLocator.getLocation() + ")");
|
||||
}
|
||||
else {
|
||||
map.add(name);
|
||||
model.addElement(name);
|
||||
}
|
||||
}
|
||||
map = null;
|
||||
}
|
||||
|
||||
public void setSearchText(String s) {
|
||||
if (searchString != null) {
|
||||
treePanel.findAndSelect(s);
|
||||
}
|
||||
}
|
||||
|
||||
private static DomainFileFilter getDefaultFilter(int type) {
|
||||
if (type == CHOOSE_FOLDER || type == OPEN) {
|
||||
// return filter which forces folder selection and allow navigation into linked-folders
|
||||
return new DomainFileFilter() {
|
||||
|
||||
@Override
|
||||
public boolean accept(DomainFile df) {
|
||||
return true; // show all files (legacy behavior)
|
||||
}
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private class FieldKeyListener extends KeyAdapter {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
clearStatusText();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.framework.main;
|
||||
|
||||
/**
|
||||
* Types of ways to use a DataTreeDialog.
|
||||
*/
|
||||
public enum DataTreeDialogType {
|
||||
/**
|
||||
* Dialog type for opening domain data files
|
||||
*/
|
||||
OPEN,
|
||||
/**
|
||||
* Dialog type for saving domain data files
|
||||
*/
|
||||
SAVE,
|
||||
/**
|
||||
* Dialog type for choosing a user folder
|
||||
*/
|
||||
CHOOSE_FOLDER,
|
||||
/**
|
||||
* Dialog type for creating domain data files
|
||||
*/
|
||||
CREATE
|
||||
}
|
|
@ -15,10 +15,11 @@
|
|||
*/
|
||||
package ghidra.framework.main;
|
||||
|
||||
import static ghidra.framework.main.DataTreeDialogType.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -40,7 +41,7 @@ import ghidra.util.Msg;
|
|||
* opened.
|
||||
* @param <T> domain object class
|
||||
*/
|
||||
public class OpenVersionedFileDialog<T extends DomainObject> extends DataTreeDialog {
|
||||
public class OpenVersionedFileDialog<T extends DomainObject> extends AbstractDataTreeDialog {
|
||||
private static final String SHOW_HISTORY_PREFERENCES_KEY = "OPEN_PROGRAM_DIALOG.SHOW_HISTORY";
|
||||
private static final String HEIGHT_PREFERENCES_KEY = "OPEN_PROGRAM_DIALOG.HEIGHT";
|
||||
private static final String WIDTH_NO_HISTORY_PREFERENCES_KEY =
|
||||
|
@ -76,12 +77,30 @@ public class OpenVersionedFileDialog<T extends DomainObject> extends DataTreeDia
|
|||
* @param domainObjectClass allowed domain object class which corresponds to {@code <T>}
|
||||
*/
|
||||
public OpenVersionedFileDialog(PluginTool tool, String title, Class<T> domainObjectClass) {
|
||||
super(tool.getToolFrame(), title, DataTreeDialog.OPEN, f -> {
|
||||
this(tool, title, domainObjectClass, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param tool tool where the file is being opened.
|
||||
* @param title title to use
|
||||
* @param domainObjectClass allowed domain object class which corresponds to {@code <T>}
|
||||
* @param openDomainObjects if non-null, will cause an additional tab showing the given
|
||||
* list of open domain objects that the user can select from
|
||||
*/
|
||||
public OpenVersionedFileDialog(PluginTool tool, String title, Class<T> domainObjectClass,
|
||||
List<T> openDomainObjects) {
|
||||
super(tool.getToolFrame(), title, OPEN, f -> {
|
||||
return domainObjectClass.isAssignableFrom(f.getDomainObjectClass());
|
||||
});
|
||||
}, AppInfo.getActiveProject());
|
||||
|
||||
this.tool = tool;
|
||||
this.domainObjectClass = domainObjectClass;
|
||||
this.openDomainObjects = openDomainObjects;
|
||||
|
||||
addWorkPanel(buildMainPanel());
|
||||
initializeFocusedComponent();
|
||||
|
||||
updateOkTooltip();
|
||||
checkIfHistoryWasOpen();
|
||||
}
|
||||
|
@ -95,20 +114,6 @@ public class OpenVersionedFileDialog<T extends DomainObject> extends DataTreeDia
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an optional list of already open domain objects of type {@code <T>} which may be
|
||||
* selected instead of a project domain file. The {@link #getDomainObject(Object, boolean)}
|
||||
* method should be used when this optional list has been set. If this dialog is reused
|
||||
* the list should be set null if previously set. This method must be invoked prior to
|
||||
* showing the dialog.
|
||||
* @param openDomainObjects list of open domain objects from which a selection may be made.
|
||||
*/
|
||||
public void setOpenObjectChoices(List<T> openDomainObjects) {
|
||||
this.openDomainObjects = (openDomainObjects != null && !openDomainObjects.isEmpty())
|
||||
? new ArrayList<>(openDomainObjects)
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the selected domain object for read-only or immutable use.
|
||||
* If an existing open object is selected its original mode applies but consumer will
|
||||
|
@ -173,7 +178,6 @@ public class OpenVersionedFileDialog<T extends DomainObject> extends DataTreeDia
|
|||
return super.getDomainFolder();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JPanel buildMainPanel() {
|
||||
historyButton = new JButton("History>>");
|
||||
historyButton.addActionListener(e -> showHistoryPanel(!historyIsShowing));
|
||||
|
@ -181,7 +185,7 @@ public class OpenVersionedFileDialog<T extends DomainObject> extends DataTreeDia
|
|||
rootPanel.setPreferredSize(getPreferredSizeForHistoryState());
|
||||
|
||||
mainPanel = new JPanel(new BorderLayout());
|
||||
mainPanel.add(super.buildMainPanel(), BorderLayout.CENTER);
|
||||
mainPanel.add(buildDataTreePanel(), BorderLayout.CENTER);
|
||||
JPanel historyButtonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
|
||||
historyButtonPanel.add(historyButton);
|
||||
mainPanel.add(historyButtonPanel, BorderLayout.SOUTH);
|
||||
|
@ -201,7 +205,7 @@ public class OpenVersionedFileDialog<T extends DomainObject> extends DataTreeDia
|
|||
openObjectsTable = null;
|
||||
tabbedPane = null;
|
||||
|
||||
if (openDomainObjects == null) {
|
||||
if (openDomainObjects == null || openDomainObjects.isEmpty()) {
|
||||
return projectFilePanel; // return Project File selection panel only
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package ghidra.plugin.importer;
|
||||
|
||||
import static ghidra.framework.main.DataTreeDialogType.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
@ -571,7 +573,7 @@ public class ImporterDialog extends DialogComponentProvider {
|
|||
|
||||
private void chooseProjectFolder() {
|
||||
DataTreeDialog dataTreeDialog = new DataTreeDialog(getComponent(),
|
||||
"Choose a project folder", DataTreeDialog.CHOOSE_FOLDER);
|
||||
"Choose a project folder", CHOOSE_FOLDER);
|
||||
dataTreeDialog.setSelectedFolder(destinationFolder);
|
||||
dataTreeDialog.showComponent();
|
||||
DomainFolder folder = dataTreeDialog.getDomainFolder();
|
||||
|
|
|
@ -21,8 +21,7 @@ import javax.swing.*;
|
|||
|
||||
import docking.widgets.button.BrowseButton;
|
||||
import docking.widgets.label.GDLabel;
|
||||
import ghidra.framework.main.AppInfo;
|
||||
import ghidra.framework.main.DataTreeDialog;
|
||||
import ghidra.framework.main.*;
|
||||
import ghidra.framework.model.*;
|
||||
|
||||
class BatchProjectDestinationPanel extends JPanel {
|
||||
|
@ -96,7 +95,7 @@ class BatchProjectDestinationPanel extends JPanel {
|
|||
|
||||
private void browseFolders() {
|
||||
DataTreeDialog dataTreeDialog =
|
||||
new DataTreeDialog(parent, "Choose a project folder", DataTreeDialog.CHOOSE_FOLDER);
|
||||
new DataTreeDialog(parent, "Choose a project folder", DataTreeDialogType.CHOOSE_FOLDER);
|
||||
dataTreeDialog.addOkActionListener(e -> {
|
||||
dataTreeDialog.close();
|
||||
setFolder(dataTreeDialog.getDomainFolder());
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package ghidra.framework.main;
|
||||
|
||||
import static ghidra.framework.main.DataTreeDialogType.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.*;
|
||||
|
@ -110,7 +111,7 @@ public class DataTreeDialogTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
@Test
|
||||
public void testOKButtonDisabled_Type_SAVE() {
|
||||
// no initial selection--button disabled
|
||||
show(DataTreeDialog.SAVE);
|
||||
show(SAVE);
|
||||
assertOK(false);
|
||||
|
||||
// select a file--enabled; name field populated
|
||||
|
@ -141,7 +142,7 @@ public class DataTreeDialogTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
@Test
|
||||
public void testOKButtonDisabled_Type_CREATE() {
|
||||
// no initial selection--button disabled
|
||||
show(DataTreeDialog.CREATE);
|
||||
show(CREATE);
|
||||
assertOK(false);
|
||||
|
||||
// select a file--enabled; name field populated
|
||||
|
@ -172,7 +173,7 @@ public class DataTreeDialogTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
@Test
|
||||
public void testOKButtonAlwaysEnabled_Type_CHOOSE_FOLDER() {
|
||||
// no initial selection--button disabled
|
||||
show(DataTreeDialog.CHOOSE_FOLDER);
|
||||
show(CHOOSE_FOLDER);
|
||||
assertOK(true);
|
||||
|
||||
// select a file--enabled; name field populated
|
||||
|
@ -199,7 +200,7 @@ public class DataTreeDialogTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
@Test
|
||||
public void testOKButtonDisabled_Type_OPEN() {
|
||||
// no initial selection--button disabled
|
||||
show(DataTreeDialog.OPEN);
|
||||
show(OPEN);
|
||||
assertOK(false);
|
||||
|
||||
// select a file--enabled; name field populated
|
||||
|
@ -224,7 +225,7 @@ public class DataTreeDialogTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
@Test
|
||||
public void testOKButtonEnabledWithInitialSelection_Type_OPEN() {
|
||||
// initial selection--button enabled
|
||||
show(DataTreeDialog.OPEN, "x07");
|
||||
show(OPEN, "x07");
|
||||
assertOK(true);
|
||||
|
||||
// select a file--enabled; name field populated
|
||||
|
@ -250,7 +251,7 @@ public class DataTreeDialogTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
public void testSelectFiles() throws Exception {
|
||||
List<DomainFile> createdFiles = createBlankProgramsInProject(
|
||||
List.of("/dir1/dir2/file1", "/dir1/dir2a/dir3a/file2", "/file3"));
|
||||
show(DataTreeDialog.OPEN);
|
||||
show(OPEN);
|
||||
|
||||
Set<DomainFile> selectedProjectElements = new HashSet<>();
|
||||
ProjectDataTreePanel projectDataTreePanel = getProjectDataTreePanel();
|
||||
|
@ -280,7 +281,7 @@ public class DataTreeDialogTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
public void testSelectFolder() throws Exception {
|
||||
List<DomainFile> createdFiles = createBlankProgramsInProject(
|
||||
List.of("/dir1/dir2/file1", "/dir1/dir2a/dir3a/file2", "/file3"));
|
||||
show(DataTreeDialog.OPEN);
|
||||
show(OPEN);
|
||||
|
||||
Set<DomainFolder> selectedProjectElements = new HashSet<>();
|
||||
ProjectDataTreePanel projectDataTreePanel = getProjectDataTreePanel();
|
||||
|
@ -398,7 +399,7 @@ public class DataTreeDialogTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
waitForTree(gTree);
|
||||
}
|
||||
|
||||
private void show(final int type) {
|
||||
private void show(DataTreeDialogType type) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
dialog = new DataTreeDialog(frontEndTool.getToolFrame(), "Test Data Tree Dialog", type);
|
||||
|
||||
|
@ -408,7 +409,7 @@ public class DataTreeDialogTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
assertNotNull(dialog);
|
||||
}
|
||||
|
||||
private void show(final int type, final String name) {
|
||||
private void show(DataTreeDialogType type, final String name) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
dialog = new DataTreeDialog(frontEndTool.getToolFrame(), "Test Data Tree Dialog", type);
|
||||
|
||||
|
@ -424,7 +425,7 @@ public class DataTreeDialogTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
private void showFiltered(final String startsWith) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
dialog = new DataTreeDialog(frontEndTool.getToolFrame(), "Test Data Tree Dialog",
|
||||
DataTreeDialog.OPEN, f -> f.getName().startsWith(startsWith));
|
||||
OPEN, f -> f.getName().startsWith(startsWith));
|
||||
dialog.showComponent();
|
||||
});
|
||||
waitForSwing();
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package ghidra.feature.fid.plugin;
|
||||
|
||||
import static ghidra.framework.main.DataTreeDialogType.*;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.io.File;
|
||||
|
@ -225,7 +227,7 @@ public class PopulateFidDialog extends DialogComponentProvider {
|
|||
JButton browseButton = new BrowseButton();
|
||||
browseButton.addActionListener(e -> {
|
||||
final DataTreeDialog dialog = new DataTreeDialog(tool.getToolFrame(),
|
||||
"Choose Root Folder", DataTreeDialog.CHOOSE_FOLDER);
|
||||
"Choose Root Folder", CHOOSE_FOLDER);
|
||||
tool.showDialog(dialog);
|
||||
DomainFolder domainFolder = dialog.getDomainFolder();
|
||||
if (domainFolder != null) {
|
||||
|
|
|
@ -150,6 +150,8 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
|||
DiffApplySettingsOptionManager applySettingsMgr;
|
||||
private boolean isHighlightCursorLine;
|
||||
private Program activeProgram;
|
||||
|
||||
// this is used for test injection only. In actual use, the dialog is not reused
|
||||
private OpenVersionedFileDialog<Program> openVersionedFileDialog;
|
||||
|
||||
/**
|
||||
|
@ -1141,10 +1143,9 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
|||
return;
|
||||
}
|
||||
|
||||
final OpenVersionedFileDialog<Program> dialog = getOpenVersionedFileDialog();
|
||||
|
||||
List<Program> openProgramList = getOpenProgramList();
|
||||
dialog.setOpenObjectChoices(openProgramList.isEmpty() ? null : openProgramList);
|
||||
|
||||
OpenVersionedFileDialog<Program> dialog = getOpenVersionedFileDialog(openProgramList);
|
||||
|
||||
dialog.addOkActionListener(e -> {
|
||||
tool.clearStatusInfo();
|
||||
|
@ -1186,14 +1187,17 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
|||
return (rc != OptionDialog.OPTION_ONE);
|
||||
}
|
||||
|
||||
private OpenVersionedFileDialog<Program> getOpenVersionedFileDialog() {
|
||||
private OpenVersionedFileDialog<Program> getOpenVersionedFileDialog(
|
||||
List<Program> openPrograms) {
|
||||
|
||||
// This will always be null except during testing.
|
||||
if (openVersionedFileDialog != null) {
|
||||
return openVersionedFileDialog;
|
||||
}
|
||||
|
||||
OpenVersionedFileDialog<Program> dialog =
|
||||
new OpenVersionedFileDialog<>(tool, "Select Other Program", Program.class);
|
||||
new OpenVersionedFileDialog<>(tool, "Select Other Program", Program.class,
|
||||
openPrograms);
|
||||
dialog.setTreeSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
|
||||
dialog.setHelpLocation(new HelpLocation("Diff", "Open_Close_Program_View"));
|
||||
return dialog;
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package ghidra.feature.vt.gui.actions;
|
||||
|
||||
import static ghidra.framework.main.DataTreeDialogType.*;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.action.DockingAction;
|
||||
import docking.action.MenuData;
|
||||
|
@ -45,8 +47,8 @@ public class OpenVersionTrackingSessionAction extends DockingAction {
|
|||
public void actionPerformed(ActionContext context) {
|
||||
PluginTool tool = controller.getTool();
|
||||
DataTreeDialog dialog =
|
||||
new DataTreeDialog(tool.getToolFrame(), "Open Version Tracking Session",
|
||||
DataTreeDialog.OPEN, new VTDomainFileFilter());
|
||||
new DataTreeDialog(tool.getToolFrame(), "Open Version Tracking Session", OPEN,
|
||||
new VTDomainFileFilter());
|
||||
|
||||
tool.showDialog(dialog);
|
||||
if (!dialog.wasCancelled()) {
|
||||
|
@ -56,6 +58,7 @@ public class OpenVersionTrackingSessionAction extends DockingAction {
|
|||
}
|
||||
|
||||
class VTDomainFileFilter implements DomainFileFilter {
|
||||
@Override
|
||||
public boolean accept(DomainFile f) {
|
||||
Class<?> c = f.getDomainObjectClass();
|
||||
return VTSession.class.isAssignableFrom(c);
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package ghidra.feature.vt.gui.wizard;
|
||||
|
||||
import static ghidra.framework.main.DataTreeDialogType.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
|
||||
|
@ -236,7 +238,7 @@ public class NewSessionPanel extends AbstractMageJPanel<VTWizardStateKey> {
|
|||
*/
|
||||
private void browseDataTreeFolders() {
|
||||
final DataTreeDialog dataTreeDialog =
|
||||
new DataTreeDialog(this, "Choose a project folder", DataTreeDialog.CHOOSE_FOLDER);
|
||||
new DataTreeDialog(this, "Choose a project folder", CHOOSE_FOLDER);
|
||||
|
||||
dataTreeDialog.addOkActionListener(e -> {
|
||||
dataTreeDialog.close();
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package ghidra.feature.vt.gui.wizard;
|
||||
|
||||
import static ghidra.framework.main.DataTreeDialogType.*;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
@ -55,8 +57,8 @@ public class VTWizardUtils {
|
|||
static DomainFile chooseDomainFile(Component parent, String domainIdentifier,
|
||||
DomainFileFilter filter, DomainFile fileToSelect) {
|
||||
final DataTreeDialog dataTreeDialog = filter == null
|
||||
? new DataTreeDialog(parent, "Choose " + domainIdentifier, DataTreeDialog.OPEN)
|
||||
: new DataTreeDialog(parent, "Choose " + domainIdentifier, DataTreeDialog.OPEN,
|
||||
? new DataTreeDialog(parent, "Choose " + domainIdentifier, OPEN)
|
||||
: new DataTreeDialog(parent, "Choose " + domainIdentifier, OPEN,
|
||||
filter);
|
||||
final DomainFileBox box = new DomainFileBox();
|
||||
dataTreeDialog.addOkActionListener(new ActionListener() {
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package help.screenshot;
|
||||
|
||||
import static ghidra.framework.main.DataTreeDialogType.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
|
@ -61,7 +63,7 @@ public class ReferencesPluginScreenShots extends GhidraScreenShotGenerator {
|
|||
|
||||
runSwing(() -> {
|
||||
DataTreeDialog dialog = new DataTreeDialog(tool.getToolFrame(),
|
||||
"Choose External Program (" + "Kernel32.dll" + ")", DataTreeDialog.OPEN);
|
||||
"Choose External Program (" + "Kernel32.dll" + ")", OPEN);
|
||||
tool.showDialog(dialog);
|
||||
}, false);
|
||||
captureDialog();
|
||||
|
|
Loading…
Reference in New Issue
Block a user