From 837928504438dbfc158566119a4744966d251613 Mon Sep 17 00:00:00 2001 From: dragonmacher <48328597+dragonmacher@users.noreply.github.com> Date: Mon, 12 Dec 2022 18:54:57 -0500 Subject: [PATCH] GP-2795 - Refactor of ButtonPanelFactory --- .../app/merge/MergeManagerProvider.java | 21 +- .../plugin/core/exporter/ExporterDialog.java | 8 +- .../core/string/SearchStringDialog.java | 20 +- .../ghidra/app/util/OptionsEditorPanel.java | 8 +- .../datatype/DataTypeSelectionEditor.java | 4 +- .../plugin/importer/ImporterDialog.java | 9 +- .../batch/BatchProjectDestinationPanel.java | 4 +- .../datatype/DataTypeSelectionDialogTest.java | 15 +- .../feature/fid/plugin/PopulateFidDialog.java | 15 +- .../graph/export/GraphExporterDialog.java | 7 +- .../pdb/symbolserver/ui/FilePromptDialog.java | 16 +- .../pdb/symbolserver/ui/LoadPdbDialog.java | 117 ++++---- .../symbolserver/ui/SymbolServerPanel.java | 54 ++-- .../vt/gui/wizard/NewSessionPanel.java | 11 +- .../options/editor/ButtonPanelFactory.java | 267 ------------------ .../options/editor/FileChooserEditor.java | 3 +- .../options/editor/IconPropertyEditor.java | 3 +- .../docking/theme/gui/ExportThemeDialog.java | 4 +- .../docking/widgets/ListSelectionDialog.java | 8 +- .../docking/widgets/button/BrowseButton.java | 59 ++++ .../framework/main/EditPluginPathDialog.java | 44 ++- .../main/ImportGhidraToolsDialog.java | 34 +-- .../framework/main/ProjectAccessPanel.java | 64 +++-- .../ghidra/framework/main/SaveDataDialog.java | 37 +-- .../ghidra/framework/main/SelectPanel.java | 55 ++++ .../framework/main/SelectProjectPanel.java | 8 +- .../dialog/SaveToolConfigDialog.java | 8 +- .../data/DataTypeArchiveTransformerPanel.java | 10 +- .../DataTypeEditorsScreenShots.java | 6 +- 29 files changed, 364 insertions(+), 555 deletions(-) delete mode 100644 Ghidra/Framework/Docking/src/main/java/docking/options/editor/ButtonPanelFactory.java create mode 100644 Ghidra/Framework/Docking/src/main/java/docking/widgets/button/BrowseButton.java create mode 100644 Ghidra/Framework/Project/src/main/java/ghidra/framework/main/SelectPanel.java diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/merge/MergeManagerProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/app/merge/MergeManagerProvider.java index ef1f0e0736..0edd9768c7 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/merge/MergeManagerProvider.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/merge/MergeManagerProvider.java @@ -19,10 +19,10 @@ import java.awt.*; import java.awt.event.MouseEvent; import javax.swing.*; +import javax.swing.border.Border; import docking.ActionContext; import docking.WindowPosition; -import docking.options.editor.ButtonPanelFactory; import docking.util.image.ToolIconURL; import docking.widgets.OptionDialog; import docking.widgets.label.*; @@ -40,8 +40,8 @@ import ghidra.util.layout.VerticalLayout; /** * Component that displays merge components as needed. - * - * + * + * */ class MergeManagerProvider extends ComponentProviderAdapter { @@ -238,8 +238,19 @@ class MergeManagerProvider extends ComponentProviderAdapter { cancelButton = new JButton("Cancel"); cancelButton.addActionListener(e -> cancelCallback(false)); - JPanel panel = ButtonPanelFactory.createButtonPanel( - new JButton[] { applyButton, cancelButton }, ButtonPanelFactory.X_AXIS); + JPanel panel = new JPanel(); + JPanel subPanel = new JPanel(); + panel.add(subPanel); + + subPanel.setLayout(new GridLayout(1, 0, 10, 0)); + + int top = 8; + int side = 20; + Border inside = BorderFactory.createEmptyBorder(top, side, top, side); + subPanel.setBorder(inside); + + subPanel.add(applyButton); + subPanel.add(cancelButton); return panel; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/exporter/ExporterDialog.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/exporter/ExporterDialog.java index a1f4b80c11..5bfb13dfbb 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/exporter/ExporterDialog.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/exporter/ExporterDialog.java @@ -26,8 +26,8 @@ import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import docking.DialogComponentProvider; -import docking.options.editor.ButtonPanelFactory; import docking.widgets.OptionDialog; +import docking.widgets.button.BrowseButton; import docking.widgets.checkbox.GCheckBox; import docking.widgets.combobox.GhidraComboBox; import docking.widgets.filechooser.GhidraFileChooser; @@ -169,8 +169,8 @@ public class ExporterDialog extends DialogComponentProvider implements AddressFa } }; OptionsDialog optionsDialog = new OptionsDialog(options, validator, this); - optionsDialog.setHelpLocation( - new HelpLocation("ExporterPlugin", getAnchorForSelectedFormat())); + optionsDialog + .setHelpLocation(new HelpLocation("ExporterPlugin", getAnchorForSelectedFormat())); tool.showDialog(optionsDialog); if (!optionsDialog.wasCancelled()) { options = optionsDialog.getOptions(); @@ -230,7 +230,7 @@ public class ExporterDialog extends DialogComponentProvider implements AddressFa }); - fileChooserButton = ButtonPanelFactory.createButton(ButtonPanelFactory.BROWSE_TYPE); + fileChooserButton = new BrowseButton(); fileChooserButton.addActionListener(e -> chooseDestinationFile()); JPanel panel = new JPanel(new BorderLayout()); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/string/SearchStringDialog.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/string/SearchStringDialog.java index e15c7c2257..db9a6daef5 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/string/SearchStringDialog.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/string/SearchStringDialog.java @@ -25,7 +25,7 @@ import javax.swing.*; import javax.swing.border.TitledBorder; import docking.DialogComponentProvider; -import docking.options.editor.ButtonPanelFactory; +import docking.widgets.button.BrowseButton; import docking.widgets.button.GRadioButton; import docking.widgets.checkbox.GCheckBox; import docking.widgets.filechooser.GhidraFileChooser; @@ -194,9 +194,9 @@ public class SearchStringDialog extends DialogComponentProvider { JLabel alignLabel = new GLabel("Alignment: "); alignLabel.setName("alignment"); - alignLabel.setToolTipText( - "Searches for strings that start on the given alignment
" + - "value. The default alignment is processor dependent."); + alignLabel + .setToolTipText("Searches for strings that start on the given alignment
" + + "value. The default alignment is processor dependent."); panel.add(alignLabel); alignField = new IntegerTextField(5, 1L); @@ -210,7 +210,7 @@ public class SearchStringDialog extends DialogComponentProvider { /** * Creates the panel containing the Word Model options field. - * + * * @param panel the parent panel this is to be added to (uses Pair layout) */ private void createModelFieldPanel(JPanel panel) { @@ -230,7 +230,7 @@ public class SearchStringDialog extends DialogComponentProvider { modelFieldPanel.add(wordModelField); // Set up a file chooser that allows the user to select a new *.sng file. - JButton browseButton = ButtonPanelFactory.createButton(ButtonPanelFactory.BROWSE_TYPE); + JButton browseButton = new BrowseButton(); browseButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -273,10 +273,10 @@ public class SearchStringDialog extends DialogComponentProvider { memoryBlockGroup.add(loadedBlocksRB); memoryBlockGroup.add(allBlocksRB); - loadedBlocksRB.setToolTipText(HTMLUtilities.toHTML( - "Only searches memory blocks that are loaded in a running executable.\n " + - "Ghidra now includes memory blocks for other data such as section headers.\n" + - "This option exludes these other (non-loaded) blocks.")); + loadedBlocksRB.setToolTipText(HTMLUtilities + .toHTML("Only searches memory blocks that are loaded in a running executable.\n " + + "Ghidra now includes memory blocks for other data such as section headers.\n" + + "This option exludes these other (non-loaded) blocks.")); allBlocksRB.setToolTipText( "Searches all memory blocks including blocks that are not actually loaded in a running executable"); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/OptionsEditorPanel.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/OptionsEditorPanel.java index 9c77b048be..13cd570ff4 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/OptionsEditorPanel.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/OptionsEditorPanel.java @@ -28,7 +28,7 @@ import javax.swing.event.DocumentListener; import org.apache.commons.collections4.map.LazyMap; import docking.DockingWindowManager; -import docking.options.editor.ButtonPanelFactory; +import docking.widgets.button.BrowseButton; import docking.widgets.checkbox.GCheckBox; import docking.widgets.combobox.GComboBox; import docking.widgets.label.GLabel; @@ -244,10 +244,10 @@ public class OptionsEditorPanel extends JPanel { JPanel panel = new JPanel(new BorderLayout()); JTextField textField = new JTextField(); textField.setEditable(false); - JButton button = ButtonPanelFactory.createButton(ButtonPanelFactory.BROWSE_TYPE); + JButton button = new BrowseButton(); button.addActionListener(e -> { - DataTreeDialog dataTreeDialog = new DataTreeDialog(this, - "Choose a project folder", DataTreeDialog.CHOOSE_FOLDER); + DataTreeDialog dataTreeDialog = + new DataTreeDialog(this, "Choose a project folder", DataTreeDialog.CHOOSE_FOLDER); dataTreeDialog.setSelectedFolder(null); dataTreeDialog.showComponent(); DomainFolder folder = dataTreeDialog.getDomainFolder(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/datatype/DataTypeSelectionEditor.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/datatype/DataTypeSelectionEditor.java index 4b23b9172f..ecfcce364f 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/datatype/DataTypeSelectionEditor.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/datatype/DataTypeSelectionEditor.java @@ -21,8 +21,8 @@ import javax.swing.*; import javax.swing.event.*; import javax.swing.tree.TreePath; -import docking.options.editor.ButtonPanelFactory; import docking.widgets.DropDownSelectionTextField; +import docking.widgets.button.BrowseButton; import ghidra.app.plugin.core.datamgr.util.DataTypeChooserDialog; import ghidra.app.plugin.core.datamgr.util.DataTypeUtils; import ghidra.app.services.DataTypeManagerService; @@ -133,7 +133,7 @@ public class DataTypeSelectionEditor extends AbstractCellEditor { selectionField.setBorder(UIManager.getBorder("Table.focusCellHighlightBorder")); - browseButton = ButtonPanelFactory.createButton(ButtonPanelFactory.BROWSE_TYPE); + browseButton = new BrowseButton(); browseButton.setToolTipText("Browse the Data Manager"); browseButton.addActionListener(e -> showDataTypeBrowser()); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/plugin/importer/ImporterDialog.java b/Ghidra/Features/Base/src/main/java/ghidra/plugin/importer/ImporterDialog.java index 12b447bc45..7d667bffcd 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/plugin/importer/ImporterDialog.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/plugin/importer/ImporterDialog.java @@ -31,8 +31,8 @@ import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.StringUtils; import docking.DialogComponentProvider; -import docking.options.editor.ButtonPanelFactory; import docking.widgets.EmptyBorderButton; +import docking.widgets.button.BrowseButton; import docking.widgets.combobox.GhidraComboBox; import docking.widgets.dialogs.MultiLineMessageDialog; import docking.widgets.label.GLabel; @@ -212,7 +212,7 @@ public class ImporterDialog extends DialogComponentProvider { folderNameTextField = new JTextField(); folderNameTextField.setEditable(false); folderNameTextField.setFocusable(false); - folderButton = ButtonPanelFactory.createButton(ButtonPanelFactory.BROWSE_TYPE); + folderButton = new BrowseButton(); folderButton.addActionListener(e -> chooseProjectFolder()); JPanel panel = new JPanel(new BorderLayout()); @@ -226,7 +226,7 @@ public class ImporterDialog extends DialogComponentProvider { languageTextField.setEditable(false); languageTextField.setFocusable(false); - languageButton = ButtonPanelFactory.createButton(ButtonPanelFactory.BROWSE_TYPE); + languageButton = new BrowseButton(); languageButton.addActionListener(e -> { Object selectedItem = loaderComboBox.getSelectedItem(); if (selectedItem instanceof Loader) { @@ -277,8 +277,7 @@ public class ImporterDialog extends DialogComponentProvider { private Component buildLoaderInfoButton() { JPanel panel = new JPanel(new BorderLayout()); - EmptyBorderButton helpButton = - new EmptyBorderButton(new GIcon("icon.information")); + EmptyBorderButton helpButton = new EmptyBorderButton(new GIcon("icon.information")); helpButton.setToolTipText("Show list of supported format/loaders"); helpButton.addActionListener(e -> showSupportedImportFormats()); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/plugins/importer/batch/BatchProjectDestinationPanel.java b/Ghidra/Features/Base/src/main/java/ghidra/plugins/importer/batch/BatchProjectDestinationPanel.java index 47eaede348..4d4a4de1f6 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/plugins/importer/batch/BatchProjectDestinationPanel.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/plugins/importer/batch/BatchProjectDestinationPanel.java @@ -19,7 +19,7 @@ import java.awt.*; import javax.swing.*; -import docking.options.editor.ButtonPanelFactory; +import docking.widgets.button.BrowseButton; import docking.widgets.label.GDLabel; import ghidra.framework.main.AppInfo; import ghidra.framework.main.DataTreeDialog; @@ -53,7 +53,7 @@ class BatchProjectDestinationPanel extends JPanel { JLabel folderLabel = new GDLabel("Destination Folder"); folderLabel.setLabelFor(folderNameTextField); - JButton browseButton = ButtonPanelFactory.createButton(ButtonPanelFactory.BROWSE_TYPE); + JButton browseButton = new BrowseButton(); browseButton.addActionListener(e -> browseFolders()); //ImporterUtils.changeFontToBold(browseButton); diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/util/datatype/DataTypeSelectionDialogTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/util/datatype/DataTypeSelectionDialogTest.java index 245f00a1ab..7cc15fbcd5 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/util/datatype/DataTypeSelectionDialogTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/util/datatype/DataTypeSelectionDialogTest.java @@ -37,9 +37,9 @@ import org.junit.*; import docking.DialogComponentProvider; import docking.DockingDialog; -import docking.options.editor.ButtonPanelFactory; import docking.widgets.DropDownSelectionTextField; import docking.widgets.DropDownTextFieldDataModel; +import docking.widgets.button.BrowseButton; import docking.widgets.tree.GTree; import docking.widgets.tree.GTreeNode; import generic.test.AbstractGTest; @@ -194,8 +194,9 @@ public class DataTypeSelectionDialogTest extends AbstractGhidraHeadedIntegration assertTrue("The dialog was not made visible when tool.showDialog() was called.", dialog.isVisible()); - final JButton browseButton = findButtonByIcon(dialog, ButtonPanelFactory.BROWSE_ICON); - pressButton(browseButton); + AbstractButton browseButton = + findAbstractButtonByName(dialog.getComponent(), BrowseButton.NAME); + pressButton(browseButton, false); Window window = waitForWindow("Data Type Chooser"); @@ -241,7 +242,7 @@ public class DataTypeSelectionDialogTest extends AbstractGhidraHeadedIntegration doubleNode.getDataType().getName(), dataType.getName()); // show the dialog again and cancel and make sure that the user selection is null - pressButton(browseButton); + pressButton(browseButton, false); window = waitForWindow("Data Type Chooser"); assertTrue("The data type selection tree was not shown after pressing the browse button", (window instanceof DockingDialog)); @@ -263,11 +264,7 @@ public class DataTypeSelectionDialogTest extends AbstractGhidraHeadedIntegration } private void waitForDialogToClose(DockingDialog dockingDialog) { - int count = 0; - while (dockingDialog.isShowing() && count < 500) { - sleep(50); - } - assertTrue("Dialog did not close!", !dockingDialog.isShowing()); + waitForCondition(() -> !dialog.isShowing(), "Dialog did not close!"); waitForSwing(); } diff --git a/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/plugin/PopulateFidDialog.java b/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/plugin/PopulateFidDialog.java index 5fdb212694..ae76a9bff0 100644 --- a/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/plugin/PopulateFidDialog.java +++ b/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/plugin/PopulateFidDialog.java @@ -25,9 +25,10 @@ import java.util.List; import javax.swing.*; import docking.DialogComponentProvider; -import docking.options.editor.ButtonPanelFactory; +import docking.widgets.button.BrowseButton; import docking.widgets.combobox.GComboBox; import docking.widgets.filechooser.GhidraFileChooser; +import docking.widgets.filechooser.GhidraFileChooserMode; import docking.widgets.label.GDLabel; import docking.widgets.label.GLabel; import ghidra.app.script.SelectLanguageDialog; @@ -148,11 +149,11 @@ public class PopulateFidDialog extends DialogComponentProvider { JPanel panel = new JPanel(new BorderLayout()); symbolsFileTextField = new JTextField(); panel.add(symbolsFileTextField, BorderLayout.CENTER); - JButton browseButton = createBrowseButton(); + JButton browseButton = new BrowseButton(); browseButton.addActionListener(e -> { GhidraFileChooser chooser = new GhidraFileChooser(tool.getToolFrame()); chooser.setTitle("Choose Common Symbols File"); - chooser.setFileSelectionMode(GhidraFileChooser.FILES_ONLY); + chooser.setFileSelectionMode(GhidraFileChooserMode.FILES_ONLY); // chooser.setFileFilter(null); File selectedFile = chooser.getSelectedFile(); if (selectedFile != null) { @@ -168,7 +169,7 @@ public class PopulateFidDialog extends DialogComponentProvider { JPanel panel = new JPanel(new BorderLayout()); languageIdField = new JTextField(); panel.add(languageIdField, BorderLayout.CENTER); - JButton browseButton = createBrowseButton(); + JButton browseButton = new BrowseButton(); browseButton.addActionListener(e -> { SelectLanguageDialog selectLanguageDialog = new SelectLanguageDialog("Select Language", "Ok"); @@ -220,7 +221,7 @@ public class PopulateFidDialog extends DialogComponentProvider { domainFolderField = new JTextField(); domainFolderField.setEditable(false); panel.add(domainFolderField, BorderLayout.CENTER); - JButton browseButton = createBrowseButton(); + JButton browseButton = new BrowseButton(); browseButton.addActionListener(e -> { final DataTreeDialog dialog = new DataTreeDialog(tool.getToolFrame(), "Choose Root Folder", DataTreeDialog.CHOOSE_FOLDER); @@ -279,10 +280,6 @@ public class PopulateFidDialog extends DialogComponentProvider { return true; } - private JButton createBrowseButton() { - return ButtonPanelFactory.createButton(ButtonPanelFactory.BROWSE_TYPE); - } - private static class LibraryChoice { private final String name; private final LibraryRecord libraryRecord; diff --git a/Ghidra/Features/GraphServices/src/main/java/ghidra/graph/export/GraphExporterDialog.java b/Ghidra/Features/GraphServices/src/main/java/ghidra/graph/export/GraphExporterDialog.java index 84d6284c22..6c17f706ae 100644 --- a/Ghidra/Features/GraphServices/src/main/java/ghidra/graph/export/GraphExporterDialog.java +++ b/Ghidra/Features/GraphServices/src/main/java/ghidra/graph/export/GraphExporterDialog.java @@ -26,8 +26,8 @@ import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import docking.DialogComponentProvider; -import docking.options.editor.ButtonPanelFactory; import docking.widgets.OptionDialog; +import docking.widgets.button.BrowseButton; import docking.widgets.combobox.GhidraComboBox; import docking.widgets.filechooser.GhidraFileChooser; import docking.widgets.filechooser.GhidraFileChooserMode; @@ -128,7 +128,7 @@ public class GraphExporterDialog extends DialogComponentProvider { }); - fileChooserButton = ButtonPanelFactory.createButton(ButtonPanelFactory.BROWSE_TYPE); + fileChooserButton = new BrowseButton(); fileChooserButton.addActionListener(e -> chooseDestinationFile()); JPanel panel = new JPanel(new BorderLayout()); @@ -262,8 +262,7 @@ public class GraphExporterDialog extends DialogComponentProvider { private boolean doExport() { AtomicBoolean success = new AtomicBoolean(); - TaskLauncher.launchModal("Exporting Graph", - monitor -> success.set(tryExport(monitor))); + TaskLauncher.launchModal("Exporting Graph", monitor -> success.set(tryExport(monitor))); return success.get(); } diff --git a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/FilePromptDialog.java b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/FilePromptDialog.java index 2b6fe7cf6a..14f489602f 100644 --- a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/FilePromptDialog.java +++ b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/FilePromptDialog.java @@ -25,8 +25,8 @@ import javax.swing.event.DocumentListener; import docking.DialogComponentProvider; import docking.DockingWindowManager; -import docking.options.editor.ButtonPanelFactory; import docking.widgets.OptionDialog; +import docking.widgets.button.BrowseButton; import docking.widgets.filechooser.GhidraFileChooser; import docking.widgets.filechooser.GhidraFileChooserMode; import docking.widgets.label.GHtmlLabel; @@ -36,7 +36,7 @@ import ghidra.util.layout.PairLayout; /** * Non-public, package-only dialog that prompts the user to enter a path * in a text field (similar to an {@link OptionDialog}) and allows them to click - * a "..." browse button to pick the file and/or directory via a + * a "..." browse button to pick the file and/or directory via a * {@link GhidraFileChooser} dialog. */ class FilePromptDialog extends DialogComponentProvider { @@ -44,8 +44,8 @@ class FilePromptDialog extends DialogComponentProvider { /** * Prompts the user to enter the path to a directory, * or to pick it using a browser dialog. - * - * @param title the dialog title + * + * @param title the dialog title * @param prompt HTML enabled prompt * @param initialValue initial value to pre-populate the input field with * @return the {@link File} the user entered / picked, or null if canceled @@ -59,14 +59,14 @@ class FilePromptDialog extends DialogComponentProvider { * Prompts the user to entry the path to a file and/or directory, * or to pick it using a browser dialog. *

- * - * @param title the dialog title + * + * @param title the dialog title * @param prompt HTML enabled prompt * @param chooseButtonText text of the choose button in the browser dialog * @param directory the initial directory of the browser dialog * @param initialFileValue the initial value to pre-populate the input field with * @param chooserMode {@link GhidraFileChooserMode} of the browser dialog - * @param fileFilters optional {@link GhidraFileFilter filters} + * @param fileFilters optional {@link GhidraFileFilter filters} * @return the {@link File} the user entered / picked, or null if canceled */ public static File chooseFile(String title, String prompt, String chooseButtonText, @@ -123,7 +123,7 @@ class FilePromptDialog extends DialogComponentProvider { updateButtonEnablement(); } }); - JButton browseButton = ButtonPanelFactory.createButton(ButtonPanelFactory.BROWSE_TYPE); + JButton browseButton = new BrowseButton(); browseButton.addActionListener(e -> browse()); JPanel textFieldWithButtonPanel = new JPanel(new BorderLayout()); diff --git a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/LoadPdbDialog.java b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/LoadPdbDialog.java index 2052a80b00..5bb7ca1fc8 100644 --- a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/LoadPdbDialog.java +++ b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/LoadPdbDialog.java @@ -31,8 +31,8 @@ import javax.swing.event.DocumentListener; import docking.DialogComponentProvider; import docking.DockingWindowManager; import docking.event.mouse.GMouseListenerAdapter; -import docking.options.editor.ButtonPanelFactory; import docking.widgets.OptionDialog; +import docking.widgets.button.BrowseButton; import docking.widgets.checkbox.GCheckBox; import docking.widgets.combobox.GComboBox; import docking.widgets.filechooser.GhidraFileChooser; @@ -83,7 +83,7 @@ public class LoadPdbDialog extends DialogComponentProvider { * Shows a modal dialog to the user, allowing them to pick or search for a Pdb * file.

* The selected file and parser options are returned in a LoadPdbResults instance. - * + * * @param program the Ghidra {@link Program} that has Pdb info * @return LoadPdbResults instance with the selected file and options, or null if canceled */ @@ -147,7 +147,7 @@ public class LoadPdbDialog extends DialogComponentProvider { /** * Creates a new instance of the LoadPdbDialog class. - * + * * @param program the ghidra {@link Program} that is loading the Pdb */ public LoadPdbDialog(Program program) { @@ -164,8 +164,7 @@ public class LoadPdbDialog extends DialogComponentProvider { private void updateSymbolServerServiceInstanceFromPreferences() { symbolServerInstanceCreatorContext = SymbolServerInstanceCreatorRegistry.getInstance().getContext(program); - symbolServerService = - PdbPlugin.getSymbolServerService(symbolServerInstanceCreatorContext); + symbolServerService = PdbPlugin.getSymbolServerService(symbolServerInstanceCreatorContext); } @Override @@ -185,7 +184,7 @@ public class LoadPdbDialog extends DialogComponentProvider { /** * For screenshot use only - * + * * @param options set of {@link FindOption} enum */ public void setSearchOptions(Set options) { @@ -201,7 +200,7 @@ public class LoadPdbDialog extends DialogComponentProvider { * Sets the contents of the search results table. *

* Public only for screenshot usage, treat as private otherwise. - * + * * @param results list of {@link SymbolFileLocation}s to add to results * @param findOptions the options used to search */ @@ -214,7 +213,7 @@ public class LoadPdbDialog extends DialogComponentProvider { * Selects a row in the results table. *

* Public only for screenshot usage. Treat as private. - * + * * @param symbolFileLocation {@link SymbolFileLocation} to select in results table */ public void selectRowByLocation(SymbolFileLocation symbolFileLocation) { @@ -242,21 +241,17 @@ public class LoadPdbDialog extends DialogComponentProvider { } private String getSymbolFileToolText(SymbolFileLocation symbolFileLocation) { - return symbolFileLocation != null - ? String.format( - "" + - "" + - "" + - "" + - "" + - "
PDB Name:%s
Path:%s
GUID/ID:%s
Age:%x
Is Exact Match:%b" + - "
", - HTMLUtilities.escapeHTML(symbolFileLocation.getFileInfo().getName()), - HTMLUtilities.escapeHTML(symbolFileLocation.getLocationStr()), - symbolFileLocation.getFileInfo().getUniqueName(), - symbolFileLocation.getFileInfo().getIdentifiers().getAge(), - symbolFileLocation.getFileInfo().isExactMatch(programSymbolFileInfo)) - : null; + return symbolFileLocation != null ? String.format( + "" + "" + + "" + + "" + + "" + + "
PDB Name:%s
Path:%s
GUID/ID:%s
Age:%x
Is Exact Match:%b" + "
", + HTMLUtilities.escapeHTML(symbolFileLocation.getFileInfo().getName()), + HTMLUtilities.escapeHTML(symbolFileLocation.getLocationStr()), + symbolFileLocation.getFileInfo().getUniqueName(), + symbolFileLocation.getFileInfo().getIdentifiers().getAge(), + symbolFileLocation.getFileInfo().isExactMatch(programSymbolFileInfo)) : null; } private void updateButtonEnablement() { @@ -334,7 +329,7 @@ public class LoadPdbDialog extends DialogComponentProvider { updateStatusText(); updateButtonEnablement(); - // later dialogShow() will be called + // later dialogShow() will be called } private void buildSymbolFilePanel() { @@ -395,18 +390,15 @@ public class LoadPdbDialog extends DialogComponentProvider { } }); DockingWindowManager.getHelpService() - .registerHelp(overridePdbPathCheckBox, - new HelpLocation(PdbPlugin.PDB_PLUGIN_HELP_TOPIC, - SymbolFilePanel.SEARCH_OPTIONS_HELP_ANCHOR)); + .registerHelp(overridePdbPathCheckBox, new HelpLocation( + PdbPlugin.PDB_PLUGIN_HELP_TOPIC, SymbolFilePanel.SEARCH_OPTIONS_HELP_ANCHOR)); pdbUniqueIdTextField = new BetterNonEditableTextField(36, "Missing", Colors.ERROR); pdbUniqueIdTextField.setEditable(false); pdbUniqueIdTextField.setText(programSymbolFileInfo.getUniqifierString()); - pdbUniqueIdTextField.setToolTipText( - "PDB GUID - 32 hexadecimal characters:
" + - "  '012345678-0123-0123-0123-0123456789ABC' (with or without dashes) or
" + - "PDB Signature ID - 8 hexadecimal characters:
" + - "  '11223344'"); + pdbUniqueIdTextField.setToolTipText("PDB GUID - 32 hexadecimal characters:
" + + "  '012345678-0123-0123-0123-0123456789ABC' (with or without dashes) or
" + + "PDB Signature ID - 8 hexadecimal characters:
" + "  '11223344'"); pdbUniqueIdTextField.getDocument().addDocumentListener(docListener); overridePdbUniqueIdCheckBox = new GCheckBox(); @@ -422,9 +414,8 @@ public class LoadPdbDialog extends DialogComponentProvider { } }); DockingWindowManager.getHelpService() - .registerHelp(overridePdbUniqueIdCheckBox, - new HelpLocation(PdbPlugin.PDB_PLUGIN_HELP_TOPIC, - SymbolFilePanel.SEARCH_OPTIONS_HELP_ANCHOR)); + .registerHelp(overridePdbUniqueIdCheckBox, new HelpLocation( + PdbPlugin.PDB_PLUGIN_HELP_TOPIC, SymbolFilePanel.SEARCH_OPTIONS_HELP_ANCHOR)); pdbAgeTextField = new BetterNonEditableHexTextField(8); pdbAgeTextField.setAllowNegative(false); @@ -446,9 +437,8 @@ public class LoadPdbDialog extends DialogComponentProvider { } }); DockingWindowManager.getHelpService() - .registerHelp(overridePdbAgeCheckBox, - new HelpLocation(PdbPlugin.PDB_PLUGIN_HELP_TOPIC, - SymbolFilePanel.SEARCH_OPTIONS_HELP_ANCHOR)); + .registerHelp(overridePdbAgeCheckBox, new HelpLocation( + PdbPlugin.PDB_PLUGIN_HELP_TOPIC, SymbolFilePanel.SEARCH_OPTIONS_HELP_ANCHOR)); programPdbPanel = new JPanel(new PairLayout(5, 5)); programPdbPanel.setBorder(BorderFactory.createTitledBorder("Program PDB Information")); @@ -474,7 +464,7 @@ public class LoadPdbDialog extends DialogComponentProvider { pdbLocationTextField = new HintTextField("Browse [...] for PDB file or use 'Advanced'"); pdbLocationTextField.setEditable(false); - choosePdbLocationButton = ButtonPanelFactory.createButton(ButtonPanelFactory.BROWSE_TYPE); + choosePdbLocationButton = new BrowseButton(); choosePdbLocationButton.addActionListener(e -> choosePdbFile()); exactMatchIconLabel = new GIconLabel(Icons.EMPTY_ICON); @@ -523,9 +513,8 @@ public class LoadPdbDialog extends DialogComponentProvider { universalParserButton .setToolTipText("Platform-independent PDB analyzer (No PDB.XML support)."); msdiaParserButton = new JRadioButton("MSDIA"); - msdiaParserButton.setToolTipText( - "Legacy PDB Analyzer.
" + - "Requires MS DIA-SDK for raw PDB processing (Windows only), or preprocessed PDB.XML file."); + msdiaParserButton.setToolTipText("Legacy PDB Analyzer.
" + + "Requires MS DIA-SDK for raw PDB processing (Windows only), or preprocessed PDB.XML file."); universalParserButton.setSelected(true); universalParserButton.addActionListener(l); msdiaParserButton.addActionListener(l); @@ -546,8 +535,7 @@ public class LoadPdbDialog extends DialogComponentProvider { parserOptionsPanel.setBorder(BorderFactory.createTitledBorder("PDB Parser")); DockingWindowManager.getHelpService() .registerHelp(parserOptionsPanel, - new HelpLocation(PdbPlugin.PDB_PLUGIN_HELP_TOPIC, - "PDB Parser Panel")); + new HelpLocation(PdbPlugin.PDB_PLUGIN_HELP_TOPIC, "PDB Parser Panel")); parserOptionsPanel.add(new GLabel("Parser:")); parserOptionsPanel.add(radioButtons); @@ -564,16 +552,16 @@ public class LoadPdbDialog extends DialogComponentProvider { loadPdbButton.setName("Load"); loadPdbButton.addActionListener(e -> { - if (selectedSymbolFile == null || - (!selectedSymbolFile.isExactMatch(programSymbolFileInfo) && - OptionDialog.showYesNoDialog(loadPdbButton, "Mismatched Pdb File Warning", - "The selected file is not an exact match for the current program.
" + - "Note: Invalid disassembly may be produced!
" + - "Continue anyway?") != OptionDialog.YES_OPTION)) { + if (selectedSymbolFile == null || (!selectedSymbolFile + .isExactMatch(programSymbolFileInfo) && + OptionDialog.showYesNoDialog(loadPdbButton, "Mismatched Pdb File Warning", + "The selected file is not an exact match for the current program.
" + + "Note: Invalid disassembly may be produced!
" + + "Continue anyway?") != OptionDialog.YES_OPTION)) { return; } - executeMonitoredRunnable("Prepare Selected Symbol File", - true, true, 0, this::prepareSelectedSymbolFileAndClose); + executeMonitoredRunnable("Prepare Selected Symbol File", true, true, 0, + this::prepareSelectedSymbolFileAndClose); }); addButton(loadPdbButton); @@ -701,9 +689,8 @@ public class LoadPdbDialog extends DialogComponentProvider { if (pdbSymbolFileInfo == null) { pdbSymbolFileInfo = makeUnknownSymbolFileInstance(file.getName()); } - SymbolFileLocation symbolFileLocation = - SameDirSymbolStore.createManuallySelectedSymbolFileLocation(file, - pdbSymbolFileInfo); + SymbolFileLocation symbolFileLocation = SameDirSymbolStore + .createManuallySelectedSymbolFileLocation(file, pdbSymbolFileInfo); Swing.runLater(() -> { setSearchResults(List.of(symbolFileLocation), null); setSelectedPdbFile(symbolFileLocation); @@ -719,9 +706,9 @@ public class LoadPdbDialog extends DialogComponentProvider { } private void setPdbLocationValue(SymbolFileLocation symbolFileLocation, File file) { - boolean isExactMatch = symbolFileLocation != null - ? symbolFileLocation.isExactMatch(programSymbolFileInfo) - : false; + boolean isExactMatch = + symbolFileLocation != null ? symbolFileLocation.isExactMatch(programSymbolFileInfo) + : false; pdbLocationTextField.setText(file != null ? file.getPath() : ""); pdbLocationTextField.setToolTipText(getSymbolFileToolText(symbolFileLocation)); exactMatchIconLabel @@ -757,7 +744,7 @@ public class LoadPdbDialog extends DialogComponentProvider { * Use this status text scheme instead of {@link #setStatusText(String)} if * there are multiple locations that need to provide a status message at the * bottom of the dialog. - * + * * @param supplier StatusText supplier */ private void addStatusTextSupplier(Supplier supplier) { @@ -769,7 +756,7 @@ public class LoadPdbDialog extends DialogComponentProvider { * Polls all {@link #addStatusTextSupplier(Supplier) registered} StatusText suppliers and * sets the status message at the bottom of the dialog to the resulting message. *

- * Not compatible with {@link #setStatusText(String)}. Either use it, or this. + * Not compatible with {@link #setStatusText(String)}. Either use it, or this. */ private void updateStatusText() { StringBuilder sb = new StringBuilder(); @@ -815,7 +802,7 @@ public class LoadPdbDialog extends DialogComponentProvider { * Execute a non-modal task that has progress and can be cancelled. *

* See {@link #executeProgressTask(Task, int)}. - * + * * @param taskTitle String title of task * @param canCancel boolean flag, if true task can be canceled by the user * @param hasProgress boolean flag, if true the task has a progress meter @@ -823,8 +810,8 @@ public class LoadPdbDialog extends DialogComponentProvider { * progress * @param runnable {@link MonitoredRunnable} to run */ - private void executeMonitoredRunnable(String taskTitle, boolean canCancel, - boolean hasProgress, int delay, MonitoredRunnable runnable) { + private void executeMonitoredRunnable(String taskTitle, boolean canCancel, boolean hasProgress, + int delay, MonitoredRunnable runnable) { Task task = new Task(taskTitle, canCancel, hasProgress, false) { @Override public void run(TaskMonitor monitor) throws CancelledException { @@ -889,7 +876,7 @@ public class LoadPdbDialog extends DialogComponentProvider { Container parent = getParent(); if (parent != null && !isEditable()) { Color bg = parent.getBackground(); - // mint a new Color object to avoid it being ignored because the parent handed us a + // mint a new Color object to avoid it being ignored because the parent handed us a // DerivedColor instance return ColorUtils.getColor(bg.getRGB()); } @@ -930,7 +917,7 @@ public class LoadPdbDialog extends DialogComponentProvider { Container parent = getParent(); if (parent != null && !isEditable()) { Color bg = parent.getBackground(); - // mint a new Color object to avoid it being ignored because the parent handed us a + // mint a new Color object to avoid it being ignored because the parent handed us a // DerivedColor instance return ColorUtils.getColor(bg.getRGB()); } diff --git a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/SymbolServerPanel.java b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/SymbolServerPanel.java index 712a6340e1..e61348f448 100644 --- a/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/SymbolServerPanel.java +++ b/Ghidra/Features/PDB/src/main/java/pdb/symbolserver/ui/SymbolServerPanel.java @@ -28,8 +28,8 @@ import javax.swing.*; import javax.swing.table.TableColumn; import docking.DockingWindowManager; -import docking.options.editor.ButtonPanelFactory; import docking.widgets.OptionDialog; +import docking.widgets.button.BrowseButton; import docking.widgets.filechooser.GhidraFileChooser; import docking.widgets.filechooser.GhidraFileChooserMode; import docking.widgets.label.GHtmlLabel; @@ -47,12 +47,14 @@ import resources.Icons; import utilities.util.FileUtilities; /** - * Panel that allows the user to configure a SymbolServerService: a local + * Panel that allows the user to configure a SymbolServerService: a local * symbol storage directory and a list of search locations. */ class SymbolServerPanel extends JPanel { private static final String MS_SYMBOLSERVER_ENVVAR = "_NT_SYMBOL_PATH"; + private static final Dimension BUTTON_SIZE = new Dimension(32, 32); + private static List knownSymbolServers = WellKnownSymbolServerLocation.loadAll(); @@ -108,11 +110,12 @@ class SymbolServerPanel extends JPanel { JPanel buttonPanel = buildButtonPanel(); JScrollPane tableScrollPane = buildTable(); defaultConfigNotice = new JPanel(); - defaultConfigNotice.add(new GHtmlLabel( - "


" + "Missing / invalid configuration.

" + - "Using default search location:
" + "Program's Import Location
", - SwingConstants.CENTER)); + defaultConfigNotice + .add(new GHtmlLabel( + "

" + + "Missing / invalid configuration.

" + + "Using default search location:
" + "Program's Import Location
", + SwingConstants.CENTER)); defaultConfigNotice.setPreferredSize(tableScrollPane.getPreferredSize()); additionalSearchLocationsPanel = new JPanel(); @@ -139,7 +142,7 @@ class SymbolServerPanel extends JPanel { /** * Returns a new {@link SymbolServerService} instance representing the currently * displayed configuration, or null if the displayed configuration is not valid. - * + * * @return new {@link SymbolServerService} or null */ SymbolServerService getSymbolServerService() { @@ -155,7 +158,7 @@ class SymbolServerPanel extends JPanel { /** * The union of the changed status of the local storage path and the additional * search paths table model changed status. - * + * * @return boolean true if the config has changed */ boolean isConfigChanged() { @@ -198,43 +201,41 @@ class SymbolServerPanel extends JPanel { } private JPanel buildButtonPanel() { + refreshSearchLocationsStatusButton = - createImageButton(Icons.REFRESH_ICON, "Refresh Status", ButtonPanelFactory.ARROW_SIZE); + createImageButton(Icons.REFRESH_ICON, "Refresh Status"); refreshSearchLocationsStatusButton.addActionListener(e -> refreshSearchLocationStatus()); DockingWindowManager.getHelpService() .registerHelp(refreshSearchLocationsStatusButton, new HelpLocation( PdbPlugin.PDB_PLUGIN_HELP_TOPIC, "SymbolServerConfig Refresh Status")); - moveLocationUpButton = ButtonPanelFactory.createButton(ButtonPanelFactory.ARROW_UP_TYPE); + moveLocationUpButton = createImageButton(Icons.UP_ICON, "Up"); moveLocationUpButton.addActionListener(e -> moveLocation(-1)); moveLocationUpButton.setToolTipText("Move location up"); DockingWindowManager.getHelpService() .registerHelp(moveLocationUpButton, new HelpLocation( PdbPlugin.PDB_PLUGIN_HELP_TOPIC, "SymbolServerConfig MoveUpDown")); - moveLocationDownButton = - ButtonPanelFactory.createButton(ButtonPanelFactory.ARROW_DOWN_TYPE); + moveLocationDownButton = createImageButton(Icons.DOWN_ICON, "Down"); moveLocationDownButton.addActionListener(e -> moveLocation(1)); moveLocationDownButton.setToolTipText("Move location down"); DockingWindowManager.getHelpService() .registerHelp(moveLocationDownButton, new HelpLocation( PdbPlugin.PDB_PLUGIN_HELP_TOPIC, "SymbolServerConfig MoveUpDown")); - deleteLocationButton = - createImageButton(Icons.DELETE_ICON, "Delete", ButtonPanelFactory.ARROW_SIZE); + deleteLocationButton = createImageButton(Icons.DELETE_ICON, "Delete"); deleteLocationButton.addActionListener(e -> deleteLocation()); DockingWindowManager.getHelpService() .registerHelp(deleteLocationButton, new HelpLocation(PdbPlugin.PDB_PLUGIN_HELP_TOPIC, "SymbolServerConfig Delete")); - addLocationButton = createImageButton(Icons.ADD_ICON, "Add", ButtonPanelFactory.ARROW_SIZE); + addLocationButton = createImageButton(Icons.ADD_ICON, "Add"); addLocationButton.addActionListener(e -> addLocation()); DockingWindowManager.getHelpService() .registerHelp(addLocationButton, new HelpLocation(PdbPlugin.PDB_PLUGIN_HELP_TOPIC, "SymbolServerConfig Add")); - saveSearchLocationsButton = ButtonPanelFactory.createImageButton( - Icons.get("images/disk.png"), "Save Configuration", ButtonPanelFactory.ARROW_SIZE); + saveSearchLocationsButton = createImageButton(Icons.SAVE_ICON, "Save Configuration"); saveSearchLocationsButton.addActionListener(e -> saveConfig()); DockingWindowManager.getHelpService() .registerHelp(saveSearchLocationsButton, @@ -260,8 +261,7 @@ class SymbolServerPanel extends JPanel { symbolStorageLocationTextField .setToolTipText("User-specified directory where PDB files are stored. Required."); - chooseSymbolStorageLocationButton = - ButtonPanelFactory.createButton(ButtonPanelFactory.BROWSE_TYPE); + chooseSymbolStorageLocationButton = new BrowseButton(); chooseSymbolStorageLocationButton.addActionListener(e -> chooseSymbolStorageLocation()); symbolStorageLocationPanel = new JPanel(new PairLayout(5, 5)); @@ -494,8 +494,8 @@ class SymbolServerPanel extends JPanel { Msg.showError(this, this, "Bad path", "Invalid path: " + dir); return; } - LocalSymbolStore localSymbolStore = new LocalSymbolStore(dir); - tableModel.addSymbolServer(localSymbolStore); + LocalSymbolStore symbolStore = new LocalSymbolStore(dir); + tableModel.addSymbolServer(symbolStore); } private void deleteLocation() { @@ -552,7 +552,7 @@ class SymbolServerPanel extends JPanel { /** * Returns true if the given file path is a directory that contains no files. *

- * + * * @param directory path to a location on the file system * @return true if is a directory and it contains no files */ @@ -564,13 +564,11 @@ class SymbolServerPanel extends JPanel { return false; } - private static JButton createImageButton(Icon buttonIcon, String alternateText, - Dimension preferredSize) { + private static JButton createImageButton(Icon buttonIcon, String alternateText) { - JButton button = ButtonPanelFactory.createButton(""); - button.setIcon(buttonIcon); + JButton button = new JButton(buttonIcon); button.setToolTipText(alternateText); - button.setPreferredSize(preferredSize); + button.setPreferredSize(BUTTON_SIZE); return button; } diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/NewSessionPanel.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/NewSessionPanel.java index f93f0f527a..033a24ba16 100644 --- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/NewSessionPanel.java +++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/NewSessionPanel.java @@ -24,7 +24,7 @@ import javax.swing.event.DocumentListener; import org.apache.commons.lang3.StringUtils; -import docking.options.editor.ButtonPanelFactory; +import docking.widgets.button.BrowseButton; import docking.widgets.label.GDLabel; import docking.wizard.*; import generic.theme.*; @@ -58,7 +58,7 @@ public class NewSessionPanel extends AbstractMageJPanel { private DomainFolder folder; private PluginTool tool; - // All program info objects that the user may have opened while using the wizard. We keep + // All program info objects that the user may have opened while using the wizard. We keep // these around to avoid reopening them and any accompanying upgrading that may be required. // These will be released when the wizard is finished. private Map allProgramInfos = new HashMap<>(); @@ -77,8 +77,7 @@ public class NewSessionPanel extends AbstractMageJPanel { Gui.registerFont(folderNameField, GThemeDefaults.Ids.Fonts.MONOSPACED); folderNameField.setEditable(false); // force user to browse to choose - JButton browseFolderButton = - ButtonPanelFactory.createButton(ButtonPanelFactory.BROWSE_TYPE); + JButton browseFolderButton = new BrowseButton(); browseFolderButton.addActionListener(e -> browseDataTreeFolders()); JLabel newSessionLabel = new GDLabel("New Session Name: "); @@ -466,7 +465,7 @@ public class NewSessionPanel extends AbstractMageJPanel { } private JButton createSourceBrowseButton() { - JButton button = ButtonPanelFactory.createButton(ButtonPanelFactory.BROWSE_TYPE); + JButton button = new BrowseButton(); button.setName("SOURCE_BUTTON"); button.addActionListener(e -> { DomainFile programFile = VTWizardUtils.chooseDomainFile(NewSessionPanel.this, @@ -479,7 +478,7 @@ public class NewSessionPanel extends AbstractMageJPanel { } private JButton createDestinationBrowseButton() { - JButton button = ButtonPanelFactory.createButton(ButtonPanelFactory.BROWSE_TYPE); + JButton button = new BrowseButton(); button.setName("DESTINATION_BUTTON"); button.addActionListener(e -> { DomainFile programFile = VTWizardUtils.chooseDomainFile(NewSessionPanel.this, diff --git a/Ghidra/Framework/Docking/src/main/java/docking/options/editor/ButtonPanelFactory.java b/Ghidra/Framework/Docking/src/main/java/docking/options/editor/ButtonPanelFactory.java deleted file mode 100644 index 68147cd3fe..0000000000 --- a/Ghidra/Framework/Docking/src/main/java/docking/options/editor/ButtonPanelFactory.java +++ /dev/null @@ -1,267 +0,0 @@ -/* ### - * 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 docking.options.editor; - -import java.awt.*; - -import javax.swing.*; -import javax.swing.border.Border; - -import generic.theme.GThemeDefaults.Colors; -import resources.ResourceManager; - -/** - * Class with static methods to create a JButton with a raised bevel border, - * and to create a JPanel with buttons created by calling the - * createButton() method. - */ -public class ButtonPanelFactory { - - private ButtonPanelFactory() { - } - - /** - * layout the buttons on the panel created with createButtonPanel() - * horizontally along the X-axis - */ - public final static char X_AXIS = '0'; - /** - * layout the buttons on the panel created with createButtonPanel() - * vertically along the Y-axis - */ - public final static char Y_AXIS = '1'; - - /* - * types of buttons you can request from the factory that have - * been pre-configured using our convention - */ - /** - * Button that has an up arrow. - */ - public final static int ARROW_UP_TYPE = 0; - /** - * Button that has a down arrow. - */ - public final static int ARROW_DOWN_TYPE = 1; - /** - * Button that indicates a file chooser to browse. - */ - public final static int BROWSE_TYPE = 2; - /** - * Button for cancel. - */ - public final static int CANCEL_TYPE = 3; - /** - * Button that indicates an edit operation. - */ - public final static int EDIT_TYPE = 4; - /** - * Button for OK. - */ - public final static int OK_TYPE = 5; - /** - * Button that has a left arrow. - */ - public final static int ARROW_LEFT_TYPE = 6; - /** - * Button that has a right arrow. - */ - public final static int ARROW_RIGHT_TYPE = 7; - - /* - * values used to construct various button types, as defined - * above. These constants may be useful outside the factory when - * the factory can't be used (e.g., when using StringInputPanel). - */ - /** - * Dimension for the arrow button. - */ - public final static Dimension ARROW_SIZE = new Dimension(32, 32); - /** - * Dimension for the browse button. - */ - public final static Dimension BROWSE_SIZE = new Dimension(30, 25); - /** - * Text for the browse button. - */ - public final static Icon BROWSE_ICON = new Icon() { - @Override - public void paintIcon(Component c, Graphics g, int x, int y) { - g.setColor(Colors.FOREGROUND); - g.fillRect(x, y + 5, 2, 2); - g.fillRect(x + 4, y + 5, 2, 2); - g.fillRect(x + 8, y + 5, 2, 2); - } - - @Override - public int getIconWidth() { - return 10; - } - - @Override - public int getIconHeight() { - return 10; - } - }; - - /** - * internal values used when creating the panels and buttons - */ - private final static int TOP_MARGIN = 8; - private final static int BOTTOM_MARGIN = 8; - private final static int SIDE_MARGIN = 20; -// private final static int BUTTON_MARGIN = 4; - private final static int BUTTON_GAP = 10; - private final static String CANCEL_LABEL = "Cancel"; - private final static String OK_LABEL = "Ok"; - private final static String UNTITLED = "Untitled Button"; - private static final String BROWSE_TOOLTIP_TEXT = "Browse"; - - /** - * Create a button with specified type. - * @param buttonType the type of button to create. - */ - public static JButton createButton(int buttonType) { - switch (buttonType) { - case ARROW_DOWN_TYPE: - return createImageButton("images/down.png", "DOWN", ARROW_SIZE); - case ARROW_UP_TYPE: - return createImageButton("images/up.png", "UP", ARROW_SIZE); - case ARROW_LEFT_TYPE: - return createImageButton("images/left.png", "LEFT", ARROW_SIZE); - case ARROW_RIGHT_TYPE: - return createImageButton("images/right.png", "RIGHT", ARROW_SIZE); - case BROWSE_TYPE: - return createBrowseButton(); - case CANCEL_TYPE: - return createButton(CANCEL_LABEL); - case EDIT_TYPE: - return createImageButton("images/accessories-text-editor.png", "Edit", BROWSE_SIZE); - case OK_TYPE: - return createButton(OK_LABEL); - default: - return createButton(UNTITLED); - } - } - - /** - * Create a button with the given text. - * @param text the text to use in the button. - */ - public static JButton createButton(String text) { - return new JButton(text); - } - - /** - * Create the panel for the buttons; the button are aligned vertically; - * the side margins on the panel has a default value of 20. - * @param buttons the array of buttons to put in the panel. - */ - public static JPanel createButtonPanel(JButton[] buttons) { - return createButtonPanel(buttons, SIDE_MARGIN, Y_AXIS); - } - - /** - * Create the panel for the buttons; the button are aligned as specified; - * the side margins on the panel has a default value of 20. - * @param buttons the array buttons to put in the panel. - * @param alignment either X_AXIS or Y_AXIS - */ - public static JPanel createButtonPanel(JButton[] buttons, char alignment) { - return createButtonPanel(buttons, SIDE_MARGIN, alignment); - } - - /** - * Create the panel for the buttons; the button are aligned vertically; - * use sideMargin value for side margins on the panel. - * @param buttons the array buttons to put in the panel. - * @param sideMargin the amount of margin space to use on the sides. - */ - public static JPanel createButtonPanel(JButton[] buttons, int sideMargin) { - return createButtonPanel(buttons, sideMargin, Y_AXIS); - } - - /** - * Create the panel for the buttons; the button are aligned as specified; - * use sideMargin value for side margins on the panel, and use either - * X_AXIS or Y_AXIS as the alignment specification. - * @param buttons the array buttons to put in the panel. - * @param alignment either X_AXIS or Y_AXIS - */ - public static JPanel createButtonPanel(JButton[] buttons, int sideMargin, char alignment) { - JPanel panel = new JPanel(); - JPanel subPanel = new JPanel(); - panel.add(subPanel); - - subPanel.setLayout((alignment == Y_AXIS ? new GridLayout(0, 1, 0, BUTTON_GAP) - : new GridLayout(1, 0, BUTTON_GAP, 0))); - - Border inside = - BorderFactory.createEmptyBorder(TOP_MARGIN, sideMargin, BOTTOM_MARGIN, sideMargin); - subPanel.setBorder(inside); - - for (JButton button : buttons) { - subPanel.add(button); - } - return panel; - } - - /** - * Create an button that has an icon created from the given imageFile. - * @param imageFile icon filename - * @param alternateText text to use if the icon could not be loaded - * @param preferredSize size that the button would like to be - * @return JButton new button - */ - public static JButton createImageButton(String imageFile, String alternateText, - Dimension preferredSize) { - - ImageIcon buttonIcon = ResourceManager.loadImage(imageFile); - return createImageButton(buttonIcon, alternateText, preferredSize); - } - - /** - * Create a button with the given icon. - * @param buttonIcon icon for the button - * @param alternateText text to use if the icon could not be loaded - * @param preferredSize size that the button would like to be - * @return JButton new button - */ - public static JButton createImageButton(ImageIcon buttonIcon, String alternateText, - Dimension preferredSize) { - - JButton button = ButtonPanelFactory.createButton(""); - if (buttonIcon != null) { - button.setIcon(buttonIcon); - } - else { - button.setText(alternateText); - } - button.setPreferredSize(preferredSize); - - return button; - } - - private static JButton createBrowseButton() { - - JButton button = new JButton(BROWSE_ICON); - button.setName("BrowseButton"); - - button.setToolTipText(BROWSE_TOOLTIP_TEXT); - - return button; - } -} diff --git a/Ghidra/Framework/Docking/src/main/java/docking/options/editor/FileChooserEditor.java b/Ghidra/Framework/Docking/src/main/java/docking/options/editor/FileChooserEditor.java index 82d3a743f6..42628ca6cd 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/options/editor/FileChooserEditor.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/options/editor/FileChooserEditor.java @@ -26,6 +26,7 @@ import javax.swing.event.DocumentListener; import org.apache.commons.lang3.StringUtils; +import docking.widgets.button.BrowseButton; import docking.widgets.filechooser.GhidraFileChooser; /** @@ -105,7 +106,7 @@ public class FileChooserEditor extends PropertyEditorSupport { setLayout(bl); textField.setText(currentFileValue != null ? currentFileValue.getAbsolutePath() : ""); - browseButton = ButtonPanelFactory.createButton(ButtonPanelFactory.BROWSE_TYPE); + browseButton = new BrowseButton(); add(textField); add(Box.createHorizontalStrut(5)); diff --git a/Ghidra/Framework/Docking/src/main/java/docking/options/editor/IconPropertyEditor.java b/Ghidra/Framework/Docking/src/main/java/docking/options/editor/IconPropertyEditor.java index 68d863f44f..684abc50cf 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/options/editor/IconPropertyEditor.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/options/editor/IconPropertyEditor.java @@ -28,6 +28,7 @@ import org.apache.commons.io.FileUtils; import docking.theme.gui.ProtectedIcon; import docking.widgets.*; +import docking.widgets.button.BrowseButton; import docking.widgets.filechooser.GhidraFileChooser; import docking.widgets.filechooser.GhidraFileChooserMode; import docking.widgets.label.GDLabel; @@ -126,7 +127,7 @@ public class IconPropertyEditor extends PropertyEditorSupport { }; dropDown.addDropDownSelectionChoiceListener(choiceListener); panel.add(dropDown, BorderLayout.CENTER); - JButton browseButton = ButtonPanelFactory.createButton(ButtonPanelFactory.BROWSE_TYPE); + JButton browseButton = new BrowseButton(); panel.add(browseButton, BorderLayout.EAST); browseButton.addActionListener(e -> browse()); diff --git a/Ghidra/Framework/Docking/src/main/java/docking/theme/gui/ExportThemeDialog.java b/Ghidra/Framework/Docking/src/main/java/docking/theme/gui/ExportThemeDialog.java index 482be31be4..9c3de8614f 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/theme/gui/ExportThemeDialog.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/theme/gui/ExportThemeDialog.java @@ -23,7 +23,7 @@ import java.io.IOException; import javax.swing.*; import docking.DialogComponentProvider; -import docking.options.editor.ButtonPanelFactory; +import docking.widgets.button.BrowseButton; import docking.widgets.checkbox.GCheckBox; import docking.widgets.filechooser.GhidraFileChooser; import docking.widgets.filechooser.GhidraFileChooserMode; @@ -138,7 +138,7 @@ public class ExportThemeDialog extends DialogComponentProvider { fileTextField.setText(file.getAbsolutePath()); fileTextField.setEditable(false); fileTextField.setFocusable(false); - JButton folderButton = ButtonPanelFactory.createButton(ButtonPanelFactory.BROWSE_TYPE); + JButton folderButton = new BrowseButton(); folderButton.addActionListener(e -> chooseFile()); JPanel panel = new JPanel(new BorderLayout()); diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/ListSelectionDialog.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/ListSelectionDialog.java index d9de1abdf3..efad5207bd 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/widgets/ListSelectionDialog.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/ListSelectionDialog.java @@ -24,7 +24,7 @@ import javax.swing.*; import docking.DialogComponentProvider; import docking.DockingWindowManager; -import docking.options.editor.ButtonPanelFactory; +import docking.widgets.button.BrowseButton; import docking.widgets.label.GLabel; import docking.widgets.table.AbstractGTableModel; import docking.widgets.table.RowObjectTableModel; @@ -134,7 +134,7 @@ public class ListSelectionDialog extends DialogComponentProvider { panel.add(jLabel, BorderLayout.WEST); panel.add(field, BorderLayout.CENTER); - JButton browseButton = ButtonPanelFactory.createButton(ButtonPanelFactory.BROWSE_TYPE); + JButton browseButton = new BrowseButton(); browseButton.addActionListener(e -> browse()); panel.add(browseButton, BorderLayout.EAST); return panel; @@ -221,8 +221,8 @@ public class ListSelectionDialog extends DialogComponentProvider { list.add("bOb"); list.add("bobby"); list.add("zzz"); - ListSelectionDialog dialog = ListSelectionDialog.getStringListSelectionDialog( - "String Picker", "Choose String:", list); + ListSelectionDialog dialog = ListSelectionDialog + .getStringListSelectionDialog("String Picker", "Choose String:", list); String selectedValue = dialog.show(jFrame); System.out.println("Selected: " + selectedValue); diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/button/BrowseButton.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/button/BrowseButton.java new file mode 100644 index 0000000000..7b5f424b85 --- /dev/null +++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/button/BrowseButton.java @@ -0,0 +1,59 @@ +/* ### + * 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 docking.widgets.button; + +import java.awt.Component; +import java.awt.Graphics; + +import javax.swing.Icon; +import javax.swing.JButton; + +import generic.theme.GThemeDefaults.Colors; + +/** + * A button meant to be used to show a chooser dialog. + */ +public class BrowseButton extends JButton { + + public static final String NAME = "BrowseButton"; + public static final String TOOLTIP_TEXT = "Browse"; + + private static final Icon ICON = new Icon() { + @Override + public void paintIcon(Component c, Graphics g, int x, int y) { + g.setColor(Colors.FOREGROUND); + g.fillRect(x, y + 5, 2, 2); + g.fillRect(x + 4, y + 5, 2, 2); + g.fillRect(x + 8, y + 5, 2, 2); + } + + @Override + public int getIconWidth() { + return 10; + } + + @Override + public int getIconHeight() { + return 10; + } + }; + + public BrowseButton() { + setIcon(ICON); + setName(NAME); + setToolTipText(TOOLTIP_TEXT); + } +} diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/EditPluginPathDialog.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/EditPluginPathDialog.java index 2c0f0f4dae..f2ce56a873 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/EditPluginPathDialog.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/EditPluginPathDialog.java @@ -25,12 +25,12 @@ import java.util.Collections; import java.util.List; import javax.swing.*; +import javax.swing.border.Border; import javax.swing.border.TitledBorder; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import docking.DialogComponentProvider; -import docking.options.editor.ButtonPanelFactory; import docking.widgets.filechooser.GhidraFileChooser; import docking.widgets.filechooser.GhidraFileChooserMode; import docking.widgets.label.GDLabel; @@ -43,22 +43,23 @@ import ghidra.util.HelpLocation; import ghidra.util.Msg; import ghidra.util.filechooser.ExtensionFileFilter; import ghidra.util.filechooser.GhidraFileFilter; +import resources.Icons; +import resources.ResourceManager; /** * Dialog for editing the Plugin path and Jar directory path preferences. - * + * *

The Plugin Path and Jar directory path are locations where Ghidra searches * for plugins to load. The Plugin Path is specified exactly as a Java Classpath - * is specified. When changes are made to these fields in the dialog, the + * is specified. When changes are made to these fields in the dialog, the * preferences file is updated and written to disk. The preferences file is * located in the .ghidra directory in the user's home directory. - * + * */ class EditPluginPathDialog extends DialogComponentProvider { static final String ADD_DIR_BUTTON_TEXT = "Add Dir ..."; static final String ADD_JAR_BUTTON_TEXT = "Add Jar ..."; - private final static int SIDE_MARGIN = 5; private final static Color INVALID_PATH_COLOR = Tables.FG_ERROR_UNSELECTED; private final static Color INVALID_SELECTED_PATH_COLOR = Tables.FG_ERROR_SELECTED; private final static Color STATUS_MESSAGE_COLOR = Messages.NORMAL; @@ -267,10 +268,13 @@ class EditPluginPathDialog extends DialogComponentProvider { private JPanel buildPluginPathsPanel() { // create the UP and DOWN arrows panel - upButton = ButtonPanelFactory.createButton(ButtonPanelFactory.ARROW_UP_TYPE); + upButton = new JButton(Icons.UP_ICON); + upButton.setDisabledIcon(ResourceManager.getDisabledIcon(Icons.UP_ICON)); upButton.setName("UpArrow"); upButton.addActionListener(e -> handleSelection(UP)); - downButton = ButtonPanelFactory.createButton(ButtonPanelFactory.ARROW_DOWN_TYPE); + + downButton = new JButton(Icons.DOWN_ICON); + downButton.setDisabledIcon(ResourceManager.getDisabledIcon(Icons.DOWN_ICON)); downButton.setName("DownArrow"); downButton.addActionListener(e -> handleSelection(DOWN)); JPanel arrowButtonsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 10)); @@ -278,17 +282,33 @@ class EditPluginPathDialog extends DialogComponentProvider { arrowButtonsPanel.add(downButton); // create the Add and Remove panel - JButton addJarButton = ButtonPanelFactory.createButton(ADD_JAR_BUTTON_TEXT); + JButton addJarButton = new JButton(ADD_JAR_BUTTON_TEXT); addJarButton.addActionListener(e -> addJarCallback()); - JButton addDirButton = ButtonPanelFactory.createButton(ADD_DIR_BUTTON_TEXT); + JButton addDirButton = new JButton(ADD_DIR_BUTTON_TEXT); addDirButton.addActionListener(e -> addDirCallback()); - removeButton = ButtonPanelFactory.createButton("Remove"); + removeButton = new JButton("Remove"); removeButton.addActionListener(e -> handleSelection(REMOVE)); Dimension d = addJarButton.getPreferredSize(); addDirButton.setPreferredSize(d); removeButton.setPreferredSize(d); - JPanel otherButtonsPanel = ButtonPanelFactory.createButtonPanel( - new JButton[] { addJarButton, addDirButton, removeButton }, SIDE_MARGIN); + + // + // Button panel for adding and removing jar files + // + JPanel otherButtonsPanel = new JPanel(); + JPanel subPanel = new JPanel(); + otherButtonsPanel.add(subPanel); + int buttonGap = 10; + subPanel.setLayout(new GridLayout(0, 1, 0, buttonGap)); + + int top = 8; + int side = 5; + Border inside = BorderFactory.createEmptyBorder(top, side, top, side); + subPanel.setBorder(inside); + + subPanel.add(addJarButton); + subPanel.add(addDirButton); + subPanel.add(removeButton); // put the right-side buttons panel together JPanel listButtonPanel = new JPanel(new BorderLayout(0, 0)); diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ImportGhidraToolsDialog.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ImportGhidraToolsDialog.java index 2d8de9eea8..cb2b3822d0 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ImportGhidraToolsDialog.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ImportGhidraToolsDialog.java @@ -26,7 +26,6 @@ import javax.swing.*; import javax.swing.border.TitledBorder; import docking.DialogComponentProvider; -import docking.options.editor.ButtonPanelFactory; import docking.tool.ToolConstants; import docking.widgets.checkbox.GCheckBox; import docking.widgets.list.ListPanel; @@ -38,15 +37,10 @@ import ghidra.util.HelpLocation; class ImportGhidraToolsDialog extends DialogComponentProvider { - private final static String SELECT_ALL = "Select All"; - private final static String DESELECT_ALL = "Select None"; - private ListPanel listPanel; private JPanel mainPanel; private GCheckBox[] checkboxes; private String[] tools; - private JButton selectAllButton; - private JButton deselectAllButton; private FrontEndTool tool; private boolean cancelled = false; @@ -66,8 +60,6 @@ class ImportGhidraToolsDialog extends DialogComponentProvider { addOKButton(); addCancelButton(); - - addListeners(); } void showDialog() { @@ -103,26 +95,13 @@ class ImportGhidraToolsDialog extends DialogComponentProvider { panel.setLayout(new BorderLayout()); JPanel availableToolsPanel = new JPanel(new BorderLayout()); - // - // Create Button Panel - // - selectAllButton = new JButton(SELECT_ALL); - selectAllButton.setMnemonic('A'); - deselectAllButton = new JButton(DESELECT_ALL); - deselectAllButton.setMnemonic('N'); + SelectPanel myButtonPanel = new SelectPanel(e -> selectAll(), e -> deselectAll()); - JPanel buttonPanel = ButtonPanelFactory.createButtonPanel( - new JButton[] { selectAllButton, deselectAllButton }); - - // - // List Panel - // listPanel = new ListPanel(); listPanel.setCellRenderer(new DataCellRenderer()); listPanel.setMouseListener(new ListMouseListener()); - // Layout Main Panel - availableToolsPanel.add(buttonPanel, BorderLayout.EAST); + availableToolsPanel.add(myButtonPanel, BorderLayout.EAST); availableToolsPanel.add(listPanel, BorderLayout.CENTER); availableToolsPanel.setBorder(new TitledBorder("Available Tools")); @@ -130,15 +109,6 @@ class ImportGhidraToolsDialog extends DialogComponentProvider { return panel; } - /** - * Add listeners to the buttons. - */ - private void addListeners() { - selectAllButton.addActionListener(e -> selectAll()); - - deselectAllButton.addActionListener(e -> deselectAll()); - } - /** * Select all files to be saved. */ diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ProjectAccessPanel.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ProjectAccessPanel.java index 355fcca2d7..d57e4e625a 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ProjectAccessPanel.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/ProjectAccessPanel.java @@ -22,8 +22,8 @@ import java.util.Arrays; import java.util.List; import javax.swing.*; +import javax.swing.border.Border; -import docking.options.editor.ButtonPanelFactory; import docking.widgets.checkbox.GCheckBox; import docking.widgets.list.GListCellRenderer; import docking.widgets.table.GTable; @@ -48,10 +48,10 @@ import util.CollectionUtils; *

  • User Access Panel: Displays all users on the project, and their access permissions
  • * *

    - * If the current user is an admin, he may change user permissions and add/remove them + * If the current user is an admin, he may change user permissions and add/remove them * from the project. If not, only the User Access Panel will be visible and it will * be read-only. - * + * */ public class ProjectAccessPanel extends AbstractWizardJPanel { @@ -73,9 +73,9 @@ public class ProjectAccessPanel extends AbstractWizardJPanel { protected PluginTool tool; - /** + /** * Construct a new panel from a {@link RepositoryAdapter} instance. - * + * * @param knownUsers names of the users that are known to the remote server * @param repository the repository adapter instance * @param tool the current tool @@ -91,13 +91,13 @@ public class ProjectAccessPanel extends AbstractWizardJPanel { /** * Constructs a new panel from the given arguments. - * + * * @param knownUsers names of the users that are known to the remote server * @param currentUser the current user * @param allUsers all users known to the repository * @param repositoryName the name of the repository * @param anonymousServerAccessAllowed true if the server allows anonymous access - * @param anonymousAccessEnabled true if the repository allows anonymous access + * @param anonymousAccessEnabled true if the repository allows anonymous access * (ignored if anonymousServerAccessAllowed is false) * @param tool the current tool */ @@ -144,7 +144,7 @@ public class ProjectAccessPanel extends AbstractWizardJPanel { /** * Sets the help location. - * + * * @param helpLoc the help location */ void setHelpLocation(HelpLocation helpLoc) { @@ -153,7 +153,7 @@ public class ProjectAccessPanel extends AbstractWizardJPanel { /** * Returns a list of all users with permission to access the project. - * + * * @return the list of users */ User[] getProjectUsers() { @@ -162,7 +162,7 @@ public class ProjectAccessPanel extends AbstractWizardJPanel { /** * Returns true if anonymous access is allowed by the repository. - * + * * @return true if allowed */ boolean allowAnonymousAccess() { @@ -171,7 +171,7 @@ public class ProjectAccessPanel extends AbstractWizardJPanel { /** * Returns the repository name. - * + * * @return the repository name */ String getRepositoryName() { @@ -237,8 +237,24 @@ public class ProjectAccessPanel extends AbstractWizardJPanel { }); removeAllButton.setEnabled(true); - JPanel panel = ButtonPanelFactory.createButtonPanel( - new JButton[] { addButton, addAllButton, removeButton, removeAllButton }, 5); + // + // Button panel for moving users back and forth; a vertical panel of buttons + // + JPanel panel = new JPanel(); + JPanel subPanel = new JPanel(); + panel.add(subPanel); + subPanel.setLayout(new GridLayout(0, 1, 0, 10)); + + int top = 8; + int side = 5; + Border inside = BorderFactory.createEmptyBorder(top, side, top, side); + subPanel.setBorder(inside); + + subPanel.add(addButton); + subPanel.add(addAllButton); + subPanel.add(removeButton); + subPanel.add(removeAllButton); + panel.setMinimumSize(panel.getPreferredSize()); // Set up a listener so this panel can update its state when something in the user @@ -325,7 +341,7 @@ public class ProjectAccessPanel extends AbstractWizardJPanel { } /** - * Panel for displaying project users and their access permissions. Users with admin rights + * Panel for displaying project users and their access permissions. Users with admin rights * can edit the permissions of other users. */ class UserAccessPanel extends JPanel { @@ -335,7 +351,7 @@ public class ProjectAccessPanel extends AbstractWizardJPanel { /** * Creates a new user access panel. - * + * * @param user the current user */ UserAccessPanel(String user) { @@ -359,7 +375,7 @@ public class ProjectAccessPanel extends AbstractWizardJPanel { /** * Returns the user table. - * + * * @return the user table */ GTable getTable() { @@ -375,7 +391,7 @@ public class ProjectAccessPanel extends AbstractWizardJPanel { /** * Returns a list of all selected users in the table. - * + * * @return list of user names */ List getSelectedUsers() { @@ -392,7 +408,7 @@ public class ProjectAccessPanel extends AbstractWizardJPanel { /** * Returns true if the given user is in the project access list. - * + * * @param name the user name * @return true if already has project access */ @@ -410,7 +426,7 @@ public class ProjectAccessPanel extends AbstractWizardJPanel { /** * Returns a list of all users who have project access. - * + * * @return list of users */ User[] getProjectUsers() { @@ -459,7 +475,7 @@ public class ProjectAccessPanel extends AbstractWizardJPanel { /** * Adds the give list of users to the table. - * + * * @param users the users to add */ private void addUsers(List users) { @@ -488,7 +504,7 @@ public class ProjectAccessPanel extends AbstractWizardJPanel { /** * Creates a new users panel. - * + * * @param users list of users to display */ KnownUsersPanel(List users) { @@ -524,7 +540,7 @@ public class ProjectAccessPanel extends AbstractWizardJPanel { /** * Returns a list of selected users - * + * * @return list of user names */ List getSelectedUsers() { @@ -533,7 +549,7 @@ public class ProjectAccessPanel extends AbstractWizardJPanel { /** * Returns the user list. - * + * * @return the user list */ JList getList() { @@ -542,7 +558,7 @@ public class ProjectAccessPanel extends AbstractWizardJPanel { /** * Returns a list of all users in the panel - * + * * @return list of user names */ List getAllUsers() { diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/SaveDataDialog.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/SaveDataDialog.java index 5eb54c70f9..eb7144b507 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/SaveDataDialog.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/SaveDataDialog.java @@ -25,7 +25,6 @@ import javax.swing.*; import javax.swing.border.TitledBorder; import docking.DialogComponentProvider; -import docking.options.editor.ButtonPanelFactory; import docking.widgets.checkbox.GCheckBox; import docking.widgets.list.ListPanel; import generic.theme.GThemeDefaults.Colors; @@ -47,16 +46,11 @@ import ghidra.util.task.*; */ public class SaveDataDialog extends DialogComponentProvider { - private final static String SELECT_ALL = "Select All"; - private final static String DESELECT_ALL = "Select None"; - private ListPanel listPanel; private JPanel mainPanel; private GCheckBox[] checkboxes; private List files; private boolean[] saveable; - private JButton selectAllButton; - private JButton deselectAllButton; private JButton yesButton; private JButton noButton; private PluginTool tool; @@ -89,15 +83,13 @@ public class SaveDataDialog extends DialogComponentProvider { }); addButton(noButton); addCancelButton(); - - addListeners(); } /** * Shows the save dialog with the given domain files, but no options to save * the project. The dialog will not appear if there is no data that needs * saving. - * + * * @param domainFiles The files that may need saving. * @return true if the user hit the 'Save' or 'Don't Save' option; return false if the * user cancelled the operation @@ -162,25 +154,12 @@ public class SaveDataDialog extends DialogComponentProvider { panel.setLayout(new BorderLayout()); JPanel parentPanel = new JPanel(new BorderLayout()); - // - // Create Button Panel - // - selectAllButton = new JButton(SELECT_ALL); - selectAllButton.setMnemonic('A'); - deselectAllButton = new JButton(DESELECT_ALL); - deselectAllButton.setMnemonic('N'); + SelectPanel myButtonPanel = new SelectPanel(e -> selectAll(), e -> deselectAll()); - JPanel myButtonPanel = ButtonPanelFactory.createButtonPanel( - new JButton[] { selectAllButton, deselectAllButton }); - - // - // List Panel - // listPanel = new ListPanel(); listPanel.setCellRenderer(new DataCellRenderer()); listPanel.setMouseListener(new ListMouseListener()); - // Layout Main Panel parentPanel.add(myButtonPanel, BorderLayout.EAST); parentPanel.add(listPanel, BorderLayout.CENTER); parentPanel.setBorder(new TitledBorder("Data")); @@ -189,16 +168,6 @@ public class SaveDataDialog extends DialogComponentProvider { return panel; } - /** - * Add listeners to the buttons. - */ - private void addListeners() { - selectAllButton.addActionListener(e -> selectAll()); - - deselectAllButton.addActionListener(e -> deselectAll()); - - } - /** * Select all files to be saved. */ @@ -304,7 +273,7 @@ public class SaveDataDialog extends DialogComponentProvider { public void mouseClicked(MouseEvent e) { clearStatusText(); - JList list = (JList) e.getSource(); + JList list = (JList) e.getSource(); int index = list.locationToIndex(e.getPoint()); if (index < 0) { return; diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/SelectPanel.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/SelectPanel.java new file mode 100644 index 0000000000..b5679dc603 --- /dev/null +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/SelectPanel.java @@ -0,0 +1,55 @@ +/* ### + * 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 java.awt.GridLayout; +import java.awt.event.ActionListener; + +import javax.swing.*; +import javax.swing.border.Border; + +/** + * A simple panel with buttons for selecting and de-selecting items + */ +public class SelectPanel extends JPanel { + + private final static String SELECT_ALL = "Select All"; + private final static String DESELECT_ALL = "Select None"; + + public SelectPanel(ActionListener selectAllCallback, ActionListener deselectAllCallback) { + + JButton selectAllButton = new JButton(SELECT_ALL); + selectAllButton.setMnemonic('A'); + selectAllButton.addActionListener(selectAllCallback); + JButton deselectAllButton = new JButton(DESELECT_ALL); + deselectAllButton.setMnemonic('N'); + deselectAllButton.addActionListener(deselectAllCallback); + + JPanel subPanel = new JPanel(); + int buttonGap = 10; + subPanel.setLayout(new GridLayout(0, 1, 0, buttonGap)); + + int top = 8; + int side = 20; + Border inside = BorderFactory.createEmptyBorder(top, side, top, side); + subPanel.setBorder(inside); + + subPanel.add(selectAllButton); + subPanel.add(deselectAllButton); + add(subPanel); + + } +} diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/SelectProjectPanel.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/SelectProjectPanel.java index 78eb9b42f5..ff9c4df2f9 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/SelectProjectPanel.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/SelectProjectPanel.java @@ -25,7 +25,7 @@ import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.text.Document; -import docking.options.editor.ButtonPanelFactory; +import docking.widgets.button.BrowseButton; import docking.widgets.filechooser.GhidraFileChooser; import docking.widgets.filechooser.GhidraFileChooserMode; import docking.widgets.label.GDLabel; @@ -45,7 +45,7 @@ import ghidra.util.layout.VerticalLayout; * Panel that allows the project directory and name to be specified for a * new project. A checkbox indicates whether the project should be created * as a shared project. - * + * */ class SelectProjectPanel extends AbstractWizardJPanel { @@ -178,7 +178,7 @@ class SelectProjectPanel extends AbstractWizardJPanel { projectNameField.getDocument().addDocumentListener(docListener); directoryField.getDocument().addDocumentListener(docListener); - browseButton = ButtonPanelFactory.createButton(ButtonPanelFactory.BROWSE_TYPE); + browseButton = new BrowseButton(); browseButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -186,7 +186,7 @@ class SelectProjectPanel extends AbstractWizardJPanel { } }); -// sharedProjectCB = new GCheckBox("Project can be Shared with Others"); +// sharedProjectCB = new GCheckBox("Project can be Shared with Others"); // sharedProjectCB.addItemListener(new ItemListener() { // public void itemStateChanged(ItemEvent e) { // panelManager.getWizardManager().validityChanged(); diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/dialog/SaveToolConfigDialog.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/dialog/SaveToolConfigDialog.java index d7d0a626ec..234b3aae04 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/dialog/SaveToolConfigDialog.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/dialog/SaveToolConfigDialog.java @@ -26,9 +26,9 @@ import javax.swing.border.TitledBorder; import javax.swing.event.*; import docking.DialogComponentProvider; -import docking.options.editor.ButtonPanelFactory; import docking.util.image.ToolIconURL; import docking.widgets.OptionDialog; +import docking.widgets.button.BrowseButton; import docking.widgets.filechooser.GhidraFileChooser; import docking.widgets.label.GLabel; import ghidra.framework.model.*; @@ -111,7 +111,7 @@ public class SaveToolConfigDialog extends DialogComponentProvider implements Lis /** * Display the "Save Tool Configuration As..." dialog; * blocks until user hits the "Cancel" button. - * + * * @param name original name for the tool */ public void show(String name, String newDefaultName) { @@ -269,7 +269,7 @@ public class SaveToolConfigDialog extends DialogComponentProvider implements Lis } /** - * Create a panel that has text fields for entering a + * Create a panel that has text fields for entering a * name and tool description */ private JPanel createToolFieldPanel() { @@ -312,7 +312,7 @@ public class SaveToolConfigDialog extends DialogComponentProvider implements Lis iconField = new JTextField(12); iconField.setName("IconName"); - browseButton = ButtonPanelFactory.createButton(ButtonPanelFactory.BROWSE_TYPE); + browseButton = new BrowseButton(); JPanel panel = new JPanel(new BorderLayout(5, 0)); panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/DataTypeArchiveTransformerPanel.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/DataTypeArchiveTransformerPanel.java index b056f0a037..79763853ef 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/DataTypeArchiveTransformerPanel.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/DataTypeArchiveTransformerPanel.java @@ -23,7 +23,7 @@ import java.io.IOException; import javax.swing.*; -import docking.options.editor.ButtonPanelFactory; +import docking.widgets.button.BrowseButton; import docking.widgets.checkbox.GCheckBox; import docking.widgets.filechooser.GhidraFileChooser; import docking.widgets.label.GHtmlLabel; @@ -47,7 +47,6 @@ public class DataTypeArchiveTransformerPanel extends JPanel { private JCheckBox useOldFileIDCheckBox; public DataTypeArchiveTransformerPanel() { - super(); initialize(); } @@ -87,7 +86,7 @@ public class DataTypeArchiveTransformerPanel extends JPanel { gbc.gridx = 2; gbc.gridwidth = 1; - JButton oldBrowseButton = ButtonPanelFactory.createButton(ButtonPanelFactory.BROWSE_TYPE); + JButton oldBrowseButton = new BrowseButton(); oldBrowseButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -124,7 +123,7 @@ public class DataTypeArchiveTransformerPanel extends JPanel { gbc.gridx = 2; gbc.gridwidth = 1; - JButton newBrowseButton = ButtonPanelFactory.createButton(ButtonPanelFactory.BROWSE_TYPE); + JButton newBrowseButton = new BrowseButton(); newBrowseButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -155,8 +154,7 @@ public class DataTypeArchiveTransformerPanel extends JPanel { gbc.gridx = 2; gbc.gridwidth = 1; - JButton destinationBrowseButton = - ButtonPanelFactory.createButton(ButtonPanelFactory.BROWSE_TYPE); + JButton destinationBrowseButton = new BrowseButton(); destinationBrowseButton.addActionListener(new ActionListener() { @Override diff --git a/Ghidra/Test/IntegrationTest/src/screen/java/help/screenshot/DataTypeEditorsScreenShots.java b/Ghidra/Test/IntegrationTest/src/screen/java/help/screenshot/DataTypeEditorsScreenShots.java index 8b384508c5..8482f280cc 100644 --- a/Ghidra/Test/IntegrationTest/src/screen/java/help/screenshot/DataTypeEditorsScreenShots.java +++ b/Ghidra/Test/IntegrationTest/src/screen/java/help/screenshot/DataTypeEditorsScreenShots.java @@ -25,8 +25,8 @@ import org.junit.Test; import docking.ComponentProvider; import docking.DialogComponentProvider; -import docking.options.editor.ButtonPanelFactory; import docking.widgets.DropDownSelectionTextField; +import docking.widgets.button.BrowseButton; import docking.widgets.tree.GTree; import ghidra.app.cmd.data.CreateDataCmd; import ghidra.app.plugin.core.compositeeditor.*; @@ -38,7 +38,6 @@ import ghidra.program.model.data.*; public class DataTypeEditorsScreenShots extends GhidraScreenShotGenerator { public DataTypeEditorsScreenShots() { - super(); } @Test @@ -120,7 +119,8 @@ public class DataTypeEditorsScreenShots extends GhidraScreenShotGenerator { performAction("Choose Data Type", "DataPlugin", false); DialogComponentProvider dialog = getDialog(); - final JButton browseButton = findButtonByIcon(dialog, ButtonPanelFactory.BROWSE_ICON); + AbstractButton browseButton = + findAbstractButtonByName(dialog.getComponent(), BrowseButton.NAME); pressButton(browseButton, false); waitForSwing();