Test fixes

This commit is contained in:
dragonmacher 2025-04-17 19:16:58 -04:00
parent 92e2b6b5d4
commit fb76362903
7 changed files with 186 additions and 201 deletions

View file

@ -106,7 +106,7 @@ class ParseDialog extends ReusableDialogComponentProvider {
private TableModel parsePathTableModel; private TableModel parsePathTableModel;
private TableModelListener parsePathTableListener; private TableModelListener parsePathTableListener;
private ArrayList<ComboBoxItem> itemList; private List<ComboBoxItem> itemList;
private ComboBoxItemComparator comparator; private ComboBoxItemComparator comparator;
private ResourceFile parentUserFile; private ResourceFile parentUserFile;
private boolean saveAsInProgress; private boolean saveAsInProgress;
@ -122,29 +122,29 @@ class ParseDialog extends ReusableDialogComponentProvider {
} }
public void setupForDisplay() { public void setupForDisplay() {
if (initialBuild) { if (!initialBuild) {
itemList = new ArrayList<>(); toFront();
comparator = new ComboBoxItemComparator(); return;
addWorkPanel(buildMainPanel()); }
addDismissButton();
createActions();
setActionsEnabled();
// setup based on save state itemList = new ArrayList<>();
if (currentProfileName != null) { comparator = new ComboBoxItemComparator();
for (int i = 0; i < itemList.size(); i++) { addWorkPanel(buildMainPanel());
ComboBoxItem item = itemList.get(i); addDismissButton();
if (userDefined == item.isUserDefined && createActions();
currentProfileName.equals(item.file.getName())) { notifyContextChanged();
comboBox.setSelectedIndex(i);
break; // 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) { void writeState(SaveState saveState) {
@ -257,7 +257,7 @@ class ParseDialog extends ReusableDialogComponentProvider {
tableListener = e -> { tableListener = e -> {
ComboBoxItem item = (ComboBoxItem) comboBox.getSelectedItem(); ComboBoxItem item = (ComboBoxItem) comboBox.getSelectedItem();
item.isChanged = !initialBuild; item.isChanged = !initialBuild;
setActionsEnabled(); notifyContextChanged();
}; };
tableModel = pathPanel.getTable().getModel(); tableModel = pathPanel.getTable().getModel();
tableModel.addTableModelListener(tableListener); tableModel.addTableModelListener(tableListener);
@ -272,7 +272,7 @@ class ParseDialog extends ReusableDialogComponentProvider {
parsePathTableListener = e -> { parsePathTableListener = e -> {
ComboBoxItem item = (ComboBoxItem) comboBox.getSelectedItem(); ComboBoxItem item = (ComboBoxItem) comboBox.getSelectedItem();
item.isChanged = !initialBuild; item.isChanged = !initialBuild;
setActionsEnabled(); notifyContextChanged();
pathPanel.getTable().repaint(); pathPanel.getTable().repaint();
}; };
parsePathTableModel = includePathPanel.getTable().getModel(); parsePathTableModel = includePathPanel.getTable().getModel();
@ -407,30 +407,38 @@ class ParseDialog extends ReusableDialogComponentProvider {
} }
private void selectionChanged(ItemEvent e) { 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) { if (e.getStateChange() == ItemEvent.SELECTED) {
loadProfile(); 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; return;
} }
item.isChanged = true; item.isChanged = true;
setActionsEnabled(); notifyContextChanged();
} }
private void createActions() { private void createActions() {
@ -491,8 +499,13 @@ class ParseDialog extends ReusableDialogComponentProvider {
public void actionPerformed(ActionContext context) { public void actionPerformed(ActionContext context) {
save((ComboBoxItem) comboBox.getSelectedItem()); 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; Icon icon = Icons.SAVE_ICON;
String saveGroup = "save"; String saveGroup = "save";
saveAction.setMenuBarData(new MenuData(new String[] { "Save" }, icon, saveGroup)); saveAction.setMenuBarData(new MenuData(new String[] { "Save" }, icon, saveGroup));
@ -506,7 +519,6 @@ class ParseDialog extends ReusableDialogComponentProvider {
saveAs((ComboBoxItem) comboBox.getSelectedItem()); saveAs((ComboBoxItem) comboBox.getSelectedItem());
} }
}; };
saveAsAction.setEnabled(true);
icon = Icons.SAVE_AS_ICON; icon = Icons.SAVE_AS_ICON;
saveAsAction.setMenuBarData(new MenuData(new String[] { "Save As..." }, icon, saveGroup)); saveAsAction.setMenuBarData(new MenuData(new String[] { "Save As..." }, icon, saveGroup));
saveAsAction.setToolBarData(new ToolBarData(icon, saveGroup)); saveAsAction.setToolBarData(new ToolBarData(icon, saveGroup));
@ -518,9 +530,13 @@ class ParseDialog extends ReusableDialogComponentProvider {
public void actionPerformed(ActionContext context) { public void actionPerformed(ActionContext context) {
clear(); clear();
} }
@Override
public boolean isEnabledForContext(ActionContext context) {
return true;
}
}; };
clearAction.setEnabled(true);
icon = Icons.CLEAR_ICON; icon = Icons.CLEAR_ICON;
String clearGroup = "clear"; String clearGroup = "clear";
clearAction clearAction
@ -534,8 +550,12 @@ class ParseDialog extends ReusableDialogComponentProvider {
public void actionPerformed(ActionContext context) { public void actionPerformed(ActionContext context) {
refresh(); refresh();
} }
@Override
public boolean isEnabledForContext(ActionContext context) {
return true;
}
}; };
refreshAction.setEnabled(true);
icon = Icons.REFRESH_ICON; icon = Icons.REFRESH_ICON;
String refreshGroup = "refresh"; String refreshGroup = "refresh";
refreshAction.setMenuBarData(new MenuData(new String[] { "Refresh" }, icon, refreshGroup)); refreshAction.setMenuBarData(new MenuData(new String[] { "Refresh" }, icon, refreshGroup));
@ -549,8 +569,13 @@ class ParseDialog extends ReusableDialogComponentProvider {
public void actionPerformed(ActionContext context) { public void actionPerformed(ActionContext context) {
delete(); delete();
} }
@Override
public boolean isEnabledForContext(ActionContext context) {
ComboBoxItem item = (ComboBoxItem) comboBox.getSelectedItem();
return item.isUserDefined;
}
}; };
deleteAction.setEnabled(false);
icon = Icons.DELETE_ICON; icon = Icons.DELETE_ICON;
String deleteGroup = "Xdelete"; String deleteGroup = "Xdelete";
deleteAction.setMenuBarData(new MenuData(new String[] { "Delete" }, icon, deleteGroup)); deleteAction.setMenuBarData(new MenuData(new String[] { "Delete" }, icon, deleteGroup));
@ -591,7 +616,7 @@ class ParseDialog extends ReusableDialogComponentProvider {
else { else {
writeProfile(item.file); writeProfile(item.file);
item.isChanged = false; item.isChanged = false;
setActionsEnabled(); notifyContextChanged();
} }
} }
@ -641,7 +666,7 @@ class ParseDialog extends ReusableDialogComponentProvider {
finally { finally {
saveAsInProgress = false; saveAsInProgress = false;
} }
setActionsEnabled(); notifyContextChanged();
} }
} }
@ -655,8 +680,8 @@ class ParseDialog extends ReusableDialogComponentProvider {
item.isChanged = false; item.isChanged = false;
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
ArrayList<String> pathList = new ArrayList<>(); List<String> pathList = new ArrayList<>();
ArrayList<String> includeList = new ArrayList<>(); List<String> includeList = new ArrayList<>();
String langString = null; String langString = null;
String compileString = null; String compileString = null;
try { try {
@ -731,7 +756,7 @@ class ParseDialog extends ReusableDialogComponentProvider {
addDocumentListener(); addDocumentListener();
tableModel.addTableModelListener(tableListener); tableModel.addTableModelListener(tableListener);
parsePathTableModel.addTableModelListener(parsePathTableListener); parsePathTableModel.addTableModelListener(parsePathTableListener);
setActionsEnabled(); notifyContextChanged();
} }
} }
@ -836,33 +861,30 @@ class ParseDialog extends ReusableDialogComponentProvider {
} }
private String[] expandPaths(String[] paths) { private String[] expandPaths(String[] paths) {
ArrayList<String> list = new ArrayList<>(); List<String> list = new ArrayList<>();
for (String path : paths) { for (String path : paths) {
File file = new File(path); File file = new File(path);
// process each header file in the directory // process each header file in the directory
if (file.isDirectory()) { if (!file.isDirectory()) {
IncludeFileFinder includeFileFinder = new IncludeFileFinder(file); list.add(path);
try { continue;
List<String> includeFileRoots = includeFileFinder.getIncludeFileRoots(true); }
for (Object element : includeFileRoots) {
String string = (String) element; IncludeFileFinder finder = new IncludeFileFinder(file);
if (string.endsWith(".h")) { try {
list.add(string); List<String> 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 { catch (IOException e) {
list.add(path); Msg.error(this, "Exception finding CParser paths", e);
} }
} }
// convert paths list to String[]
return list.toArray(new String[0]); 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() { private File getSaveFile() {
GhidraFileChooser fileChooser = new GhidraFileChooser(rootPanel); GhidraFileChooser fileChooser = new GhidraFileChooser(rootPanel);
@ -914,41 +928,44 @@ class ParseDialog extends ReusableDialogComponentProvider {
File file = fileChooser.getSelectedFile(); File file = fileChooser.getSelectedFile();
fileChooser.dispose(); fileChooser.dispose();
if (file != null) { if (file == null) {
File parent = file.getParentFile(); return null;
if (parent != null) { }
Preferences.setProperty(Preferences.LAST_EXPORT_DIRECTORY,
parent.getAbsolutePath());
}
String name = file.getName(); File parent = file.getParentFile();
if (!file.getName().endsWith(FileDataTypeManager.SUFFIX)) { if (parent != null) {
file = new File(file.getParentFile(), name + FileDataTypeManager.SUFFIX); Preferences.setProperty(Preferences.LAST_EXPORT_DIRECTORY,
} parent.getAbsolutePath());
if (file.exists()) { }
if (OptionDialog.showOptionDialog(rootPanel, "Overwrite Existing File?",
"The file " + file.getAbsolutePath() + String name = file.getName();
" already exists.\nDo you want to overwrite it?", if (!file.getName().endsWith(FileDataTypeManager.SUFFIX)) {
"Yes", OptionDialog.QUESTION_MESSAGE) != OptionDialog.OPTION_ONE) { file = new File(file.getParentFile(), name + FileDataTypeManager.SUFFIX);
file = null; }
}
else { if (!file.exists()) {
try { return file;
PackedDatabase.delete(file); }
}
catch (IOException e) { int choice = OptionDialog.showOptionDialog(rootPanel, "Overwrite Existing File?",
Msg.showError(this, mainPanel, "Archive Overwrite Failed", e.getMessage()); "The file " + file.getAbsolutePath() +
return null; " 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; return file;
} }
/**
* Called when user selects Cancel Button
*/
@Override @Override
protected void dismissCallback() { protected void dismissCallback() {
close(); close();
@ -1023,9 +1040,9 @@ class ParseDialog extends ReusableDialogComponentProvider {
} }
} }
//================================================================================================== //==================================================================================================
// Methods for Testing // Methods for Testing
//================================================================================================== //==================================================================================================
GhidraComboBox<ParseDialog.ComboBoxItem> getParseComboBox() { GhidraComboBox<ParseDialog.ComboBoxItem> getParseComboBox() {
return comboBox; return comboBox;
@ -1059,7 +1076,7 @@ class ParseDialog extends ReusableDialogComponentProvider {
return this.parseToFileButton; return this.parseToFileButton;
} }
ArrayList<ComboBoxItem> getProfiles() { List<ComboBoxItem> getProfiles() {
return this.itemList; return this.itemList;
} }

View file

@ -17,7 +17,6 @@ package docking;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.util.Set; import java.util.Set;
@ -622,10 +621,14 @@ public class ComponentProviderActionsTest extends AbstractGhidraHeadedIntegratio
} }
private void performLaunchKeyStrokeDialogAction() { private void performLaunchKeyStrokeDialogAction() {
ToolActions toolActions = (ToolActions) ((AbstractDockingTool) tool).getToolActions(); ToolActions toolActions = (ToolActions) tool.getToolActions();
Action action = toolActions.getAction(KeyStroke.getKeyStroke("F4")); Action action = toolActions.getAction(KeyStroke.getKeyStroke("F4"));
assertNotNull(action); 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() { private ToolOptions getKeyBindingOptions() {

View file

@ -17,11 +17,8 @@ package ghidra.app.plugin.core.cparser;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.awt.Window;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.List;
import javax.swing.JTextArea;
import org.junit.*; import org.junit.*;
@ -46,8 +43,6 @@ import utilities.util.FileUtilities;
public class ParseDialogParsingAndPromptsTest extends AbstractGhidraHeadedIntegrationTest { public class ParseDialogParsingAndPromptsTest extends AbstractGhidraHeadedIntegrationTest {
private static final String TITLE = "CParser Results Summary";
private TestEnv env; private TestEnv env;
private PluginTool tool; 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() { private ParseDialog showParseDialog() {
//ActionContext actionContext = cbPlugin.getProvider().getActionContext(null);
performAction(cparserAction, false); performAction(cparserAction, false);
ParseDialog parseDialog = waitForDialogComponent(ParseDialog.class); ParseDialog parseDialog = waitForDialogComponent(ParseDialog.class);
assertNotNull(parseDialog); assertNotNull(parseDialog);
return 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[]) { private void setIncludePaths(ParseDialog dialog, String paths[]) {
runSwing(() -> { runSwing(() -> {
PathnameTablePanel incPaths = dialog.getIncludePaths(); PathnameTablePanel incPaths = dialog.getIncludePaths();
@ -602,7 +553,7 @@ public class ParseDialogParsingAndPromptsTest extends AbstractGhidraHeadedIntegr
private void setSelectedParseProfile(ParseDialog dialog, String profileName) { private void setSelectedParseProfile(ParseDialog dialog, String profileName) {
runSwing(() -> { runSwing(() -> {
GhidraComboBox<ParseDialog.ComboBoxItem> parseComboBox = dialog.getParseComboBox(); GhidraComboBox<ParseDialog.ComboBoxItem> parseComboBox = dialog.getParseComboBox();
ArrayList<ComboBoxItem> profiles = dialog.getProfiles(); List<ComboBoxItem> profiles = dialog.getProfiles();
int index = 0; int index = 0;
for (ComboBoxItem comboBoxItem : profiles) { for (ComboBoxItem comboBoxItem : profiles) {
if (profileName.equals(comboBoxItem.getName())) { if (profileName.equals(comboBoxItem.getName())) {

View file

@ -344,7 +344,7 @@ public class ParseDialogTest extends AbstractGhidraHeadedIntegrationTest {
private void readDefaultParseProfileFile() throws Exception { private void readDefaultParseProfileFile() throws Exception {
StringBuffer buffy = new StringBuffer(); StringBuilder buffy = new StringBuilder();
List<String> pathList = new ArrayList<>(); List<String> pathList = new ArrayList<>();
ResourceFile profileFile = getPrfFile(); ResourceFile profileFile = getPrfFile();
@ -367,7 +367,6 @@ public class ParseDialogTest extends AbstractGhidraHeadedIntegrationTest {
buffy.append(line + "\n"); buffy.append(line + "\n");
} }
paths = pathList; paths = pathList;
defaultPrfOptions = buffy.toString(); defaultPrfOptions = buffy.toString();

View file

@ -17,7 +17,6 @@ package ghidra.app.tablechooser;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.util.*; import java.util.*;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
@ -456,10 +455,14 @@ public class TableChooserDialogTest extends AbstractGhidraHeadedIntegrationTest
} }
private void performLaunchKeyStrokeDialogAction() { private void performLaunchKeyStrokeDialogAction() {
ToolActions toolActions = (ToolActions) ((AbstractDockingTool) tool).getToolActions(); ToolActions toolActions = (ToolActions) tool.getToolActions();
Action action = toolActions.getAction(KeyStroke.getKeyStroke("F4")); Action action = toolActions.getAction(KeyStroke.getKeyStroke("F4"));
assertNotNull(action); 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) { private void setOptionsKeyStroke(DockingAction action, KeyStroke newKs) {

View file

@ -24,6 +24,7 @@ import javax.swing.table.TableModel;
import org.junit.*; import org.junit.*;
import docking.action.DockingAction;
import docking.action.DockingActionIf; import docking.action.DockingActionIf;
import docking.tool.ToolConstants; import docking.tool.ToolConstants;
import docking.widgets.table.GTableFilterPanel; import docking.widgets.table.GTableFilterPanel;
@ -95,10 +96,12 @@ public class ManagePluginsTest extends AbstractGhidraHeadedIntegrationTest {
@Test @Test
public void testActionEnablement() { public void testActionEnablement() {
performAction(managePluginsDialog.getSaveAction(), true); DockingAction saveAction = managePluginsDialog.getSaveAction();
performAction(saveAction, true);
assertFalse(saveAction.isEnabledForContext(managePluginsDialog.getActionContext(null)));
assertFalse(managePluginsDialog.getSaveAction().isEnabled()); DockingAction saveAsAction = managePluginsDialog.getSaveAsAction();
assertTrue(managePluginsDialog.getSaveAsAction().isEnabled()); assertTrue(saveAsAction.isEnabledForContext(managePluginsDialog.getActionContext(null)));
} }
@Test @Test
@ -144,7 +147,8 @@ public class ManagePluginsTest extends AbstractGhidraHeadedIntegrationTest {
waitForTasks(); waitForTasks();
assertTrue(tool.hasConfigChanged()); assertTrue(tool.hasConfigChanged());
assertTrue(managePluginsDialog.getSaveAction().isEnabled()); DockingAction action = managePluginsDialog.getSaveAction();
assertTrue(action.isEnabledForContext(managePluginsDialog.getActionContext(null)));
assertTrue( assertTrue(
pluginModel.isLoaded(PluginDescription.getPluginDescription(AboutProgramPlugin.class))); pluginModel.isLoaded(PluginDescription.getPluginDescription(AboutProgramPlugin.class)));
} }
@ -152,10 +156,11 @@ public class ManagePluginsTest extends AbstractGhidraHeadedIntegrationTest {
@Test @Test
public void testRemovePlugin() throws Exception { public void testRemovePlugin() throws Exception {
tool.setConfigChanged(false); tool.setConfigChanged(false);
SwingUtilities.invokeLater(() -> pluginManagerComponent.manageAllPlugins()); runSwingLater(() -> pluginManagerComponent.manageAllPlugins());
pluginModel.removePlugin(PluginDescription.getPluginDescription(EquateTablePlugin.class)); pluginModel.removePlugin(PluginDescription.getPluginDescription(EquateTablePlugin.class));
assertTrue(tool.hasConfigChanged()); assertTrue(tool.hasConfigChanged());
assertTrue(managePluginsDialog.getSaveAction().isEnabled()); DockingAction action = managePluginsDialog.getSaveAction();
assertTrue(action.isEnabledForContext(managePluginsDialog.getActionContext(null)));
assertFalse( assertFalse(
pluginModel.isLoaded(PluginDescription.getPluginDescription(AboutProgramPlugin.class))); pluginModel.isLoaded(PluginDescription.getPluginDescription(AboutProgramPlugin.class)));

View file

@ -120,8 +120,13 @@ public class ManagePluginsDialog extends ReusableDialogComponentProvider {
public void actionPerformed(ActionContext context) { public void actionPerformed(ActionContext context) {
save(); save();
} }
@Override
public boolean isEnabledForContext(ActionContext context) {
return tool.hasConfigChanged();
}
}; };
saveAction.setEnabled(tool.hasConfigChanged());
icon = Icons.SAVE_ICON; icon = Icons.SAVE_ICON;
String saveGroup = "save"; String saveGroup = "save";
saveAction.setMenuBarData(new MenuData(new String[] { "Save" }, icon, saveGroup)); saveAction.setMenuBarData(new MenuData(new String[] { "Save" }, icon, saveGroup));
@ -135,8 +140,12 @@ public class ManagePluginsDialog extends ReusableDialogComponentProvider {
public void actionPerformed(ActionContext context) { public void actionPerformed(ActionContext context) {
saveAs(); saveAs();
} }
@Override
public boolean isEnabledForContext(ActionContext context) {
return true;
}
}; };
saveAsAction.setEnabled(true);
icon = Icons.SAVE_AS_ICON; icon = Icons.SAVE_AS_ICON;
saveAsAction saveAsAction
.setMenuBarData(new MenuData(new String[] { "Save As..." }, icon, saveGroup)); .setMenuBarData(new MenuData(new String[] { "Save As..." }, icon, saveGroup));
@ -157,20 +166,18 @@ public class ManagePluginsDialog extends ReusableDialogComponentProvider {
} }
else { else {
tool.getToolServices().saveTool(tool); tool.getToolServices().saveTool(tool);
saveAction.setEnabled(false); tool.contextChanged(null);
} }
} }
private void saveAs() { private void saveAs() {
tool.saveToolAs(); tool.saveToolAs();
saveAction.setEnabled(tool.hasConfigChanged()); tool.contextChanged(null);
isNewTool = false; isNewTool = false;
} }
public void stateChanged() { public void stateChanged() {
if (saveAction != null) { tool.contextChanged(null);
saveAction.setEnabled(tool.hasConfigChanged());
}
} }
int getPackageCount() { int getPackageCount() {