diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/cparser/ParseDialog.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/cparser/ParseDialog.java index 68b95d6f08..76a4ebba49 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/cparser/ParseDialog.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/cparser/ParseDialog.java @@ -106,7 +106,7 @@ class ParseDialog extends ReusableDialogComponentProvider { private TableModel parsePathTableModel; private TableModelListener parsePathTableListener; - private ArrayList itemList; + private List itemList; private ComboBoxItemComparator comparator; private ResourceFile parentUserFile; private boolean saveAsInProgress; @@ -122,29 +122,29 @@ class ParseDialog extends ReusableDialogComponentProvider { } public void setupForDisplay() { - if (initialBuild) { - itemList = new ArrayList<>(); - comparator = new ComboBoxItemComparator(); - addWorkPanel(buildMainPanel()); - addDismissButton(); - createActions(); - setActionsEnabled(); + if (!initialBuild) { + toFront(); + return; + } - // setup based on save state - if (currentProfileName != null) { - for (int i = 0; i < itemList.size(); i++) { - ComboBoxItem item = itemList.get(i); - if (userDefined == item.isUserDefined && - currentProfileName.equals(item.file.getName())) { - comboBox.setSelectedIndex(i); - break; - } + itemList = new ArrayList<>(); + comparator = new ComboBoxItemComparator(); + addWorkPanel(buildMainPanel()); + addDismissButton(); + createActions(); + notifyContextChanged(); + + // setup based on save state + if (currentProfileName != null) { + for (int i = 0; i < itemList.size(); i++) { + ComboBoxItem item = itemList.get(i); + if (userDefined == item.isUserDefined && + currentProfileName.equals(item.file.getName())) { + comboBox.setSelectedIndex(i); + break; } } } - else { - toFront(); - } } void writeState(SaveState saveState) { @@ -257,7 +257,7 @@ class ParseDialog extends ReusableDialogComponentProvider { tableListener = e -> { ComboBoxItem item = (ComboBoxItem) comboBox.getSelectedItem(); item.isChanged = !initialBuild; - setActionsEnabled(); + notifyContextChanged(); }; tableModel = pathPanel.getTable().getModel(); tableModel.addTableModelListener(tableListener); @@ -272,7 +272,7 @@ class ParseDialog extends ReusableDialogComponentProvider { parsePathTableListener = e -> { ComboBoxItem item = (ComboBoxItem) comboBox.getSelectedItem(); item.isChanged = !initialBuild; - setActionsEnabled(); + notifyContextChanged(); pathPanel.getTable().repaint(); }; parsePathTableModel = includePathPanel.getTable().getModel(); @@ -407,30 +407,38 @@ class ParseDialog extends ReusableDialogComponentProvider { } private void selectionChanged(ItemEvent e) { - if (e.getStateChange() == ItemEvent.DESELECTED) { - ComboBoxItem item = (ComboBoxItem) e.getItem(); - if (item.isChanged && !saveAsInProgress && !initialBuild) { - if (item.isUserDefined) { - if (OptionDialog.showOptionDialog(rootPanel, "Save Changes to Profile?", - "Profile " + item.file.getName() + - " has changed.\nDo you want to save your changes?", - "Yes", OptionDialog.QUESTION_MESSAGE) == OptionDialog.OPTION_ONE) { - save(item); - } - } - else { - if (OptionDialog.showOptionDialog(rootPanel, "Save Changes to Another Profile?", - "You have made changes to the default profile " + item.file.getName() + - ",\nhowever, updating default profiles is not allowed." + - "\nDo you want to save your changes to another profile?", - "Yes", OptionDialog.QUESTION_MESSAGE) == OptionDialog.OPTION_ONE) { - saveAs(item); - } - } - } - } if (e.getStateChange() == ItemEvent.SELECTED) { loadProfile(); + return; + } + + ComboBoxItem item = (ComboBoxItem) e.getItem(); + if (!item.isChanged) { + return; + } + if (saveAsInProgress) { + return; + } + if (initialBuild) { + return; + } + + if (item.isUserDefined) { + if (OptionDialog.showOptionDialog(rootPanel, "Save Changes to Profile?", + "Profile " + item.file.getName() + + " has changed.\nDo you want to save your changes?", + "Yes", OptionDialog.QUESTION_MESSAGE) == OptionDialog.OPTION_ONE) { + save(item); + } + } + else { + if (OptionDialog.showOptionDialog(rootPanel, "Save Changes to Another Profile?", + "You have made changes to the default profile " + item.file.getName() + + ",\nhowever, updating default profiles is not allowed." + + "\nDo you want to save your changes to another profile?", + "Yes", OptionDialog.QUESTION_MESSAGE) == OptionDialog.OPTION_ONE) { + saveAs(item); + } } } @@ -482,7 +490,7 @@ class ParseDialog extends ReusableDialogComponentProvider { return; } item.isChanged = true; - setActionsEnabled(); + notifyContextChanged(); } private void createActions() { @@ -491,8 +499,13 @@ class ParseDialog extends ReusableDialogComponentProvider { public void actionPerformed(ActionContext context) { save((ComboBoxItem) comboBox.getSelectedItem()); } + + @Override + public boolean isEnabledForContext(ActionContext context) { + ComboBoxItem item = (ComboBoxItem) comboBox.getSelectedItem(); + return item.isChanged && item.isUserDefined; + } }; - saveAction.setEnabled(false); Icon icon = Icons.SAVE_ICON; String saveGroup = "save"; saveAction.setMenuBarData(new MenuData(new String[] { "Save" }, icon, saveGroup)); @@ -506,7 +519,6 @@ class ParseDialog extends ReusableDialogComponentProvider { saveAs((ComboBoxItem) comboBox.getSelectedItem()); } }; - saveAsAction.setEnabled(true); icon = Icons.SAVE_AS_ICON; saveAsAction.setMenuBarData(new MenuData(new String[] { "Save As..." }, icon, saveGroup)); saveAsAction.setToolBarData(new ToolBarData(icon, saveGroup)); @@ -518,9 +530,13 @@ class ParseDialog extends ReusableDialogComponentProvider { public void actionPerformed(ActionContext context) { clear(); } + + @Override + public boolean isEnabledForContext(ActionContext context) { + return true; + } }; - clearAction.setEnabled(true); icon = Icons.CLEAR_ICON; String clearGroup = "clear"; clearAction @@ -534,8 +550,12 @@ class ParseDialog extends ReusableDialogComponentProvider { public void actionPerformed(ActionContext context) { refresh(); } + + @Override + public boolean isEnabledForContext(ActionContext context) { + return true; + } }; - refreshAction.setEnabled(true); icon = Icons.REFRESH_ICON; String refreshGroup = "refresh"; refreshAction.setMenuBarData(new MenuData(new String[] { "Refresh" }, icon, refreshGroup)); @@ -549,8 +569,13 @@ class ParseDialog extends ReusableDialogComponentProvider { public void actionPerformed(ActionContext context) { delete(); } + + @Override + public boolean isEnabledForContext(ActionContext context) { + ComboBoxItem item = (ComboBoxItem) comboBox.getSelectedItem(); + return item.isUserDefined; + } }; - deleteAction.setEnabled(false); icon = Icons.DELETE_ICON; String deleteGroup = "Xdelete"; deleteAction.setMenuBarData(new MenuData(new String[] { "Delete" }, icon, deleteGroup)); @@ -591,7 +616,7 @@ class ParseDialog extends ReusableDialogComponentProvider { else { writeProfile(item.file); item.isChanged = false; - setActionsEnabled(); + notifyContextChanged(); } } @@ -641,7 +666,7 @@ class ParseDialog extends ReusableDialogComponentProvider { finally { saveAsInProgress = false; } - setActionsEnabled(); + notifyContextChanged(); } } @@ -655,8 +680,8 @@ class ParseDialog extends ReusableDialogComponentProvider { item.isChanged = false; StringBuffer sb = new StringBuffer(); - ArrayList pathList = new ArrayList<>(); - ArrayList includeList = new ArrayList<>(); + List pathList = new ArrayList<>(); + List includeList = new ArrayList<>(); String langString = null; String compileString = null; try { @@ -731,7 +756,7 @@ class ParseDialog extends ReusableDialogComponentProvider { addDocumentListener(); tableModel.addTableModelListener(tableListener); parsePathTableModel.addTableModelListener(parsePathTableListener); - setActionsEnabled(); + notifyContextChanged(); } } @@ -836,33 +861,30 @@ class ParseDialog extends ReusableDialogComponentProvider { } private String[] expandPaths(String[] paths) { - ArrayList list = new ArrayList<>(); - + List list = new ArrayList<>(); for (String path : paths) { File file = new File(path); + // process each header file in the directory - if (file.isDirectory()) { - IncludeFileFinder includeFileFinder = new IncludeFileFinder(file); - try { - List includeFileRoots = includeFileFinder.getIncludeFileRoots(true); - for (Object element : includeFileRoots) { - String string = (String) element; - if (string.endsWith(".h")) { - list.add(string); - } + if (!file.isDirectory()) { + list.add(path); + continue; + } + + IncludeFileFinder finder = new IncludeFileFinder(file); + try { + List roots = finder.getIncludeFileRoots(true); + for (String filePath : roots) { + if (filePath.endsWith(".h")) { + list.add(filePath); } } - catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } } - else { - list.add(path); + catch (IOException e) { + Msg.error(this, "Exception finding CParser paths", e); } } - // convert paths list to String[] return list.toArray(new String[0]); } @@ -896,14 +918,6 @@ class ParseDialog extends ReusableDialogComponentProvider { } } - private void setActionsEnabled() { - ComboBoxItem item = (ComboBoxItem) comboBox.getSelectedItem(); - if (saveAction != null) { - saveAction.setEnabled(item.isChanged && item.isUserDefined); - deleteAction.setEnabled(item.isUserDefined); - } - } - private File getSaveFile() { GhidraFileChooser fileChooser = new GhidraFileChooser(rootPanel); @@ -914,41 +928,44 @@ class ParseDialog extends ReusableDialogComponentProvider { File file = fileChooser.getSelectedFile(); fileChooser.dispose(); - if (file != null) { - File parent = file.getParentFile(); - if (parent != null) { - Preferences.setProperty(Preferences.LAST_EXPORT_DIRECTORY, - parent.getAbsolutePath()); - } + if (file == null) { + return null; + } - String name = file.getName(); - if (!file.getName().endsWith(FileDataTypeManager.SUFFIX)) { - file = new File(file.getParentFile(), name + FileDataTypeManager.SUFFIX); - } - if (file.exists()) { - if (OptionDialog.showOptionDialog(rootPanel, "Overwrite Existing File?", - "The file " + file.getAbsolutePath() + - " already exists.\nDo you want to overwrite it?", - "Yes", OptionDialog.QUESTION_MESSAGE) != OptionDialog.OPTION_ONE) { - file = null; - } - else { - try { - PackedDatabase.delete(file); - } - catch (IOException e) { - Msg.showError(this, mainPanel, "Archive Overwrite Failed", e.getMessage()); - return null; - } - } - } + File parent = file.getParentFile(); + if (parent != null) { + Preferences.setProperty(Preferences.LAST_EXPORT_DIRECTORY, + parent.getAbsolutePath()); + } + + String name = file.getName(); + if (!file.getName().endsWith(FileDataTypeManager.SUFFIX)) { + file = new File(file.getParentFile(), name + FileDataTypeManager.SUFFIX); + } + + if (!file.exists()) { + return file; + } + + int choice = OptionDialog.showOptionDialog(rootPanel, "Overwrite Existing File?", + "The file " + file.getAbsolutePath() + + " already exists.\nDo you want to overwrite it?", + "Yes", OptionDialog.QUESTION_MESSAGE); + + if (choice != OptionDialog.OPTION_ONE) { + return null; + } + + try { + PackedDatabase.delete(file); + } + catch (IOException e) { + Msg.showError(this, mainPanel, "Archive Overwrite Failed", e.getMessage()); + return null; } return file; } - /** - * Called when user selects Cancel Button - */ @Override protected void dismissCallback() { close(); @@ -1023,9 +1040,9 @@ class ParseDialog extends ReusableDialogComponentProvider { } } - //================================================================================================== - // Methods for Testing - //================================================================================================== +//================================================================================================== +// Methods for Testing +//================================================================================================== GhidraComboBox getParseComboBox() { return comboBox; @@ -1059,7 +1076,7 @@ class ParseDialog extends ReusableDialogComponentProvider { return this.parseToFileButton; } - ArrayList getProfiles() { + List getProfiles() { return this.itemList; } diff --git a/Ghidra/Features/Base/src/test.slow/java/docking/ComponentProviderActionsTest.java b/Ghidra/Features/Base/src/test.slow/java/docking/ComponentProviderActionsTest.java index 9eb1b9f594..0f574db55a 100644 --- a/Ghidra/Features/Base/src/test.slow/java/docking/ComponentProviderActionsTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/docking/ComponentProviderActionsTest.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,7 +17,6 @@ package docking; import static org.junit.Assert.*; -import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.util.Set; @@ -622,10 +621,14 @@ public class ComponentProviderActionsTest extends AbstractGhidraHeadedIntegratio } private void performLaunchKeyStrokeDialogAction() { - ToolActions toolActions = (ToolActions) ((AbstractDockingTool) tool).getToolActions(); + ToolActions toolActions = (ToolActions) tool.getToolActions(); Action action = toolActions.getAction(KeyStroke.getKeyStroke("F4")); assertNotNull(action); - runSwing(() -> action.actionPerformed(new ActionEvent(this, 0, "")), false); + runSwing(() -> { + SystemKeyBindingAction sysAction = (SystemKeyBindingAction) action; + ExecutableAction executableAction = sysAction.getExecutableAction(null); + executableAction.execute(); + }, false); } private ToolOptions getKeyBindingOptions() { diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/cparser/ParseDialogParsingAndPromptsTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/cparser/ParseDialogParsingAndPromptsTest.java index 853e172e88..9f9b8d35db 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/cparser/ParseDialogParsingAndPromptsTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/cparser/ParseDialogParsingAndPromptsTest.java @@ -17,11 +17,8 @@ package ghidra.app.plugin.core.cparser; import static org.junit.Assert.*; -import java.awt.Window; import java.io.File; -import java.util.ArrayList; - -import javax.swing.JTextArea; +import java.util.List; import org.junit.*; @@ -46,8 +43,6 @@ import utilities.util.FileUtilities; public class ParseDialogParsingAndPromptsTest extends AbstractGhidraHeadedIntegrationTest { - private static final String TITLE = "CParser Results Summary"; - private TestEnv env; private PluginTool tool; @@ -534,57 +529,13 @@ public class ParseDialogParsingAndPromptsTest extends AbstractGhidraHeadedIntegr } } - private void startSetLanguage(LanguageID languageID, CompilerSpecID compilerSpecID) - throws Exception { - if (languageID == null) { - throw new RuntimeException("languageID == null not allowed"); - } - if (compilerSpecID == null) { - throw new RuntimeException("compilerSpecID == null not allowed"); - } - - SetLanguageDialog dlg = waitForDialogComponent(SetLanguageDialog.class); - assertNotNull(dlg); - NewLanguagePanel languagePanel = - (NewLanguagePanel) getInstanceField("selectLangPanel", dlg); - assertNotNull(languagePanel); - - waitForSwing(); - - runSwing(() -> { - NewLanguagePanel selectLangPanel = - (NewLanguagePanel) getInstanceField("selectLangPanel", dlg); - selectLangPanel.setSelectedLcsPair( - new LanguageCompilerSpecPair(languageID, compilerSpecID)); - }, true); - - waitForSwing(); - - pressButtonByText(dlg, "OK"); - } - - private void assertResultDialog() { - Window aboutDialog = waitForWindow(TITLE); - assertNotNull(aboutDialog); - pressButtonByText(aboutDialog, "OK"); - } - private ParseDialog showParseDialog() { - - //ActionContext actionContext = cbPlugin.getProvider().getActionContext(null); performAction(cparserAction, false); ParseDialog parseDialog = waitForDialogComponent(ParseDialog.class); assertNotNull(parseDialog); return parseDialog; } - private void setOption(ParseDialog dialog, String options) { - runSwing(() -> { - JTextArea parseOptionsTextField = dialog.getParseOptionsTextField(); - parseOptionsTextField.setText(options); - }); - } - private void setIncludePaths(ParseDialog dialog, String paths[]) { runSwing(() -> { PathnameTablePanel incPaths = dialog.getIncludePaths(); @@ -602,7 +553,7 @@ public class ParseDialogParsingAndPromptsTest extends AbstractGhidraHeadedIntegr private void setSelectedParseProfile(ParseDialog dialog, String profileName) { runSwing(() -> { GhidraComboBox parseComboBox = dialog.getParseComboBox(); - ArrayList profiles = dialog.getProfiles(); + List profiles = dialog.getProfiles(); int index = 0; for (ComboBoxItem comboBoxItem : profiles) { if (profileName.equals(comboBoxItem.getName())) { diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/cparser/ParseDialogTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/cparser/ParseDialogTest.java index e3d14c13e5..209bb5a7e0 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/cparser/ParseDialogTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/cparser/ParseDialogTest.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -344,7 +344,7 @@ public class ParseDialogTest extends AbstractGhidraHeadedIntegrationTest { private void readDefaultParseProfileFile() throws Exception { - StringBuffer buffy = new StringBuffer(); + StringBuilder buffy = new StringBuilder(); List pathList = new ArrayList<>(); ResourceFile profileFile = getPrfFile(); @@ -356,17 +356,16 @@ public class ParseDialogTest extends AbstractGhidraHeadedIntegrationTest { // read paths while ((line = br.readLine()) != null && line.trim().length() > 0) { line = line.trim(); - + pathList.add(line); } - + // read options while ((line = br.readLine()) != null && line.trim().length() > 0) { line = line.trim(); - + buffy.append(line + "\n"); - } - + } paths = pathList; defaultPrfOptions = buffy.toString(); diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/tablechooser/TableChooserDialogTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/tablechooser/TableChooserDialogTest.java index 131789a4c9..b052640198 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/tablechooser/TableChooserDialogTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/tablechooser/TableChooserDialogTest.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,7 +17,6 @@ package ghidra.app.tablechooser; import static org.junit.Assert.*; -import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.util.*; import java.util.concurrent.CountDownLatch; @@ -456,10 +455,14 @@ public class TableChooserDialogTest extends AbstractGhidraHeadedIntegrationTest } private void performLaunchKeyStrokeDialogAction() { - ToolActions toolActions = (ToolActions) ((AbstractDockingTool) tool).getToolActions(); + ToolActions toolActions = (ToolActions) tool.getToolActions(); Action action = toolActions.getAction(KeyStroke.getKeyStroke("F4")); assertNotNull(action); - runSwing(() -> action.actionPerformed(new ActionEvent(this, 0, "")), false); + runSwing(() -> { + SystemKeyBindingAction sysAction = (SystemKeyBindingAction) action; + ExecutableAction executableAction = sysAction.getExecutableAction(null); + executableAction.execute(); + }, false); } private void setOptionsKeyStroke(DockingAction action, KeyStroke newKs) { diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/plugintool/dialog/ManagePluginsTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/plugintool/dialog/ManagePluginsTest.java index ec6385f1a6..45ec6eef73 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/plugintool/dialog/ManagePluginsTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/plugintool/dialog/ManagePluginsTest.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -24,6 +24,7 @@ import javax.swing.table.TableModel; import org.junit.*; +import docking.action.DockingAction; import docking.action.DockingActionIf; import docking.tool.ToolConstants; import docking.widgets.table.GTableFilterPanel; @@ -95,10 +96,12 @@ public class ManagePluginsTest extends AbstractGhidraHeadedIntegrationTest { @Test public void testActionEnablement() { - performAction(managePluginsDialog.getSaveAction(), true); + DockingAction saveAction = managePluginsDialog.getSaveAction(); + performAction(saveAction, true); + assertFalse(saveAction.isEnabledForContext(managePluginsDialog.getActionContext(null))); - assertFalse(managePluginsDialog.getSaveAction().isEnabled()); - assertTrue(managePluginsDialog.getSaveAsAction().isEnabled()); + DockingAction saveAsAction = managePluginsDialog.getSaveAsAction(); + assertTrue(saveAsAction.isEnabledForContext(managePluginsDialog.getActionContext(null))); } @Test @@ -144,7 +147,8 @@ public class ManagePluginsTest extends AbstractGhidraHeadedIntegrationTest { waitForTasks(); assertTrue(tool.hasConfigChanged()); - assertTrue(managePluginsDialog.getSaveAction().isEnabled()); + DockingAction action = managePluginsDialog.getSaveAction(); + assertTrue(action.isEnabledForContext(managePluginsDialog.getActionContext(null))); assertTrue( pluginModel.isLoaded(PluginDescription.getPluginDescription(AboutProgramPlugin.class))); } @@ -152,10 +156,11 @@ public class ManagePluginsTest extends AbstractGhidraHeadedIntegrationTest { @Test public void testRemovePlugin() throws Exception { tool.setConfigChanged(false); - SwingUtilities.invokeLater(() -> pluginManagerComponent.manageAllPlugins()); + runSwingLater(() -> pluginManagerComponent.manageAllPlugins()); pluginModel.removePlugin(PluginDescription.getPluginDescription(EquateTablePlugin.class)); assertTrue(tool.hasConfigChanged()); - assertTrue(managePluginsDialog.getSaveAction().isEnabled()); + DockingAction action = managePluginsDialog.getSaveAction(); + assertTrue(action.isEnabledForContext(managePluginsDialog.getActionContext(null))); assertFalse( pluginModel.isLoaded(PluginDescription.getPluginDescription(AboutProgramPlugin.class))); diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/dialog/ManagePluginsDialog.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/dialog/ManagePluginsDialog.java index 0c078af693..2ba35d9df8 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/dialog/ManagePluginsDialog.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/dialog/ManagePluginsDialog.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -120,8 +120,13 @@ public class ManagePluginsDialog extends ReusableDialogComponentProvider { public void actionPerformed(ActionContext context) { save(); } + + @Override + public boolean isEnabledForContext(ActionContext context) { + return tool.hasConfigChanged(); + } }; - saveAction.setEnabled(tool.hasConfigChanged()); + icon = Icons.SAVE_ICON; String saveGroup = "save"; saveAction.setMenuBarData(new MenuData(new String[] { "Save" }, icon, saveGroup)); @@ -135,8 +140,12 @@ public class ManagePluginsDialog extends ReusableDialogComponentProvider { public void actionPerformed(ActionContext context) { saveAs(); } + + @Override + public boolean isEnabledForContext(ActionContext context) { + return true; + } }; - saveAsAction.setEnabled(true); icon = Icons.SAVE_AS_ICON; saveAsAction .setMenuBarData(new MenuData(new String[] { "Save As..." }, icon, saveGroup)); @@ -157,20 +166,18 @@ public class ManagePluginsDialog extends ReusableDialogComponentProvider { } else { tool.getToolServices().saveTool(tool); - saveAction.setEnabled(false); + tool.contextChanged(null); } } private void saveAs() { tool.saveToolAs(); - saveAction.setEnabled(tool.hasConfigChanged()); + tool.contextChanged(null); isNewTool = false; } public void stateChanged() { - if (saveAction != null) { - saveAction.setEnabled(tool.hasConfigChanged()); - } + tool.contextChanged(null); } int getPackageCount() {