GP-2986 - ComponentProvder and dialog cleanup on dispose

This commit is contained in:
dragonmacher 2023-02-02 17:51:15 -05:00
parent e5a8f26347
commit c252e3b905
174 changed files with 1418 additions and 1529 deletions

View file

@ -20,13 +20,13 @@ import java.util.Collection;
import javax.swing.*;
import docking.DialogComponentProvider;
import docking.ReusableDialogComponentProvider;
import docking.widgets.table.EnumeratedColumnTableModel;
import docking.widgets.table.GTable;
import ghidra.framework.plugintool.PluginTool;
import ghidra.util.table.GhidraTableFilterPanel;
public abstract class AbstractDebuggerMapProposalDialog<R> extends DialogComponentProvider {
public abstract class AbstractDebuggerMapProposalDialog<R> extends ReusableDialogComponentProvider {
protected final EnumeratedColumnTableModel<R> tableModel;
protected GTable table;

View file

@ -24,7 +24,7 @@ import javax.swing.*;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import docking.DialogComponentProvider;
import docking.ReusableDialogComponentProvider;
import docking.widgets.table.*;
import docking.widgets.table.ColumnSortState.SortDirection;
import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn;
@ -38,7 +38,7 @@ import ghidra.trace.model.memory.TraceMemoryRegion;
import ghidra.trace.model.modules.TraceSection;
import ghidra.util.table.GhidraTableFilterPanel;
public class DebuggerBlockChooserDialog extends DialogComponentProvider {
public class DebuggerBlockChooserDialog extends ReusableDialogComponentProvider {
public static class MemoryBlockRow {
private final Program program;
private final MemoryBlock block;

View file

@ -42,14 +42,10 @@ public abstract class DebuggerGoToTrait {
protected DebuggerCoordinates current = DebuggerCoordinates.NOWHERE;
protected final DebuggerGoToDialog goToDialog;
public DebuggerGoToTrait(PluginTool tool, Plugin plugin, ComponentProvider provider) {
this.tool = tool;
this.plugin = plugin;
this.provider = provider;
goToDialog = new DebuggerGoToDialog(this);
}
protected abstract boolean goToAddress(Address address);
@ -68,6 +64,7 @@ public abstract class DebuggerGoToTrait {
}
private void activatedGoTo(ActionContext context) {
DebuggerGoToDialog goToDialog = new DebuggerGoToDialog(this);
TracePlatform platform = current.getPlatform();
goToDialog.show((SleighLanguage) platform.getLanguage());
}

View file

@ -32,19 +32,10 @@ import ghidra.program.util.ProgramSelection;
import ghidra.trace.model.program.TraceProgramView;
import ghidra.trace.model.program.TraceVariableSnapProgramView;
@PluginInfo(
shortDescription = "Copy and export trace data",
description = "Provides tool actions for moving data from traces to various destinations.",
category = PluginCategoryNames.DEBUGGER,
packageName = DebuggerPluginPackage.NAME,
status = PluginStatus.RELEASED,
eventsConsumed = {},
eventsProduced = {},
servicesRequired = {
@PluginInfo(shortDescription = "Copy and export trace data", description = "Provides tool actions for moving data from traces to various destinations.", category = PluginCategoryNames.DEBUGGER, packageName = DebuggerPluginPackage.NAME, status = PluginStatus.RELEASED, eventsConsumed = {}, eventsProduced = {}, servicesRequired = {
DebuggerStaticMappingService.class,
ProgramManager.class,
},
servicesProvided = {})
}, servicesProvided = {})
public class DebuggerCopyActionsPlugin extends AbstractDebuggerPlugin {
protected static ProgramSelection getSelectionFromContext(ActionContext context) {
@ -75,6 +66,13 @@ public class DebuggerCopyActionsPlugin extends AbstractDebuggerPlugin {
createActions();
}
@Override
protected void dispose() {
super.dispose();
copyDialog.dispose();
}
protected void createActions() {
actionExportView = ExportTraceViewAction.builder(this)
.enabled(false)

View file

@ -27,7 +27,7 @@ import javax.swing.*;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import docking.DialogComponentProvider;
import docking.ReusableDialogComponentProvider;
import docking.widgets.table.*;
import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn;
import ghidra.app.plugin.core.debug.DebuggerCoordinates;
@ -52,7 +52,7 @@ import ghidra.util.exception.CancelledException;
import ghidra.util.table.GhidraTableFilterPanel;
import ghidra.util.task.*;
public class DebuggerCopyIntoProgramDialog extends DialogComponentProvider {
public class DebuggerCopyIntoProgramDialog extends ReusableDialogComponentProvider {
static final int GAP = 5;
static final int BUTTON_SIZE = 32;

View file

@ -24,19 +24,12 @@ import ghidra.app.services.*;
import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.util.PluginStatus;
@PluginInfo(
shortDescription = "Debugger regions manager",
description = "GUI to manage memory regions",
category = PluginCategoryNames.DEBUGGER,
packageName = DebuggerPluginPackage.NAME,
status = PluginStatus.RELEASED,
eventsConsumed = {
@PluginInfo(shortDescription = "Debugger regions manager", description = "GUI to manage memory regions", category = PluginCategoryNames.DEBUGGER, packageName = DebuggerPluginPackage.NAME, status = PluginStatus.RELEASED, eventsConsumed = {
ProgramActivatedPluginEvent.class,
ProgramLocationPluginEvent.class,
ProgramClosedPluginEvent.class,
TraceActivatedPluginEvent.class,
},
servicesRequired = {
}, servicesRequired = {
DebuggerModelService.class,
DebuggerStaticMappingService.class,
DebuggerTraceManagerService.class,
@ -58,6 +51,7 @@ public class DebuggerRegionsPlugin extends AbstractDebuggerPlugin {
@Override
protected void dispose() {
tool.removeComponentProvider(provider);
provider.dispose();
super.dispose();
}

View file

@ -204,6 +204,11 @@ public class DebuggerRegionsProvider extends ComponentProviderAdapter {
createActions();
}
void dispose() {
blockChooserDialog.dispose();
regionProposalDialog.dispose();
}
protected void buildMainPanel() {
panel = new DebuggerRegionsPanel(this);
mainPanel.add(panel);

View file

@ -23,7 +23,7 @@ import java.math.BigInteger;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import docking.DialogComponentProvider;
import docking.ReusableDialogComponentProvider;
import docking.widgets.model.GAddressRangeField;
import docking.widgets.model.GSpanField;
import ghidra.app.services.DebuggerStaticMappingService;
@ -36,7 +36,7 @@ import ghidra.trace.model.modules.TraceConflictedMappingException;
import ghidra.util.MathUtilities;
import ghidra.util.layout.PairLayout;
public class DebuggerAddMappingDialog extends DialogComponentProvider {
public class DebuggerAddMappingDialog extends ReusableDialogComponentProvider {
private static final String HEX_BIT64 = "0x" + BigInteger.ONE.shiftLeft(64).toString(16);
private DebuggerStaticMappingService mappingService;

View file

@ -418,7 +418,6 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
private final DebuggerBlockChooserDialog blockChooserDialog;
private final DebuggerModuleMapProposalDialog moduleProposalDialog;
private final DebuggerSectionMapProposalDialog sectionProposalDialog;
private DataTreeDialog programChooserDialog; // Already lazy
private DebuggerCoordinates current = DebuggerCoordinates.NOWHERE;
private Program currentProgram;
@ -470,6 +469,7 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
GhidraFileChooser chooser = new GhidraFileChooser(getComponent());
chooser.setSelectedFile(new File(module.getName()));
File file = chooser.getSelectedFile();
chooser.dispose();
if (file == null) { // Perhaps cancelled
return;
}
@ -511,6 +511,10 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
consoleService.removeResolutionAction(actionMapMissingModule);
}
}
blockChooserDialog.dispose();
moduleProposalDialog.dispose();
sectionProposalDialog.dispose();
}
@Override
@ -1071,14 +1075,11 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
}
private DataTreeDialog getProgramChooserDialog() {
if (programChooserDialog != null) {
return programChooserDialog;
}
DomainFileFilter filter = df -> Program.class.isAssignableFrom(df.getDomainObjectClass());
// TODO regarding the hack note below, I believe it's fixed, but not sure how to test
return programChooserDialog =
new DataTreeDialog(null, "Map Module to Program", DataTreeDialog.OPEN, filter) {
return new DataTreeDialog(null, "Map Module to Program", DataTreeDialog.OPEN, filter) {
{ // TODO/HACK: I get an NPE setting the default selection if I don't fake this.
dialogShown();
}
@ -1086,12 +1087,12 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
}
public DomainFile askProgram(Program program) {
getProgramChooserDialog();
DataTreeDialog dialog = getProgramChooserDialog();
if (program != null) {
programChooserDialog.selectDomainFile(program.getDomainFile());
dialog.selectDomainFile(program.getDomainFile());
}
tool.showDialog(programChooserDialog);
return programChooserDialog.getDomainFile();
tool.showDialog(dialog);
return dialog.getDomainFile();
}
public Entry<Program, MemoryBlock> askBlock(TraceSection section, Program program,

View file

@ -25,17 +25,10 @@ import ghidra.app.services.DebuggerTraceManagerService;
import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.util.PluginStatus;
@PluginInfo(
shortDescription = "Debugger static mapping manager",
description = "GUI to manage static mappings",
category = PluginCategoryNames.DEBUGGER,
packageName = DebuggerPluginPackage.NAME,
status = PluginStatus.RELEASED,
eventsConsumed = {
@PluginInfo(shortDescription = "Debugger static mapping manager", description = "GUI to manage static mappings", category = PluginCategoryNames.DEBUGGER, packageName = DebuggerPluginPackage.NAME, status = PluginStatus.RELEASED, eventsConsumed = {
TraceActivatedPluginEvent.class,
ProgramActivatedPluginEvent.class,
},
servicesRequired = {
}, servicesRequired = {
DebuggerStaticMappingService.class,
DebuggerTraceManagerService.class,
})
@ -55,6 +48,7 @@ public class DebuggerStaticMappingPlugin extends AbstractDebuggerPlugin {
@Override
protected void dispose() {
tool.removeComponentProvider(provider);
provider.dispose();
super.dispose();
}

View file

@ -176,6 +176,10 @@ public class DebuggerStaticMappingProvider extends ComponentProviderAdapter
createActions();
}
void dispose() {
addMappingDialog.dispose();
}
@AutoServiceConsumed
private void setMappingService(DebuggerStaticMappingService mappingService) {
addMappingDialog.setMappingService(mappingService);

View file

@ -132,9 +132,7 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter
@SuppressWarnings("unused")
private final AutoService.Wiring autoServiceWiring;
@AutoOptionDefined(
name = "Default Extended Step",
description = "The default string for the extended step command")
@AutoOptionDefined(name = "Default Extended Step", description = "The default string for the extended step command")
String extendedStep = "";
@SuppressWarnings("unused")
@ -244,6 +242,16 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter
repeatLastSet.run();
}
void dispose() {
// TODO This is not currently called, since the clients of this provider to not hold onto
// the provider after creation. Ideally, these providers should either be tracked and
// disposed, or this provider should perform cleanup on itself when it is no longer used.
configDialog.dispose();
methodDialog.dispose();
attachDialog.dispose();
breakpointDialog.dispose();
}
@Override
public void addLocalAction(DockingActionIf action) {
super.addLocalAction(action);

View file

@ -78,6 +78,7 @@ public abstract class ImportExportAsAction extends DockingAction {
chooser.setCurrentDirectory(Application.getUserSettingsDirectory());
File f = chooser.getSelectedFile();
chooser.dispose();
if (chooser.wasCancelled() || f == null) { // Redundant? Meh, it's cheap.
return;
}

View file

@ -15,8 +15,7 @@
*/
package ghidra.app.plugin.core.debug.gui.objects.components;
import static ghidra.app.plugin.core.debug.gui.DebuggerResources.GROUP_GENERAL;
import static ghidra.app.plugin.core.debug.gui.DebuggerResources.tableRowActivationAction;
import static ghidra.app.plugin.core.debug.gui.DebuggerResources.*;
import java.awt.BorderLayout;
import java.util.List;
@ -26,7 +25,7 @@ import java.util.concurrent.atomic.AtomicReference;
import javax.swing.*;
import docking.ActionContext;
import docking.DialogComponentProvider;
import docking.ReusableDialogComponentProvider;
import docking.action.ToolBarData;
import docking.widgets.table.*;
import ghidra.app.plugin.core.debug.gui.DebuggerResources.AbstractAttachAction;
@ -40,7 +39,7 @@ import ghidra.util.MessageType;
import ghidra.util.Msg;
import ghidra.util.table.GhidraTableFilterPanel;
public class DebuggerAttachDialog extends DialogComponentProvider {
public class DebuggerAttachDialog extends ReusableDialogComponentProvider {
protected class RefreshAction extends AbstractRefreshAction {
public static final String GROUP = GROUP_GENERAL;

View file

@ -26,7 +26,7 @@ import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import docking.ActionContext;
import docking.DialogComponentProvider;
import docking.ReusableDialogComponentProvider;
import docking.action.DockingAction;
import docking.widgets.table.DefaultEnumeratedColumnTableModel;
import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn;
@ -37,7 +37,7 @@ import ghidra.program.model.lang.Language;
import ghidra.program.model.lang.Register;
import ghidra.util.table.GhidraTableFilterPanel;
public class DebuggerAvailableRegistersDialog extends DialogComponentProvider {
public class DebuggerAvailableRegistersDialog extends ReusableDialogComponentProvider {
protected enum AvailableRegisterTableColumns
implements EnumeratedTableColumn<AvailableRegisterTableColumns, AvailableRegisterRow> {

View file

@ -553,6 +553,8 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
@Override
public void removeFromTool() {
availableRegsDialog.dispose();
plugin.providerRemoved(this);
plugin.getTool().removePopupActionProvider(this);
super.removeFromTool();
@ -1296,7 +1298,8 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
return AsyncUtils.NIL;
}
toRead.retainAll(regMapper.getRegistersOnTarget());
Set<TargetRegisterBank> banks = recorder.getTargetRegisterBanks(traceThread, current.getFrame());
Set<TargetRegisterBank> banks =
recorder.getTargetRegisterBanks(traceThread, current.getFrame());
if (banks == null || banks.isEmpty()) {
Msg.error(this, "Current frame's bank does not exist");
return AsyncUtils.NIL;

View file

@ -31,7 +31,7 @@ import javax.swing.text.View;
import org.apache.commons.collections4.BidiMap;
import org.apache.commons.collections4.bidimap.DualLinkedHashBidiMap;
import docking.DialogComponentProvider;
import docking.ReusableDialogComponentProvider;
import ghidra.app.plugin.core.debug.gui.DebuggerResources.AbstractConnectAction;
import ghidra.app.plugin.core.debug.utils.MiscellaneousUtils;
import ghidra.app.services.DebuggerModelService;
@ -45,7 +45,7 @@ import ghidra.program.model.listing.Program;
import ghidra.util.*;
import ghidra.util.datastruct.CollectionChangeListener;
public class DebuggerConnectDialog extends DialogComponentProvider
public class DebuggerConnectDialog extends ReusableDialogComponentProvider
implements PropertyChangeListener {
private static final String KEY_CURRENT_FACTORY_CLASSNAME = "currentFactoryCls";
private static final String KEY_SUCCESS_FACTORY_CLASSNAME = "successFactoryCls";

View file

@ -62,14 +62,7 @@ import ghidra.util.classfinder.ClassSearcher;
import ghidra.util.datastruct.CollectionChangeListener;
import ghidra.util.datastruct.ListenerSet;
@PluginInfo(
shortDescription = "Debugger models manager service",
description = "Manage debug sessions, connections, and trace recording",
category = PluginCategoryNames.DEBUGGER,
packageName = DebuggerPluginPackage.NAME,
status = PluginStatus.HIDDEN,
servicesRequired = {},
servicesProvided = {
@PluginInfo(shortDescription = "Debugger models manager service", description = "Manage debug sessions, connections, and trace recording", category = PluginCategoryNames.DEBUGGER, packageName = DebuggerPluginPackage.NAME, status = PluginStatus.HIDDEN, servicesRequired = {}, servicesProvided = {
DebuggerModelService.class, })
public class DebuggerModelServicePlugin extends Plugin
implements DebuggerModelServiceInternal, ApplicationLevelOnlyPlugin {
@ -184,6 +177,14 @@ public class DebuggerModelServicePlugin extends Plugin
createActions();
}
@Override
protected void dispose() {
super.dispose();
connectDialog.dispose();
offerDialog.dispose();
}
protected void createActions() {
actionDisconnectAll = DisconnectAllAction.builder(this, this)
.menuPath("Debugger", DisconnectAllAction.NAME)

View file

@ -23,7 +23,7 @@ import java.util.function.Function;
import javax.swing.*;
import docking.DialogComponentProvider;
import docking.ReusableDialogComponentProvider;
import docking.widgets.table.*;
import docking.widgets.table.ColumnSortState.SortDirection;
import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn;
@ -35,7 +35,7 @@ import ghidra.program.util.DefaultLanguageService;
import ghidra.util.table.GhidraTable;
import ghidra.util.table.GhidraTableFilterPanel;
public class DebuggerSelectMappingOfferDialog extends DialogComponentProvider {
public class DebuggerSelectMappingOfferDialog extends ReusableDialogComponentProvider {
protected enum OfferTableColumns
implements EnumeratedTableColumn<OfferTableColumns, DebuggerMappingOffer> {

View file

@ -66,24 +66,15 @@ import ghidra.util.datastruct.CollectionChangeListener;
import ghidra.util.exception.*;
import ghidra.util.task.*;
@PluginInfo(
shortDescription = "Debugger Trace View Management Plugin",
description = "Manages UI Components, Wrappers, Focus, etc.",
category = PluginCategoryNames.DEBUGGER,
packageName = DebuggerPluginPackage.NAME,
status = PluginStatus.RELEASED,
eventsProduced = {
@PluginInfo(shortDescription = "Debugger Trace View Management Plugin", description = "Manages UI Components, Wrappers, Focus, etc.", category = PluginCategoryNames.DEBUGGER, packageName = DebuggerPluginPackage.NAME, status = PluginStatus.RELEASED, eventsProduced = {
TraceActivatedPluginEvent.class,
},
eventsConsumed = {
}, eventsConsumed = {
TraceActivatedPluginEvent.class,
TraceClosedPluginEvent.class,
ModelObjectFocusedPluginEvent.class,
TraceRecorderAdvancedPluginEvent.class,
DebuggerPlatformPluginEvent.class,
},
servicesRequired = {},
servicesProvided = {
}, servicesRequired = {}, servicesProvided = {
DebuggerTraceManagerService.class,
})
public class DebuggerTraceManagerServicePlugin extends Plugin
@ -277,8 +268,6 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
@SuppressWarnings("unused")
private final AutoService.Wiring autoServiceWiring;
private DataTreeDialog traceChooserDialog;
DockingAction actionCloseTrace;
DockingAction actionCloseAllTraces;
DockingAction actionCloseOtherTraces;
@ -388,9 +377,7 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
}
protected DataTreeDialog getTraceChooserDialog() {
if (traceChooserDialog != null) {
return traceChooserDialog;
}
DomainFileFilter filter = new DomainFileFilter() {
@Override
@ -405,8 +392,7 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
};
// TODO regarding the hack note below, I believe this issue ahs been fixed, but not sure how to test
return traceChooserDialog =
new DataTreeDialog(null, OpenTraceAction.NAME, DataTreeDialog.OPEN, filter) {
return new DataTreeDialog(null, OpenTraceAction.NAME, DataTreeDialog.OPEN, filter) {
{ // TODO/HACK: Why the NPE if I don't do this?
dialogShown();
}
@ -414,12 +400,12 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
}
public DomainFile askTrace(Trace trace) {
getTraceChooserDialog();
DataTreeDialog dialog = getTraceChooserDialog();
if (trace != null) {
traceChooserDialog.selectDomainFile(trace.getDomainFile());
dialog.selectDomainFile(trace.getDomainFile());
}
tool.showDialog(traceChooserDialog);
return traceChooserDialog.getDomainFile();
tool.showDialog(dialog);
return dialog.getDomainFile();
}
@Override

View file

@ -24,7 +24,7 @@ import javax.swing.*;
import org.apache.commons.lang3.StringUtils;
import docking.DialogComponentProvider;
import docking.ReusableDialogComponentProvider;
import docking.action.DockingAction;
import docking.action.builder.ActionBuilder;
import docking.widgets.combobox.GComboBox;
@ -50,7 +50,7 @@ import ghidra.util.task.*;
* for learning function starts, train models, see performance statistics, and
* apply the models.
*/
public class FunctionStartRFParamsDialog extends DialogComponentProvider {
public class FunctionStartRFParamsDialog extends ReusableDialogComponentProvider {
private static final String INITIAL_BYTES_TEXT = "Number of Initial Bytes (CSV)";
private static final String INITIAL_BYTES_TIP =

View file

@ -96,6 +96,15 @@ public class RandomForestFunctionFinderPlugin extends ProgramPlugin
initOptions(getTool().getOptions("Random Forest Function Finder"));
}
@Override
protected void dispose() {
super.dispose();
if (paramsDialog != null) {
paramsDialog.dispose();
}
}
@Override
public void optionsChanged(ToolOptions options, String optionName, Object oldValue,
Object newValue) throws OptionsVetoException {

View file

@ -69,6 +69,7 @@ public class SampleTableProvider extends ComponentProviderAdapter implements Opt
void dispose() {
filterTable.dispose();
fileChooserPanel.dispose();
removeFromTool();
}

View file

@ -192,7 +192,6 @@ src/main/help/help/topics/DataTypeManagerPlugin/data_type_manager_archives.html|
src/main/help/help/topics/DataTypeManagerPlugin/data_type_manager_description.htm||GHIDRA||||END|
src/main/help/help/topics/DataTypeManagerPlugin/data_type_manager_window.html||GHIDRA||||END|
src/main/help/help/topics/DataTypeManagerPlugin/images/CommitDialog.png||GHIDRA||||END|
src/main/help/help/topics/DataTypeManagerPlugin/images/DataTypeConflict.png||GHIDRA||||END|
src/main/help/help/topics/DataTypeManagerPlugin/images/DataTypeManager.png||GHIDRA||||END|
src/main/help/help/topics/DataTypeManagerPlugin/images/DisassociateDialog.png||GHIDRA||||END|
src/main/help/help/topics/DataTypeManagerPlugin/images/EditPaths.png||GHIDRA||||END|

View file

@ -991,35 +991,6 @@
</BLOCKQUOTE>
<H3><A name="DataTypeConflicts"></A>Handling Data Type Conflicts</H3>
<BLOCKQUOTE>
<P>When you move or copy a data type to a category that has a data type with the same
name, a conflict occurs. If the data types are not the same, then a dialog is displayed
in order to resolve the conflict, as shown below:</P>
</BLOCKQUOTE>
<P align="center"><IMG src="images/DataTypeConflict.png" alt="" border="0"></P>
<BLOCKQUOTE>
<P>In this example, you dragged (or pasted) the data type "SIZE_T" from one category to
the /basetsd.h category; the one being dragged is different from the one that already
exists in the /basetsd.h category. The choices to resolve the conflict are:</P>
<OL>
<LI><I>Rename</I> the data type that you are dragging to have ".conflict" appended to
it to make a unique name.</LI>
<LI><I>Replace</I> the existing data type with the new one;
this means any use of the existing data types is <B><I>replaced</I></B> with the new
data type; the existing data type is deleted.</LI>
<LI>Use the existing data type; if you did a cut/paste or drag/move operation, the
"cut" or "dragged" data type is removed from its original category; the destination
category is unaffected.</LI>
</OL>
</BLOCKQUOTE>
<H3><A name="ReplaceDataType"></A>Replacing a Data Type</H3>
<BLOCKQUOTE>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View file

@ -20,9 +20,10 @@ import java.io.File;
import javax.swing.*;
import docking.DialogComponentProvider;
import docking.ReusableDialogComponentProvider;
import docking.widgets.OptionDialog;
import docking.widgets.filechooser.GhidraFileChooser;
import docking.widgets.filechooser.GhidraFileChooserMode;
import docking.widgets.label.GDLabel;
import ghidra.framework.GenericRunInfo;
import ghidra.framework.model.ProjectLocator;
@ -32,10 +33,9 @@ import ghidra.util.filechooser.GhidraFileChooserModel;
import ghidra.util.filechooser.GhidraFileFilter;
/**
* Dialog to prompt the user for the project to archive and the file to archive
* it to.
* Dialog to prompt the user for the project to archive and the file to archive it to.
*/
public class ArchiveDialog extends DialogComponentProvider {
public class ArchiveDialog extends ReusableDialogComponentProvider {
private static final int NUM_TEXT_COLUMNS = 40;
private boolean actionComplete;
@ -43,14 +43,12 @@ public class ArchiveDialog extends DialogComponentProvider {
private JTextField archiveField;
private JButton archiveBrowse;
private GhidraFileChooser jarFileChooser;
private ProjectLocator projectLocator;
private String archivePathName;
/**
* Constructor
*
* @param parent the parent frame of the NumberInputDialog.
* @param plugin the archive plugin using this dialog.
*/
ArchiveDialog(ArchivePlugin plugin) {
@ -179,6 +177,7 @@ public class ArchiveDialog extends DialogComponentProvider {
* Display this dialog.
* @param pProjectLocator the project URL to display when the dialog pops up.
* @param pArchivePathName the archive file name to display when the dialog pops up.
* @param tool the tool
*
* @return true if the user submitted valid values for the project and
* archive file, false if user cancelled.
@ -237,7 +236,7 @@ public class ArchiveDialog extends DialogComponentProvider {
File file = new File(pathname);
String name = file.getName();
if (!isValidName(name)) {
if (!NamingUtilities.isValidProjectName(name)) {
setStatusText("Archive name contains invalid characters.");
return false;
}
@ -256,8 +255,7 @@ public class ArchiveDialog extends DialogComponentProvider {
String filePathName) {
GhidraFileChooser fileChooser = new GhidraFileChooser(getComponent());
fileChooser.setFileSelectionMode(GhidraFileChooser.FILES_ONLY);
fileChooser.setFileSelectionMode(GhidraFileChooserMode.FILES_ONLY);
fileChooser.setFileFilter(new GhidraFileFilter() {
@Override
public boolean accept(File file, GhidraFileChooserModel model) {
@ -310,12 +308,12 @@ public class ArchiveDialog extends DialogComponentProvider {
* @param approveToolTip The tool tip for the "Open" button on the file chooser
* @return the archive file path.
*/
String chooseArchiveFile(String approveButtonText, String approveToolTip) {
if (jarFileChooser == null) {
jarFileChooser = createFileChooser(ArchivePlugin.ARCHIVE_EXTENSION, "Ghidra Archives",
private String chooseArchiveFile(String approveButtonText, String approveToolTip) {
GhidraFileChooser jarFileChooser =
createFileChooser(ArchivePlugin.ARCHIVE_EXTENSION, "Ghidra Archives",
archivePathName);
jarFileChooser.setTitle("Archive a Ghidra Project");
}
File jarFile = null;
if (archivePathName != null && archivePathName.length() != 0) {
jarFile = new File(archivePathName);
@ -338,7 +336,7 @@ public class ArchiveDialog extends DialogComponentProvider {
File file = selectedFile;
String chosenPathname = file.getAbsolutePath();
String name = file.getName();
if (!NamingUtilities.isValidName(name)) {
if (!NamingUtilities.isValidProjectName(name)) {
Msg.showError(getClass(), null, "Invalid Archive Name",
name + " is not a valid archive name");
continue;
@ -354,32 +352,7 @@ public class ArchiveDialog extends DialogComponentProvider {
pathname = chosenPathname;
}
jarFileChooser.dispose();
return pathname;
}
/**
* tests whether the given string is a valid name.
* @param name name to validate
*/
public boolean isValidName(String name) {
if (name == null) {
return false;
}
if ((name.length() < 1)) {
return false;
}
for (int i = 0; i < name.length(); i++) {
char c = name.charAt(i);
if (!Character.isLetterOrDigit(c) && c != '.' && c != '-' && c != ' ' && c != '_' &&
c != '\\' && c != '~' && c != '/' && c != ':') {
return false;
}
}
return true;
}
}

View file

@ -96,8 +96,6 @@ public class ArchivePlugin extends Plugin implements ApplicationLevelOnlyPlugin,
private TaskListener archivingListener;
private TaskListener restoringListener;
//////////////////////////////////////////////////////////////////
/**
* The archive plugin provides menu action from the front end allowing the
* user to archive a project or restore an archived project.
@ -112,36 +110,34 @@ public class ArchivePlugin extends Plugin implements ApplicationLevelOnlyPlugin,
@Override
public void dispose() {
super.dispose();
if (archiveDialog != null) {
archiveDialog.dispose();
}
if (restoreDialog != null) {
restoreDialog.dispose();
}
}
/////////////////////////////////////////////////////////////////////
/**
* @see ghidra.framework.model.ProjectListener#projectClosed(Project)
*/
@Override
public void projectClosed(Project project) {
archiveAction.setEnabled(false);
restoreAction.setEnabled(true);
}
/**
* @see ghidra.framework.model.ProjectListener#projectOpened(Project)
*/
@Override
public void projectOpened(Project project) {
archiveAction.setEnabled(true);
restoreAction.setEnabled(false);
}
/**
/*
* for JUnits...
*/
boolean isArchiving() {
return isArchiving;
}
/**
/*
* for JUnits...
*/
boolean isRestoring() {
@ -300,12 +296,6 @@ public class ArchivePlugin extends Plugin implements ApplicationLevelOnlyPlugin,
new TaskLauncher(task, tool.getToolFrame());
}
/**
* Return true if the jar file contains the JAR_FORMAT tag to indicate
* the new jar file format.
* @param jarFile
* @throws IOException
*/
private boolean isJarFormat(File jarFile) throws IOException {
JarInputStream jarIn = new JarInputStream(new FileInputStream(jarFile));
JarEntry entry = jarIn.getNextJarEntry();

View file

@ -22,8 +22,9 @@ import java.io.File;
import javax.swing.*;
import docking.DialogComponentProvider;
import docking.ReusableDialogComponentProvider;
import docking.widgets.filechooser.GhidraFileChooser;
import docking.widgets.filechooser.GhidraFileChooserMode;
import docking.widgets.label.GDLabel;
import ghidra.framework.GenericRunInfo;
import ghidra.framework.model.ProjectLocator;
@ -35,7 +36,7 @@ import ghidra.util.filechooser.ExtensionFileFilter;
* Dialog to prompt the user for the archive file to restore
* and where to restore it to.
*/
public class RestoreDialog extends DialogComponentProvider {
public class RestoreDialog extends ReusableDialogComponentProvider {
/**
* Preference name for directory last selected to choose a jar file
* to restore.
@ -54,14 +55,12 @@ public class RestoreDialog extends DialogComponentProvider {
private JButton restoreBrowse;
private JLabel projectNameLabel;
private JTextField projectNameField;
private GhidraFileChooser jarFileChooser;
private GhidraFileChooser dirChooser;
private String archivePathName;
private ProjectLocator restoreURL;
public RestoreDialog(ArchivePlugin plugin) {
super("Restore Project Archive", true);
super("Restore Project Archive");
this.plugin = plugin;
initialize();
@ -374,10 +373,9 @@ public class RestoreDialog extends DialogComponentProvider {
GhidraFileChooser fileChooser = new GhidraFileChooser(null);
// start the browsing in the user's preferred project directory
File projectDirectory = new File(GenericRunInfo.getProjectsDirPath());
fileChooser.setFileSelectionMode(GhidraFileChooser.DIRECTORIES_ONLY);
fileChooser.setFileSelectionMode(GhidraFileChooserMode.DIRECTORIES_ONLY);
fileChooser.setCurrentDirectory(projectDirectory);
fileChooser.setSelectedFile(projectDirectory);
return fileChooser;
}
@ -389,8 +387,9 @@ public class RestoreDialog extends DialogComponentProvider {
* @return the archive file path.
*/
String chooseArchiveFile(String approveButtonText, String approveToolTip) {
if (jarFileChooser == null) {
jarFileChooser = createFileChooser(ArchivePlugin.ARCHIVE_EXTENSION, "Ghidra Archives",
GhidraFileChooser jarFileChooser =
createFileChooser(ArchivePlugin.ARCHIVE_EXTENSION, "Ghidra Archives",
archivePathName);
jarFileChooser.setTitle("Restore a Ghidra Project - Archive");
String lastDirSelected = Preferences.getProperty(ArchivePlugin.LAST_ARCHIVE_DIR);
@ -400,7 +399,6 @@ public class RestoreDialog extends DialogComponentProvider {
jarFileChooser.setCurrentDirectory(file);
}
}
}
File jarFile = null;
if (archivePathName != null && archivePathName.length() != 0) {
jarFile = new File(archivePathName);
@ -419,7 +417,7 @@ public class RestoreDialog extends DialogComponentProvider {
File file = selectedFile;
String chosenName = file.getName();
if (!NamingUtilities.isValidName(chosenName)) {
if (!NamingUtilities.isValidProjectName(chosenName)) {
Msg.showError(getClass(), null, "Invalid Archive Name",
chosenName + " is not a valid archive name");
continue;
@ -428,6 +426,9 @@ public class RestoreDialog extends DialogComponentProvider {
Preferences.setProperty(ArchivePlugin.LAST_ARCHIVE_DIR, file.getParent());
pathname = file.getAbsolutePath();
}
jarFileChooser.dispose();
return pathname;
}
@ -439,10 +440,8 @@ public class RestoreDialog extends DialogComponentProvider {
* @return the restore directory file path.
*/
String chooseDirectory(String approveButtonText, String approveToolTip) {
if (dirChooser == null) {
dirChooser = createDirectoryChooser();
GhidraFileChooser dirChooser = createDirectoryChooser();
dirChooser.setTitle("Restore a Ghidra Project - Directory");
}
if (restoreURL != null) {
dirChooser.setSelectedFile(new File(restoreURL.getLocation()));
}
@ -450,6 +449,7 @@ public class RestoreDialog extends DialogComponentProvider {
dirChooser.setApproveButtonToolTipText(approveToolTip);
File selectedFile = dirChooser.getSelectedFile(true);
dirChooser.dispose();
if (selectedFile != null) {
return selectedFile.getAbsolutePath();
}

View file

@ -77,7 +77,6 @@ public class BookmarkPlugin extends ProgramPlugin
private BookmarkProvider provider;
private DockingAction addAction;
private DockingAction deleteAction;
private CreateBookmarkDialog createDialog;
private GoToService goToService;
private MarkerService markerService;
private BookmarkManager bookmarkMgr;
@ -206,10 +205,6 @@ public class BookmarkPlugin extends ProgramPlugin
provider.dispose();
provider = null;
}
if (createDialog != null) {
createDialog.dispose();
createDialog = null;
}
goToService = null;
disposeAllBookmarkers();
@ -444,7 +439,7 @@ public class BookmarkPlugin extends ProgramPlugin
return;
}
boolean hasSelection = currentSelection != null && !currentSelection.isEmpty();
createDialog = new CreateBookmarkDialog(this, currCU, hasSelection);
CreateBookmarkDialog createDialog = new CreateBookmarkDialog(this, currCU, hasSelection);
tool.showDialog(createDialog);
}

View file

@ -46,22 +46,11 @@ public class ClearPlugin extends Plugin {
private static final String CLEAR_CODE_BYTES_NAME = "Clear Code Bytes";
private static final String CLEAR_FLOW_AND_REPAIR = "Clear Flow and Repair";
private ClearDialog clearDialog;
private ClearFlowDialog clearFlowDialog;
/**
* Constructor
*/
public ClearPlugin(PluginTool tool) {
super(tool);
createActions();
}
// /////////////////////////////////////////////////////////////////////
/**
* Clear the flow and repair disassembly at the current location
*/
void clearFlowAndRepair(ListingActionContext context, boolean clearSymbols, boolean clearData,
boolean repair) {
ClearFlowAndRepairCmd cmd;
@ -76,10 +65,6 @@ public class ClearPlugin extends Plugin {
tool.executeBackgroundCommand(cmd, context.getProgram());
}
/**
* Use the options to determine what must be cleared. Starts a new thread if
* necessary to do the work. Called by the actions and by the dialog.
*/
void clear(ClearOptions options, ListingActionContext context) {
if (!options.clearAny()) {
return;
@ -258,13 +243,12 @@ public class ClearPlugin extends Plugin {
clear(opts, context);
}
/**
* Pop up the clear with options dialog.
*/
private void showClearAllDialog(ListingActionContext programActionContext) {
if (clearDialog == null) {
clearDialog = new ClearDialog(this);
}
ClearDialog clearDialog = new ClearDialog(this);
clearDialog.setProgramActionContext(programActionContext);
tool.showDialog(clearDialog);
}
@ -273,9 +257,7 @@ public class ClearPlugin extends Plugin {
* Pop up the clear flows dialog
*/
private void showClearFlowDialog(ListingActionContext context) {
if (clearFlowDialog == null) {
clearFlowDialog = new ClearFlowDialog(this);
}
ClearFlowDialog clearFlowDialog = new ClearFlowDialog(this);
clearFlowDialog.setProgramActionContext(context);
tool.showDialog(clearFlowDialog);
}

View file

@ -38,7 +38,7 @@ import ghidra.util.HelpLocation;
/**
* Dialog for setting the comments for a CodeUnit.
*/
public class CommentsDialog extends DialogComponentProvider implements KeyListener {
public class CommentsDialog extends ReusableDialogComponentProvider implements KeyListener {
private JTextArea eolField;
private JTextArea preField;

View file

@ -58,7 +58,6 @@ public class CommentsPlugin extends Plugin implements OptionsChangeListener {
private DockingAction deleteAction;
private DockingAction historyAction;
private CommentsDialog dialog;
private CommentHistoryDialog historyDialog;
private DockingAction preCommentEditAction;
private DockingAction postCommentEditAction;
@ -76,6 +75,12 @@ public class CommentsPlugin extends Plugin implements OptionsChangeListener {
initializeOptions(tool.getOptions("Comments"));
}
@Override
protected void dispose() {
super.dispose();
dialog.dispose();
}
@Override
public void optionsChanged(ToolOptions options, String optionName, Object oldValue,
Object newValue) {
@ -223,9 +228,7 @@ public class CommentsPlugin extends Plugin implements OptionsChangeListener {
private void showCommentHistory(ListingActionContext context) {
CodeUnit cu = context.getCodeUnit();
ProgramLocation loc = context.getLocation();
if (historyDialog == null) {
historyDialog = new CommentHistoryDialog();
}
CommentHistoryDialog historyDialog = new CommentHistoryDialog();
historyDialog.showDialog(cu, CommentType.getCommentType(null, loc, CodeUnit.EOL_COMMENT),
tool, context);
}
@ -238,13 +241,16 @@ public class CommentsPlugin extends Plugin implements OptionsChangeListener {
}
if (loc instanceof FunctionRepeatableCommentFieldLocation) {
action.getPopupMenuData().setMenuPath(
new String[] { "Comments", actionString + " Repeatable Comment" + endString });
action.getPopupMenuData()
.setMenuPath(
new String[] { "Comments",
actionString + " Repeatable Comment" + endString });
return;
}
if (loc instanceof PlateFieldLocation) {
action.getPopupMenuData().setMenuPath(
action.getPopupMenuData()
.setMenuPath(
new String[] { "Comments", actionString + " Plate Comment" + endString });
return;
}
@ -253,23 +259,29 @@ public class CommentsPlugin extends Plugin implements OptionsChangeListener {
int type = cfLoc.getCommentType();
switch (type) {
case CodeUnit.PRE_COMMENT:
action.getPopupMenuData().setMenuPath(
action.getPopupMenuData()
.setMenuPath(
new String[] { "Comments", actionString + " Pre-Comment" + endString });
break;
case CodeUnit.POST_COMMENT:
action.getPopupMenuData().setMenuPath(
new String[] { "Comments", actionString + " Post-Comment" + endString });
action.getPopupMenuData()
.setMenuPath(
new String[] { "Comments",
actionString + " Post-Comment" + endString });
break;
case CodeUnit.EOL_COMMENT:
action.getPopupMenuData().setMenuPath(
action.getPopupMenuData()
.setMenuPath(
new String[] { "Comments", actionString + " EOL Comment" + endString });
break;
case CodeUnit.REPEATABLE_COMMENT:
action.getPopupMenuData().setMenuPath(
new String[] { "Comments", actionString + " Repeatable Comment" + endString });
action.getPopupMenuData()
.setMenuPath(
new String[] { "Comments",
actionString + " Repeatable Comment" + endString });
break;
}
}

View file

@ -150,6 +150,7 @@ public abstract class CompositeEditorProvider extends ComponentProviderAdapter
editorModel.endFieldEditing();
}
if (saveChanges(true) != 0) {
super.closeComponent();
dispose();
}
}

View file

@ -59,7 +59,7 @@ import resources.Icons;
*
*
*/
class ParseDialog extends DialogComponentProvider {
class ParseDialog extends ReusableDialogComponentProvider {
final static String PROFILE_DIR = "parserprofiles";
private static String FILE_EXTENSION = ".prf";
@ -89,11 +89,10 @@ class ParseDialog extends DialogComponentProvider {
private ArrayList<ComboBoxItem> itemList;
private ComboBoxItemComparator comparator;
private ResourceFile parentUserFile;
private GhidraFileChooser fileChooser;
private boolean saveAsInProgress;
ParseDialog(CParserPlugin plugin) {
super("Parse C Source", false);
super("Parse C Source", false, true, true, false);
this.plugin = plugin;
itemList = new ArrayList<>();
@ -157,7 +156,7 @@ class ParseDialog extends DialogComponentProvider {
pathPanel.setBorder(BorderFactory.createTitledBorder("Source files to parse"));
String importDir = Preferences.getProperty(LAST_IMPORT_C_DIRECTORY);
if (importDir == null) {
importDir = Preferences.getProperty(Preferences.LAST_IMPORT_DIRECTORY);
importDir = Preferences.getProperty(Preferences.LAST_PATH_DIRECTORY);
if (importDir != null) {
Preferences.setProperty(LAST_IMPORT_C_DIRECTORY, importDir);
}
@ -625,19 +624,15 @@ class ParseDialog extends DialogComponentProvider {
}
private File getSaveFile() {
if (fileChooser == null) {
fileChooser = new GhidraFileChooser(rootPanel);
String dir = Preferences.getProperty(Preferences.LAST_EXPORT_DIRECTORY);
if (dir != null) {
File file = new File(dir);
fileChooser.setCurrentDirectory(file);
GhidraFileChooser fileChooser = new GhidraFileChooser(rootPanel);
fileChooser.setTitle("Choose Save Archive File");
fileChooser.setApproveButtonText("Choose Save Archive File");
fileChooser.setApproveButtonToolTipText("Choose filename for archive");
}
}
fileChooser.rescanCurrentDirectory();
fileChooser.setLastDirectoryPreference(Preferences.LAST_EXPORT_DIRECTORY);
File file = fileChooser.getSelectedFile();
fileChooser.dispose();
if (file != null) {
File parent = file.getParentFile();
if (parent != null) {

View file

@ -42,14 +42,9 @@ class CreateStructureAction extends ListingContextAction {
private DataPlugin plugin;
private CreateStructureDialog createStructureDialog;
/**
* Constructor
* @param name action name
* @param owner owner of this action (the plugin name)
*/
public CreateStructureAction(DataPlugin plugin) {
super("Create Structure", plugin.getName());
// ACTIONS - auto generated
setPopupMenuData(new MenuData(CREATE_STRUCTURE_POPUP_MENU, null, "BasicData"));
setKeyBindingData(new KeyBindingData(KeyEvent.VK_OPEN_BRACKET, InputEvent.SHIFT_DOWN_MASK));

View file

@ -28,7 +28,7 @@ import javax.swing.table.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import docking.DialogComponentProvider;
import docking.ReusableDialogComponentProvider;
import docking.widgets.button.GRadioButton;
import docking.widgets.table.*;
import generic.theme.GThemeDefaults.Colors;
@ -48,7 +48,7 @@ import ghidra.util.table.GhidraTableFilterPanel;
*
*
*/
public class CreateStructureDialog extends DialogComponentProvider {
public class CreateStructureDialog extends ReusableDialogComponentProvider {
private static final String NEW_STRUCTURE_STATUS_PREFIX = "Creating new structure: ";
private static final String EXISITING_STRUCTURE_STATUS_PREFIX = "Using existing structure: ";

View file

@ -35,11 +35,9 @@ import ghidra.program.util.ProgramLocation;
class RenameDataFieldAction extends ListingContextAction {
private DataPlugin plugin;
private RenameDataFieldDialog dialog;
public RenameDataFieldAction(DataPlugin plugin) {
super("Rename Data Field", plugin.getName());
dialog = new RenameDataFieldDialog(plugin);
setPopupMenuData(
new MenuData(
@ -54,7 +52,8 @@ class RenameDataFieldAction extends ListingContextAction {
@Override
protected void actionPerformed(ListingActionContext context) {
ListingActionContext programActionContext = (ListingActionContext) context.getContextObject();
ListingActionContext programActionContext =
(ListingActionContext) context.getContextObject();
PluginTool tool = plugin.getTool();
Program program = programActionContext.getProgram();
ProgramLocation loc = programActionContext.getLocation();
@ -67,14 +66,17 @@ class RenameDataFieldAction extends ListingContextAction {
for (int i = 0; i < compPath.length - 1; i++) {
DataTypeComponent subComp = comp.getComponent(compPath[i]);
type = subComp.getDataType();
if (type instanceof Composite)
if (type instanceof Composite) {
comp = (Composite) type;
else
}
else {
return;
}
}
Data instance = data.getComponent(compPath);
DataTypeComponent subComp = comp.getComponent(compPath[compPath.length - 1]);
RenameDataFieldDialog dialog = new RenameDataFieldDialog(plugin);
dialog.setDataComponent(program, subComp, instance.getFieldName());
tool.showDialog(dialog, tool.getComponentProvider(PluginConstants.CODE_BROWSER));
}

View file

@ -17,7 +17,6 @@ package ghidra.app.plugin.core.datamgr;
import java.awt.Component;
import java.awt.datatransfer.Clipboard;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.*;
@ -95,7 +94,6 @@ public class DataTypeManagerPlugin extends ProgramPlugin
private DataTypeManagerHandler dataTypeManagerHandler;
private DataTypesProvider provider;
private OpenVersionedFileDialog<DataTypeArchive> openDialog;
private Map<String, DockingAction> recentlyOpenedArchiveMap;
private Map<String, DockingAction> installArchiveMap;
@ -366,19 +364,10 @@ public class DataTypeManagerPlugin extends ProgramPlugin
newProvider.setIncludeDataTypeMembersInFilter(provider.includeDataMembersInSearch());
newProvider.setFilteringArrays(provider.isFilteringArrays());
newProvider.setFilteringPointers(provider.isFilteringPointers());
newProvider.setTransient();
return newProvider;
}
public void closeProvider(DataTypesProvider providerToClose) {
if (providerToClose != provider) {
providerToClose.removeFromTool(); // remove any transient providers when closed
providerToClose.dispose();
}
else {
provider.setVisible(false);
}
}
public Program getProgram() {
return currentProgram;
}
@ -574,25 +563,24 @@ public class DataTypeManagerPlugin extends ProgramPlugin
}
public void openProjectDataTypeArchive() {
if (openDialog == null) {
ActionListener listener = ev -> {
DomainFile domainFile = openDialog.getDomainFile();
int version = openDialog.getVersion();
if (domainFile == null) {
openDialog.setStatusText("Please choose a Project Data Type Archive");
}
else {
openDialog.close();
openArchive(domainFile, version);
}
};
openDialog =
OpenVersionedFileDialog<DataTypeArchive> dialog =
new OpenVersionedFileDialog<>(tool, "Open Project Data Type Archive",
DataTypeArchive.class);
openDialog.setHelpLocation(new HelpLocation(HelpTopics.PROGRAM, "Open_File_Dialog"));
openDialog.addOkActionListener(listener);
dialog.setHelpLocation(new HelpLocation(HelpTopics.PROGRAM, "Open_File_Dialog"));
dialog.addOkActionListener(ev -> {
DomainFile domainFile = dialog.getDomainFile();
int version = dialog.getVersion();
if (domainFile == null) {
dialog.setStatusText("Please choose a Project Data Type Archive");
}
tool.showDialog(openDialog);
else {
dialog.close();
openArchive(domainFile, version);
}
});
tool.showDialog(dialog);
}
@Override

View file

@ -42,7 +42,6 @@ public class DataTypeSyncDialog extends DialogComponentProvider implements DataT
private DataTypeComparePanel comparePanel;
private final String operationName;
private boolean cancelled;
private List<DataTypeSyncInfo> selectedInfos = Collections.emptyList();
public DataTypeSyncDialog(DataTypeManagerPlugin plugin, String clientName, String sourceName,
@ -118,7 +117,6 @@ public class DataTypeSyncDialog extends DialogComponentProvider implements DataT
@Override
protected void cancelCallback() {
cancelled = true;
close();
}

View file

@ -114,6 +114,11 @@ public class DataTypesProvider extends ComponentProviderAdapter {
createLocalActions();
}
@Override // overridden to open access
protected void setTransient() {
super.setTransient();
}
/**
* This creates all the actions for opening/creating data type archives.
* It also creates the action for refreshing the built-in data types
@ -358,7 +363,10 @@ public class DataTypesProvider extends ComponentProviderAdapter {
@Override // overridden to handle special logic in plugin
public void closeComponent() {
plugin.closeProvider(this);
super.closeComponent();
if (isTransient()) {
dispose();
}
}
private void buildComponent() {

View file

@ -51,6 +51,7 @@ public class CreateArchiveAction extends DockingAction {
Msg.trace(this, "Showing filechooser to get new archive name...");
File file = fileChooser.promptUserForFile("New_Archive");
fileChooser.dispose();
if (file == null) {
Msg.trace(this, "No new archive filename chosen by user - not performing action");
return;

View file

@ -176,6 +176,8 @@ public class ExportToHeaderAction extends DockingAction {
new DataTypeWriterTask(gTree, programDataTypeMgr, dataTypeList, handler, file),
gTree);
}
fileChooser.dispose();
}
private class DataTypeWriterTask extends Task {
@ -209,7 +211,8 @@ public class ExportToHeaderAction extends DockingAction {
finally {
writer.close();
}
plugin.getTool().setStatusInfo(
plugin.getTool()
.setStatusInfo(
"Successfully exported data type(s) to " + file.getAbsolutePath());
}
catch (CancelledException e) {

View file

@ -67,6 +67,7 @@ public class OpenArchiveAction extends DockingAction {
DataTypeManagerHandler manager = plugin.getDataTypeManagerHandler();
File file = fileChooser.getSelectedFile();
fileChooser.dispose();
if (file == null) {
return;
}

View file

@ -119,7 +119,7 @@ public class ArchiveUtils {
ArchiveFileChooser fileChooser = new ArchiveFileChooser(component);
String archiveName = archive.getName();
File file = fileChooser.promptUserForFile(archiveName);
fileChooser.dispose();
if (file == null) {
return null;
}

View file

@ -73,8 +73,6 @@ public class DataTypeManagerHandler {
private Set<String> knownOpenFileArchiveNames = new HashSet<>();
private Map<UniversalID, InvalidFileArchive> invalidArchives = new HashMap<>();
private DataTreeDialog dataTreeSaveDialog;
private CreateDataTypeArchiveDataTreeDialog dataTreeCreateDialog;
private boolean treeDialogCancelled = false;
private DomainFileFilter createArchiveFileFilter;
@ -1409,77 +1407,74 @@ public class DataTypeManagerHandler {
}
private DataTreeDialog getSaveDialog() {
if (dataTreeSaveDialog == null) {
DataTreeDialog dialog =
new DataTreeDialog(null, "Save As", DataTreeDialog.SAVE, createArchiveFileFilter);
ActionListener listener = event -> {
DomainFolder folder = dataTreeSaveDialog.getDomainFolder();
String newName = dataTreeSaveDialog.getNameText();
DomainFolder folder = dialog.getDomainFolder();
String newName = dialog.getNameText();
if (newName.length() == 0) {
dataTreeSaveDialog.setStatusText("Please enter a name");
dialog.setStatusText("Please enter a name");
return;
}
else if (folder == null) {
dataTreeSaveDialog.setStatusText("Please select a folder");
dialog.setStatusText("Please select a folder");
return;
}
DomainFile file = folder.getFile(newName);
if (file != null && file.isReadOnly()) {
dataTreeSaveDialog.setStatusText("Read Only. Choose new name/folder");
dialog.setStatusText("Read Only. Choose new name/folder");
}
else {
dataTreeSaveDialog.close();
dialog.close();
treeDialogCancelled = false;
}
};
dataTreeSaveDialog =
new DataTreeDialog(null, "Save As", DataTreeDialog.SAVE, createArchiveFileFilter);
dataTreeSaveDialog.addOkActionListener(listener);
dataTreeSaveDialog
.setHelpLocation(new HelpLocation(HelpTopics.PROGRAM, "Save_As_File"));
}
return dataTreeSaveDialog;
dialog.addOkActionListener(listener);
dialog.setHelpLocation(new HelpLocation(HelpTopics.PROGRAM, "Save_As_File"));
return dialog;
}
private CreateDataTypeArchiveDataTreeDialog getCreateDialog() {
if (dataTreeCreateDialog == null) {
CreateDataTypeArchiveDataTreeDialog dialog =
new CreateDataTypeArchiveDataTreeDialog(null, "Create",
DataTreeDialog.CREATE, createArchiveFileFilter);
ActionListener listener = event -> {
DomainFolder folder = dataTreeCreateDialog.getDomainFolder();
String newName = dataTreeCreateDialog.getNameText();
DomainFolder folder = dialog.getDomainFolder();
String newName = dialog.getNameText();
if (newName.length() == 0) {
dataTreeCreateDialog.setStatusText("Please enter a name");
dialog.setStatusText("Please enter a name");
return;
}
else if (folder == null) {
dataTreeCreateDialog.setStatusText("Please select a folder");
dialog.setStatusText("Please select a folder");
return;
}
DomainFile file = folder.getFile(newName);
if (file != null) {
dataTreeCreateDialog.setStatusText("Choose a name that doesn't exist.");
dialog.setStatusText("Choose a name that doesn't exist.");
return;
}
if (!dataTreeCreateDialog.createNewDataTypeArchive()) {
if (!dialog.createNewDataTypeArchive()) {
return;
}
// everything is OK
dataTreeCreateDialog.close();
dialog.close();
treeDialogCancelled = false;
};
dataTreeCreateDialog = new CreateDataTypeArchiveDataTreeDialog(null, "Create",
DataTreeDialog.CREATE, createArchiveFileFilter);
dataTreeCreateDialog.addOkActionListener(listener);
dataTreeCreateDialog.setHelpLocation(
dialog.addOkActionListener(listener);
dialog.setHelpLocation(
new HelpLocation(HelpTopics.DATA_MANAGER, "Create_Data_Type_Archive"));
}
return dataTreeCreateDialog;
return dialog;
}
public DataTypeManager getDataTypeManager(SourceArchive source) {
@ -1520,14 +1515,14 @@ public class DataTypeManagerHandler {
return true;
}
catch (DuplicateNameException e) {
dataTreeCreateDialog.setStatusText("Duplicate Name: " + e.getMessage());
setStatusText("Duplicate Name: " + e.getMessage());
}
catch (InvalidNameException e) {
dataTreeCreateDialog.setStatusText("Invalid Name: " + e.getMessage());
setStatusText("Invalid Name: " + e.getMessage());
}
catch (IOException e) {
dataTreeCreateDialog.setStatusText("Unexpected IOException!");
Msg.showError(null, dataTreeCreateDialog.getComponent(), "Unexpected Exception",
setStatusText("Unexpected IOException!");
Msg.showError(null, getComponent(), "Unexpected Exception",
e.getMessage(), e);
}

View file

@ -1,150 +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 ghidra.app.plugin.core.datamgr.util;
import java.awt.BorderLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.*;
import docking.DialogComponentProvider;
import docking.widgets.button.GRadioButton;
import docking.widgets.label.GIconLabel;
import docking.widgets.label.GLabel;
import generic.theme.GIcon;
import ghidra.util.HelpLocation;
/**
* Dialog to get user input on how to handle data type conflicts.
*/
public class ConflictDialog extends DialogComponentProvider {
final static int REPLACE = 1;
final static int USE_EXISTING = 2;
final static int RENAME = 3;
private boolean applyToAll;
private JRadioButton replaceRB;
private JRadioButton useExistingRB;
private JRadioButton renameRB;
private JButton applyToAllButton;
private int selectedOption = RENAME;
private Icon INFORM_ICON = new GIcon("icon.warning");
/**
* Constructor
* @param dtName data type name
* @param categoryPath category path
* @param newDTName new name to resolve conflict
*/
public ConflictDialog(String dtName, String categoryPath, String newDTName) {
super("Data Type Conflict for " + dtName);
setHelpLocation(new HelpLocation("DataManagerPlugin", "DataTypeConflicts"));
addWorkPanel(buildMainPanel(dtName, categoryPath, newDTName));
addOKButton();
applyToAllButton = new JButton("Apply to All");
applyToAllButton.addActionListener(e -> {
applyToAll = true;
close();
});
addButton(applyToAllButton);
}
@Override
protected void okCallback() {
close();
}
@Override
protected void cancelCallback() {
close();
}
int getSelectedOption() {
return selectedOption;
}
boolean applyChoiceToAll() {
return applyToAll;
}
private JPanel buildMainPanel(String dtName, String categoryPath, String newDTName) {
JPanel outerPanel = new JPanel(new BorderLayout(20, 0));
outerPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
JPanel mainPanel = new JPanel();
mainPanel.setBorder(BorderFactory.createTitledBorder("Resolve Data Type Conflict"));
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
ItemListener listener = e -> {
if (e.getStateChange() == ItemEvent.SELECTED) {
Object source = e.getSource();
if (source == replaceRB) {
selectedOption = REPLACE;
}
else if (source == useExistingRB) {
selectedOption = USE_EXISTING;
}
else {
selectedOption = RENAME;
}
}
};
ButtonGroup bg = new ButtonGroup();
renameRB = new GRadioButton("Rename new data type to " + newDTName, true);
replaceRB = new GRadioButton("Replace existing data type");
useExistingRB = new GRadioButton("Use existing data type");
renameRB.addItemListener(listener);
useExistingRB.addItemListener(listener);
replaceRB.addItemListener(listener);
bg.add(renameRB);
bg.add(replaceRB);
bg.add(useExistingRB);
mainPanel.add(Box.createVerticalStrut(5));
mainPanel.add(renameRB);
mainPanel.add(replaceRB);
mainPanel.add(useExistingRB);
outerPanel.add(createLabelPanel(dtName, categoryPath), BorderLayout.NORTH);
outerPanel.add(mainPanel, BorderLayout.CENTER);
return outerPanel;
}
private JPanel createLabelPanel(String dtName, String categoryPath) {
JPanel labelPanel = new JPanel();
labelPanel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 20));
BoxLayout bl = new BoxLayout(labelPanel, BoxLayout.X_AXIS);
labelPanel.setLayout(bl);
labelPanel.add(Box.createHorizontalStrut(5));
labelPanel.add(new GIconLabel(INFORM_ICON));
labelPanel.add(Box.createHorizontalStrut(5));
labelPanel.add(new GLabel("Conflict exists in " + categoryPath + " for " + dtName));
JPanel panel = new JPanel(new BorderLayout());
panel.add(labelPanel);
panel.setBorder(BorderFactory.createEmptyBorder(0, 0, 20, 0));
return panel;
}
}

View file

@ -219,7 +219,6 @@ public class DataWindowPlugin extends ProgramPlugin implements DomainObjectListe
filterAction.addType(type.getDisplayName());
}
filterAction.selectTypes(selectedList);
filterAction.repaint();
provider.reload();
}
}

View file

@ -52,8 +52,6 @@ class FilterAction extends ToggleDockingAction {
private boolean viewMode = false;
private boolean selectionMode = false;
private FilterDialog dialog;
private static class SortMapComparatorASC implements Comparator<String> {
@Override
@ -82,10 +80,7 @@ class FilterAction extends ToggleDockingAction {
@Override
public void actionPerformed(ActionContext context) {
if (dialog == null) {
dialog = new FilterDialog();
}
FilterDialog dialog = new FilterDialog();
dialog.setSelectionEnabled(plugin.getSelection() != null);
dialog.updateButtonEnabledState();
plugin.getTool().showDialog(dialog);
@ -93,19 +88,11 @@ class FilterAction extends ToggleDockingAction {
synchronized void clearTypes() {
typeEnabledMap.clear();
if (dialog != null) {
dialog.clearTypes();
}
}
synchronized void addType(String type) {
Boolean bool = new Boolean(!filterEnabled);
Boolean bool = !filterEnabled;
typeEnabledMap.put(type, bool);
if (dialog != null) {
dialog.createCheckBox(type, type, bool.booleanValue());
}
}
synchronized boolean typeEnabled(String type) {
@ -137,16 +124,6 @@ class FilterAction extends ToggleDockingAction {
for (String element : list) {
typeEnabledMap.put(element, Boolean.TRUE);
}
if (dialog != null) {
dialog.selectTypes(list);
}
}
void repaint() {
if (dialog == null) {
return;
}
dialog.repaint();
}
boolean getViewMode() {
@ -170,7 +147,6 @@ class FilterAction extends ToggleDockingAction {
filterEnabled = false;
viewMode = false;
selectionMode = false;
dialog = null;
setEnabled(false);
clearTypes();
}

View file

@ -23,7 +23,7 @@ import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import docking.DialogComponentProvider;
import docking.ReusableDialogComponentProvider;
import docking.action.DockingAction;
import docking.widgets.checkbox.GCheckBox;
import docking.widgets.label.GDLabel;
@ -39,7 +39,7 @@ import ghidra.util.table.*;
import ghidra.util.table.actions.MakeProgramSelectionAction;
import ghidra.util.task.Task;
public class AddressTableDialog extends DialogComponentProvider {
public class AddressTableDialog extends ReusableDialogComponentProvider {
private static final int DEFAULT_MINIMUM_TABLE_SIZE = 3;
private static final String DIALOG_NAME = "Search For Address Tables";

View file

@ -44,9 +44,9 @@ public class TextEditorComponentProvider extends ComponentProviderAdapter {
private static final String TITLE = "Text Editor";
private static final String FONT_ID = "font.plugin.service.text.editor";
private static final int MAX_UNDO_REDO_SIZE = 50;
private static final String LAST_SAVED_TEXT_FILE_DIR = "LastSavedTextFileDirectory";
private TextEditorManagerPlugin plugin;
private GhidraFileChooser chooser;
private File textFile;
private String textFileName;
private DockingAction saveAction;
@ -146,17 +146,13 @@ public class TextEditorComponentProvider extends ComponentProviderAdapter {
}
private String loadTextFile(InputStream inputStream) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
try {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
return loadTextFile(reader);
}
finally {
reader.close();
}
}
private String loadTextFile(BufferedReader reader) throws IOException {
StringBuffer buffer = new StringBuffer();
StringBuilder buffer = new StringBuilder();
while (true) {
String line = reader.readLine();
if (line == null) {
@ -290,21 +286,25 @@ public class TextEditorComponentProvider extends ComponentProviderAdapter {
}
catch (IOException e) {
if (textFile.canWrite()) {
Msg.showError(getClass(), getComponent(), "Error saving file", e.getMessage());
Msg.showError(getClass(), getComponent(), "Error Saving File",
"Unable to save file", e);
}
else {
Msg.showError(getClass(), getComponent(), "Error Saving File",
"The file is not writable.");
"The file is not writable");
}
}
}
}
private void saveAs() {
if (chooser == null) {
chooser = new GhidraFileChooser(getComponent());
}
GhidraFileChooser chooser = new GhidraFileChooser(getComponent());
chooser.setLastDirectoryPreference(LAST_SAVED_TEXT_FILE_DIR);
File saveAsFile = chooser.getSelectedFile();
chooser.dispose();
if (saveAsFile == null) {
return;
}
@ -344,6 +344,7 @@ public class TextEditorComponentProvider extends ComponentProviderAdapter {
public void closeComponent() {
if (plugin.removeTextFile(this, textFileName)) {
clearUndoRedoStack();
super.closeComponent();
plugin.getTool().removeComponentProvider(this);
}
}

View file

@ -269,6 +269,7 @@ public class ExporterDialog extends DialogComponentProvider implements AddressFa
setLastExportDirectory(file);
filePathTextField.setText(file.getAbsolutePath());
}
chooser.dispose();
}
private void setLastExportDirectory(File file) {

View file

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,18 +15,17 @@
*/
package ghidra.app.plugin.core.function;
import ghidra.app.util.PluginConstants;
import ghidra.framework.plugintool.PluginTool;
import java.awt.BorderLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.*;
import docking.DialogComponentProvider;
import docking.ReusableDialogComponentProvider;
import ghidra.app.util.PluginConstants;
import ghidra.framework.plugintool.PluginTool;
abstract class CommentDialog extends DialogComponentProvider {
abstract class CommentDialog extends ReusableDialogComponentProvider {
private JTextArea commentsField;
private boolean applyWasDone;

View file

@ -173,8 +173,7 @@ public class FunctionPlugin extends Plugin implements DataService {
* Add the cycle group actions
*/
private void addCycleGroupActions() {
for (int i = 0; i < cgActions.size(); i++) {
DockingAction action = cgActions.get(i);
for (CycleGroupAction action : cgActions) {
tool.removeAction(action);
}
cgActions.clear();

View file

@ -60,16 +60,12 @@ class VariableCommentAction extends ListingContextAction {
return;
}
VariableCommentDialog dialog = funcPlugin.getVariableCommentDialog();
if (dialog == null) {
dialog = new VariableCommentDialog(funcPlugin);
}
dialog.showDialog(function.getProgram(), var);
}
/////////////////////////////////////////////////////////////
/**
* Get a variable using the current location.
* @param function
* @param function the function
* @return null if function is null or if current location is not
* a stack variable location.
*/

View file

@ -15,15 +15,14 @@
*/
package ghidra.app.plugin.core.help;
import java.util.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.Transferable;
import java.util.*;
import javax.swing.*;
import docking.ActionContext;
import docking.DialogComponentProvider;
import docking.ReusableDialogComponentProvider;
import docking.action.DockingAction;
import docking.action.MenuData;
import docking.dnd.GClipboard;
@ -70,6 +69,10 @@ public class ProcessorListPlugin extends Plugin implements ApplicationLevelPlugi
public void dispose() {
tool.removeAction(processorListAction);
processorListAction.dispose();
if (dialogProvider != null) {
dialogProvider.dispose();
}
super.dispose();
}
@ -154,7 +157,7 @@ public class ProcessorListPlugin extends Plugin implements ApplicationLevelPlugi
return strBuilder.toString();
}
class ProcessorListDialogProvider extends DialogComponentProvider {
class ProcessorListDialogProvider extends ReusableDialogComponentProvider {
ProcessorListDialogProvider() {
super("Installed Processor Modules", false, false, true, false);

View file

@ -94,6 +94,16 @@ public class InstructionSearchPlugin extends ProgramPlugin {
createActions();
}
@Override
protected void dispose() {
super.dispose();
if (searchDialog != null) {
searchDialog.dispose();
}
}
public InstructionSearchDialog getSearchDialog() {
return searchDialog;
}

View file

@ -25,7 +25,7 @@ import java.util.List;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import docking.DialogComponentProvider;
import docking.ReusableDialogComponentProvider;
import generic.theme.GThemeDefaults.Colors.Messages;
import ghidra.app.plugin.core.instructionsearch.model.*;
import ghidra.app.plugin.core.instructionsearch.ui.SelectionModeWidget.InputMode;
@ -43,7 +43,7 @@ import ghidra.util.SystemUtilities;
* will then be disassembled and displayed in the {@link InstructionTable}.
*
*/
public class InsertBytesWidget extends DialogComponentProvider implements KeyListener {
public class InsertBytesWidget extends ReusableDialogComponentProvider implements KeyListener {
// The input text area. This is a generic JTextArea but displays a textual 'hint' to inform
// the user of what type of input is required.

View file

@ -22,7 +22,7 @@ import java.util.*;
import javax.swing.*;
import docking.ComponentProvider;
import docking.DialogComponentProvider;
import docking.ReusableDialogComponentProvider;
import generic.theme.GColor;
import generic.theme.GThemeDefaults.Colors.Messages;
import ghidra.app.events.ProgramSelectionPluginEvent;
@ -61,7 +61,7 @@ import ghidra.util.task.TaskMonitor;
* ------------------------------------
*/
public class InstructionSearchDialog extends DialogComponentProvider implements Observer {
public class InstructionSearchDialog extends ReusableDialogComponentProvider implements Observer {
private static final Color BG_COLOR_MARKERS =
new GColor("color.bg.plugin.instructionsearch.search.markers");

View file

@ -41,12 +41,6 @@ public class InstructionTablePanel extends JPanel {
private JPanel workPanel;
/**
*
* @param numColumns
* @param plugin
* @param dialog
*/
public InstructionTablePanel(int numColumns, InstructionSearchPlugin plugin,
InstructionSearchDialog dialog) {
@ -74,11 +68,6 @@ public class InstructionTablePanel extends JPanel {
return workPanel;
}
/*********************************************************************************************
* PRIVATE METHODS
* @throws InvalidInputException
********************************************************************************************/
private void setup() throws InvalidInputException {
workPanel = new JPanel();

View file

@ -49,9 +49,7 @@ import ghidra.util.Msg;
//@formatter:on
public class LabelMgrPlugin extends Plugin {
private OperandLabelDialog operandDialog;
private AddEditDialog addEditDialog;
private EditFieldNameDialog editFieldDialog;
/**
* Constructor
@ -62,6 +60,8 @@ public class LabelMgrPlugin extends Plugin {
super(tool);
// Setup list of actions
setupActions();
addEditDialog = new AddEditDialog("", tool);
}
private void setupActions() {
@ -88,25 +88,21 @@ public class LabelMgrPlugin extends Plugin {
tool.addAction(allHistoryAction);
}
AddEditDialog getAddEditDialog() {
if (addEditDialog == null) {
addEditDialog = new AddEditDialog("", tool);
@Override
protected void dispose() {
addEditDialog.dispose();
}
AddEditDialog getAddEditDialog() {
return addEditDialog;
}
EditFieldNameDialog getEditFieldDialog() {
if (editFieldDialog == null) {
editFieldDialog = new EditFieldNameDialog("", tool);
}
return editFieldDialog;
return new EditFieldNameDialog("", tool);
}
OperandLabelDialog getOperandLabelDialog() {
if (operandDialog == null) {
operandDialog = new OperandLabelDialog(this);
}
return operandDialog;
return new OperandLabelDialog(this);
}
/**

View file

@ -614,8 +614,11 @@ class MemoryMapProvider extends ComponentProviderAdapter {
else {
model = new ExpandBlockDownModel(tool, program);
}
ExpandBlockDialog dialog =
new ExpandBlockDialog(tool, model, block, program.getAddressFactory(), dialogType);
model.initialize(block);
dialog.dispose();
}
private void showMoveBlockDialog(MemoryBlock block) {

View file

@ -16,7 +16,6 @@
package ghidra.app.plugin.core.memory;
import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
@ -54,12 +53,6 @@ class SplitBlockDialog extends DialogComponentProvider {
private AddressFactory addrFactory;
private MemoryMapPlugin plugin;
/**
* Constructor
* @param parent
* @param block
* @param af
*/
SplitBlockDialog(MemoryMapPlugin plugin, MemoryBlock block, AddressFactory af) {
super("Split Block");
this.plugin = plugin;
@ -74,9 +67,6 @@ class SplitBlockDialog extends DialogComponentProvider {
addListeners();
}
/**
* @see ghidra.util.bean.GhidraDialog#okCallback()
*/
@Override
protected void okCallback() {
// call plugin to do the work
@ -195,12 +185,7 @@ class SplitBlockDialog extends DialogComponentProvider {
blockOneEnd.addChangeListener(new AddressChangeListener(blockOneEnd));
blockTwoStart.addChangeListener(new AddressChangeListener(blockTwoStart));
ActionListener al = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setStatusText("");
}
};
ActionListener al = e -> setStatusText("");
blockOneLengthField.addActionListener(al);
blockTwoLengthField.addActionListener(al);
blockOneEnd.addActionListener(al);

View file

@ -366,6 +366,7 @@ public class LocationReferencesProvider extends ComponentProviderAdapter
@Override
public void closeComponent() {
super.closeComponent();
locationReferencesPlugin.providerDismissed(this);
}

View file

@ -60,7 +60,6 @@ public class BundleStatusComponentProvider extends ComponentProviderAdapter {
private final BundleStatusTableModel bundleStatusTableModel;
private GTableFilterPanel<BundleStatus> filterPanel;
private GhidraFileChooser fileChooser;
private GhidraFileFilter filter;
private final BundleHost bundleHost;
private transient boolean isDisposed;
@ -94,7 +93,6 @@ public class BundleStatusComponentProvider extends ComponentProviderAdapter {
return GhidraBundle.getType(file) != GhidraBundle.Type.INVALID;
}
};
this.fileChooser = null;
build();
addToTool();
@ -249,8 +247,8 @@ public class BundleStatusComponentProvider extends ComponentProviderAdapter {
}
private void showAddBundlesFileChooser() {
if (fileChooser == null) {
fileChooser = new GhidraFileChooser(getComponent());
GhidraFileChooser fileChooser = new GhidraFileChooser(getComponent());
fileChooser.setMultiSelectionEnabled(true);
fileChooser.setFileSelectionMode(GhidraFileChooserMode.FILES_AND_DIRECTORIES);
fileChooser.setTitle("Select Bundle(s)");
@ -273,15 +271,6 @@ public class BundleStatusComponentProvider extends ComponentProviderAdapter {
File lastSelectedFile = new File(lastSelected);
fileChooser.setSelectedFile(lastSelectedFile);
}
}
else {
String lastSelected = Preferences.getProperty(PREFERENCE_LAST_SELECTED_BUNDLE);
if (lastSelected != null) {
File lastSelectedFile = new File(lastSelected);
fileChooser.setSelectedFile(lastSelectedFile);
}
fileChooser.rescanCurrentDirectory();
}
List<File> files = fileChooser.getSelectedFiles();
if (!files.isEmpty()) {
@ -304,6 +293,8 @@ public class BundleStatusComponentProvider extends ComponentProviderAdapter {
}
});
}
fileChooser.dispose();
}
protected List<BundleStatus> getSelectedStatuses() {

View file

@ -69,7 +69,6 @@ public class AddressTypeOverviewColorService
private Listing listing;
private OverviewColorComponent overviewComponent;
private PluginTool tool;
private DialogComponentProvider legendDialog;
private AddressTypeOverviewLegendPanel legendPanel;
@Override
@ -336,12 +335,12 @@ public class AddressTypeOverviewColorService
}
private DialogComponentProvider getLegendDialog() {
if (legendDialog == null) {
if (legendPanel == null) {
legendPanel = new AddressTypeOverviewLegendPanel(this);
legendDialog =
new OverviewColorLegendDialog("Overview Legend", legendPanel, getHelpLocation());
}
OverviewColorLegendDialog legendDialog =
new OverviewColorLegendDialog("Overview Legend", legendPanel, getHelpLocation());
return legendDialog;
}

View file

@ -45,7 +45,6 @@ public class EntropyOverviewColorService implements OverviewColorService {
private OverviewPalette palette;
private EntropyOverviewOptionsManager entropyOptionsManager;
private OverviewColorComponent overviewComponent;
private OverviewColorLegendDialog legendDialog;
@Override
public String getName() {
@ -193,9 +192,6 @@ public class EntropyOverviewColorService implements OverviewColorService {
if (overviewComponent != null) {
overviewComponent.refreshAll();
}
if (legendDialog != null) {
legendDialog.refresh();
}
}
@Override
@ -219,12 +215,11 @@ public class EntropyOverviewColorService implements OverviewColorService {
}
private DialogComponentProvider getLegendDialog() {
if (legendDialog == null) {
LegendPanel legendPanel = new LegendPanel();
legendPanel.setPalette(palette);
legendDialog =
OverviewColorLegendDialog legendDialog =
new OverviewColorLegendDialog("Entropy Legend", legendPanel, getHelpLocation());
}
return legendDialog;
}
}

View file

@ -20,13 +20,13 @@ import java.awt.event.*;
import javax.swing.*;
import docking.DialogComponentProvider;
import docking.ReusableDialogComponentProvider;
import docking.widgets.button.GRadioButton;
import docking.widgets.checkbox.GCheckBox;
import generic.theme.Gui;
import ghidra.util.HelpLocation;
public class PrintOptionsDialog extends DialogComponentProvider {
public class PrintOptionsDialog extends ReusableDialogComponentProvider {
private static final String FONT_ID = "font.print";
private boolean selectionEnabled;

View file

@ -76,6 +76,15 @@ public class PrintingPlugin extends ProgramPlugin {
cvService = tool.getService(CodeViewerService.class);
}
@Override
protected void dispose() {
super.dispose();
if (pod != null) {
pod.dispose();
}
}
@Override
protected void programActivated(Program program) {
printAction.setEnabled(true);

View file

@ -16,7 +16,6 @@
package ghidra.app.plugin.core.progmgr;
import java.awt.Component;
import java.awt.event.ActionListener;
import java.beans.PropertyEditor;
import java.net.MalformedURLException;
import java.net.URL;
@ -83,12 +82,13 @@ public class ProgramManagerPlugin extends Plugin implements ProgramManager {
private MultiProgramManager programMgr;
private ProgramSaveManager programSaveMgr;
private int transactionID = -1;
private OpenVersionedFileDialog<Program> openDialog;
private boolean locked = false;
private UndoAction undoAction;
private RedoAction redoAction;
private ProgramLocation currentLocation;
private OpenVersionedFileDialog<Program> openDialog;
public ProgramManagerPlugin(PluginTool tool) {
super(tool);
@ -297,6 +297,9 @@ public class ProgramManagerPlugin extends Plugin implements ProgramManager {
public void dispose() {
programMgr.dispose();
tool.clearLastEvents();
if (openDialog != null) {
openDialog.dispose();
}
}
@Override
@ -567,6 +570,7 @@ public class ProgramManagerPlugin extends Plugin implements ProgramManager {
});
dialog.setHelpLocation(new HelpLocation(HelpTopics.PROGRAM, "Program_Options"));
tool.showDialog(dialog);
dialog.dispose();
}
/**
@ -605,8 +609,12 @@ public class ProgramManagerPlugin extends Plugin implements ProgramManager {
}
private void open() {
if (openDialog == null) {
ActionListener listener = e -> {
openDialog = new OpenVersionedFileDialog<>(tool, "Open Program", Program.class);
openDialog.setHelpLocation(new HelpLocation(HelpTopics.PROGRAM, "Open_File_Dialog"));
openDialog.addOkActionListener(e -> {
DomainFile domainFile = openDialog.getDomainFile();
int version = openDialog.getVersion();
if (domainFile == null) {
@ -616,11 +624,9 @@ public class ProgramManagerPlugin extends Plugin implements ProgramManager {
openDialog.close();
doOpenProgram(domainFile, version, OPEN_CURRENT);
}
};
openDialog = new OpenVersionedFileDialog<>(tool, "Open Program", Program.class);
openDialog.setHelpLocation(new HelpLocation(HelpTopics.PROGRAM, "Open_File_Dialog"));
openDialog.addOkActionListener(listener);
});
}
tool.showDialog(openDialog);
contextChanged();
}

View file

@ -38,7 +38,6 @@ import ghidra.util.task.*;
class ProgramSaveManager {
private ProgramManager programMgr;
private PluginTool tool;
private DataTreeDialog dataTreeSaveDialog;
private boolean treeDialogCancelled;
private DomainFileFilter domainFileFilter;
@ -450,37 +449,35 @@ class ProgramSaveManager {
}
private DataTreeDialog getSaveDialog() {
if (dataTreeSaveDialog == null) {
DataTreeDialog dialog =
new DataTreeDialog(null, "Save As", DataTreeDialog.SAVE, domainFileFilter);
ActionListener listener = event -> {
DomainFolder folder = dataTreeSaveDialog.getDomainFolder();
String newName = dataTreeSaveDialog.getNameText();
DomainFolder folder = dialog.getDomainFolder();
String newName = dialog.getNameText();
if (newName.length() == 0) {
dataTreeSaveDialog.setStatusText("Please enter a name");
dialog.setStatusText("Please enter a name");
return;
}
else if (folder == null) {
dataTreeSaveDialog.setStatusText("Please select a folder");
dialog.setStatusText("Please select a folder");
return;
}
DomainFile file = folder.getFile(newName);
if (file != null && file.isReadOnly()) {
dataTreeSaveDialog.setStatusText("Read Only. Choose new name/folder");
dialog.setStatusText("Read Only. Choose new name/folder");
}
else {
dataTreeSaveDialog.close();
dialog.close();
treeDialogCancelled = false;
}
};
dataTreeSaveDialog =
new DataTreeDialog(null, "Save As", DataTreeDialog.SAVE, domainFileFilter);
dataTreeSaveDialog.addOkActionListener(listener);
dataTreeSaveDialog.setHelpLocation(
new HelpLocation(HelpTopics.PROGRAM, "Save_As_File"));
}
return dataTreeSaveDialog;
dialog.addOkActionListener(listener);
dialog.setHelpLocation(new HelpLocation(HelpTopics.PROGRAM, "Save_As_File"));
return dialog;
}
class SaveFileTask extends Task {

View file

@ -19,12 +19,11 @@ import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.jdom.Element;
import docking.DialogComponentProvider;
import docking.ReusableDialogComponentProvider;
import docking.widgets.button.GRadioButton;
import ghidra.framework.options.SaveState;
import ghidra.program.model.address.Address;
@ -35,7 +34,7 @@ import ghidra.program.model.symbol.Reference;
import ghidra.util.HelpLocation;
import ghidra.util.exception.AssertException;
public class EditReferenceDialog extends DialogComponentProvider {
public class EditReferenceDialog extends ReusableDialogComponentProvider {
static final int PREFERRED_PANEL_HEIGHT = 190;
static final int PREFERRED_PANEL_WIDTH = 450;
@ -63,7 +62,7 @@ public class EditReferenceDialog extends DialogComponentProvider {
private boolean initializing;
public EditReferenceDialog(ReferencesPlugin plugin) {
super("Edit Reference", true);
super("Edit Reference");
this.plugin = plugin;
addWorkPanel(buildMainPanel());
addApplyButton();
@ -72,17 +71,12 @@ public class EditReferenceDialog extends DialogComponentProvider {
setDefaultButton(applyButton);
}
/**
* Dispose of this dialog.
*/
@Override
public void dispose() {
close();
cleanup();
}
/**
* Returns the current code unit displayed.
*/
CodeUnit getCurrentCodeUnit() {
return instrPanel.getCurrentCodeUnit();
}
@ -120,9 +114,7 @@ public class EditReferenceDialog extends DialogComponentProvider {
JPanel refTypePanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 5));
refTypePanel.setBorder(new TitledBorder(new EtchedBorder(), "Type of Reference"));
ChangeListener refChoiceListener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
ChangeListener refChoiceListener = e -> {
Object src = e.getSource();
if (src instanceof JRadioButton) {
JRadioButton refChoiceButton = (JRadioButton) src;
@ -130,7 +122,6 @@ public class EditReferenceDialog extends DialogComponentProvider {
refChoiceActivated(refChoiceButton);
}
}
}
};
memRefChoice = new GRadioButton("Memory");

View file

@ -101,6 +101,7 @@ public class ResourceActionsPlugin extends Plugin {
chooser.setApproveButtonText("Save Image As");
chooser.addFileFilter(GRAPHIC_FORMATS_FILTER);
File f = chooser.getSelectedFile();
chooser.dispose();
if (f != null) {
if (f.exists() && OptionDialog.showYesNoDialog(tool.getActiveWindow(),
"Overwrite Existing File?",
@ -146,6 +147,7 @@ public class ResourceActionsPlugin extends Plugin {
chooser.setApproveButtonText("Save Image As");
chooser.addFileFilter(GRAPHIC_FORMATS_FILTER);
File f = chooser.getSelectedFile();
chooser.dispose();
if (f != null) {
if (f.exists() && OptionDialog.showYesNoDialog(tool.getActiveWindow(),
"Overwrite Existing File?",

View file

@ -628,11 +628,15 @@ public class GhidraScriptEditorComponentProvider extends ComponentProvider {
}
private void closeComponentSavingAsNecessary() {
provider.removeScriptEditor(scriptSourceFile, true);
if (provider.removeScriptEditor(scriptSourceFile, true)) {
super.closeComponent();
}
}
private void closeComponentWithoutSaving() {
provider.removeScriptEditor(scriptSourceFile, false);
if (provider.removeScriptEditor(scriptSourceFile, false)) {
super.closeComponent();
}
}
@Override

View file

@ -50,7 +50,7 @@ import ghidra.util.task.Task;
* backward searching, proper endianness and whether to find just
* the next occurrence or all of them in the program.
*/
class MemSearchDialog extends DialogComponentProvider {
class MemSearchDialog extends ReusableDialogComponentProvider {
static final String ADVANCED_BUTTON_NAME = "mem.search.advanced";
private static final String CODE_UNIT_SCOPE_NAME = "Code Unit Scope";

View file

@ -39,7 +39,7 @@ import ghidra.util.task.TaskMonitorComponent;
/**
* Dialog for showing options to search text in a Program.
*/
class SearchTextDialog extends DialogComponentProvider {
class SearchTextDialog extends ReusableDialogComponentProvider {
private static final int DEFAULT_MAX_ENTRIES = 10;

View file

@ -179,16 +179,19 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
navigatable = null;
if (searchDialog != null && searchDialog.isVisible()) {
if (searchDialog != null) {
if (searchDialog.isVisible()) {
TaskMonitor taskMonitor = searchDialog.getTaskMonitorComponent();
taskMonitor.cancel();
searchDialog.dispose();
if (searchAllTaskMonitor != null) {
searchAllTaskMonitor.cancel();
}
}
searchDialog.dispose();
}
if (currentTask != null) {
currentTask.cancel();
}

View file

@ -16,14 +16,12 @@
package ghidra.app.plugin.core.select;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.math.BigInteger;
import javax.swing.*;
import docking.ComponentProvider;
import docking.DialogComponentProvider;
import docking.ReusableDialogComponentProvider;
import docking.widgets.button.GRadioButton;
import docking.widgets.label.GLabel;
import docking.widgets.textfield.IntegerTextField;
@ -39,7 +37,7 @@ import ghidra.util.layout.PairLayout;
* Class to set up dialog box that will enable the user
* to set the available options for block selection
*/
class SelectBlockDialog extends DialogComponentProvider {
class SelectBlockDialog extends ReusableDialogComponentProvider {
private static final String OVERFLOW_SELECTION_WARNING =
"Selection is larger than available " + "bytes, using the end of the address space";
@ -53,7 +51,7 @@ class SelectBlockDialog extends DialogComponentProvider {
private PluginTool tool;
SelectBlockDialog(PluginTool tool, Navigatable navigatable) {
super("Select Bytes", false);
super("Select Bytes", false, true, true, false);
this.tool = tool;
this.navigatable = navigatable;
// navigatable.addNavigatableListener(this);
@ -113,46 +111,34 @@ class SelectBlockDialog extends DialogComponentProvider {
forwardButton = new GRadioButton("Select Forward", true);
forwardButton.setName("forwardButton");
forwardButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
forwardButton.addActionListener(ae -> {
setStatusText("Enter number of bytes to select");
setAddressFieldEnabled(false);
setLengthInputEnabled(true);
}
});
buttonGroup.add(forwardButton);
backwardButton = new GRadioButton("Select Backward");
backwardButton.setName("backwardButton");
backwardButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
backwardButton.addActionListener(ae -> {
setStatusText("Enter number of bytes to select");
setAddressFieldEnabled(false);
setLengthInputEnabled(true);
}
});
buttonGroup.add(backwardButton);
allButton = new GRadioButton("Select All");
allButton.setName("allButton");
allButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
allButton.addActionListener(ae -> {
setItemsEnabled(false);
clearStatusText();
}
});
buttonGroup.add(allButton);
toButton = new GRadioButton("To Address");
toButton.setName("toButton");
toButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
toButton.addActionListener(ae -> {
setStatusText("Enter an Address to go to");
setAddressFieldEnabled(true);
setLengthInputEnabled(false);
}
});
buttonGroup.add(toButton);
gbc.gridx = 0;
@ -298,7 +284,6 @@ class SelectBlockDialog extends DialogComponentProvider {
Address currentAddress = navigatable.getLocation().getAddress();
length *= currentAddress.getAddressSpace().getAddressableUnitSize();
AddressFactory addressFactory = navigatable.getProgram().getAddressFactory();
AddressSet addressSet = new AddressSet(navigatable.getSelection());
if (addressSet.isEmpty()) {
addressSet.addRange(currentAddress, currentAddress);
@ -361,12 +346,7 @@ class SelectBlockDialog extends DialogComponentProvider {
}
private void showWarningDialog(final String text) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JOptionPane.showMessageDialog(getComponent(), text);
}
});
SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(getComponent(), text));
}
public void setNavigatable(Navigatable navigatable) {

View file

@ -57,6 +57,15 @@ public class SelectBlockPlugin extends Plugin {
createActions();
}
@Override
protected void dispose() {
super.dispose();
if (dialog != null) {
dialog.dispose();
}
}
private void createActions() {
toolBarAction = new NavigatableContextAction("SelectBlock", getName()) {

View file

@ -16,8 +16,6 @@
package ghidra.app.plugin.core.string;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
@ -231,15 +229,14 @@ public class SearchStringDialog extends DialogComponentProvider {
// Set up a file chooser that allows the user to select a new *.sng file.
JButton browseButton = new BrowseButton();
browseButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
browseButton.addActionListener(e -> {
GhidraFileChooser chooser = new GhidraFileChooser(panel);
chooser.setTitle("Select Word Model File");
chooser.setMultiSelectionEnabled(false);
chooser.setFileFilter(new ExtensionFileFilter("sng", "Word File"));
File selectedFile = chooser.getSelectedFile();
chooser.dispose();
if (selectedFile == null) {
return;
}
@ -247,7 +244,6 @@ public class SearchStringDialog extends DialogComponentProvider {
// Important to only save off the name of the file. The NGramUtils call that
// loads the file will search for the file given this name.
wordModelField.setText(selectedFile.getName());
}
});
modelFieldPanel.add(browseButton);

View file

@ -25,7 +25,7 @@ import javax.swing.*;
import org.jdom.Element;
import docking.ComponentProvider;
import docking.DialogComponentProvider;
import docking.ReusableDialogComponentProvider;
import docking.widgets.checkbox.GCheckBox;
import docking.widgets.label.GHtmlLabel;
import docking.widgets.label.GIconLabel;
@ -35,7 +35,7 @@ import ghidra.util.*;
import ghidra.util.layout.*;
import resources.Icons;
public class FilterDialog extends DialogComponentProvider {
public class FilterDialog extends ReusableDialogComponentProvider {
private NewSymbolFilter filter;
private JPanel advancedPanel;
private JPanel advancedFilterPanel;
@ -48,7 +48,7 @@ public class FilterDialog extends DialogComponentProvider {
private PluginTool tool;
public FilterDialog(PluginTool tool) {
super("Symbol Table Filter", false);
super("Symbol Table Filter", false, true, true, false);
this.tool = tool;
filter = new NewSymbolFilter();
addWorkPanel(buildWorkPanel());

View file

@ -133,9 +133,7 @@ class SymbolPanel extends JPanel {
symTable.dispose();
threadedTablePanel.dispose();
tableFilterPanel.dispose();
symProvider = null;
filterDialog.close();
filterDialog = null;
filterDialog.dispose();
}
void setFilter() {

View file

@ -287,7 +287,7 @@ public class TableComponentProvider<T> extends ComponentProviderAdapter
navigatable.removeNavigatableListener(this);
}
tool.removeComponentProvider(this);
super.closeComponent();
tableServicePlugin.remove(this);
if (markerSet != null) {

View file

@ -22,8 +22,8 @@ import java.util.List;
import javax.swing.*;
import javax.swing.border.Border;
import docking.DialogComponentProvider;
import docking.DockingWindowManager;
import docking.ReusableDialogComponentProvider;
import docking.widgets.checkbox.GCheckBox;
import docking.widgets.label.GLabel;
import generic.theme.GIcon;
@ -31,7 +31,7 @@ import generic.theme.GThemeDefaults.Colors;
import generic.theme.GThemeDefaults.Colors.Java;
import generic.theme.Gui;
class TipOfTheDayDialog extends DialogComponentProvider {
class TipOfTheDayDialog extends ReusableDialogComponentProvider {
private static final String FONT_ID = "font.plugin.tips";
private static final String FONT_LABEL_ID = "font.plugin.tips.label";
private static final int _24_HOURS = 86400000;

View file

@ -134,7 +134,6 @@ public class GenerateOldLanguagePlugin extends Plugin implements ApplicationLeve
private JPanel panel;
private SelectLanguagePanel selectLangPanel;
private GhidraFileChooser chooser;
GenerateOldLanguageDialog(final boolean skipOldLangGeneration) {
super("Select Old Language", true, true, true, false);
@ -169,8 +168,7 @@ public class GenerateOldLanguagePlugin extends Plugin implements ApplicationLeve
return;
}
if (chooser == null) {
chooser = new GhidraFileChooser(panel);
GhidraFileChooser chooser = new GhidraFileChooser(panel);
chooser.setTitle("Specify Old Language Output File");
chooser.setFileFilter(OLD_LANG_FILTER);
chooser.setApproveButtonText("Create");
@ -178,8 +176,9 @@ public class GenerateOldLanguagePlugin extends Plugin implements ApplicationLeve
// chooser.setCurrentDirectory(LANGUAGE_DIR);
chooser.setCurrentDirectory(
Application.getApplicationRootDirectory().getFile(false));
}
File file = chooser.getSelectedFile(true);
chooser.dispose();
if (file == null) {
return;
}
@ -234,7 +233,6 @@ public class GenerateOldLanguagePlugin extends Plugin implements ApplicationLeve
private JPanel panel;
private SelectLanguagePanel selectLangPanel;
private GhidraFileChooser chooser;
private Language oldLang;
private File oldLangFile;
@ -269,8 +267,8 @@ public class GenerateOldLanguagePlugin extends Plugin implements ApplicationLeve
File transFile;
if (GenerateTranslatorDialog.this.oldLangFile == null) {
if (chooser == null) {
chooser = new GhidraFileChooser(panel);
GhidraFileChooser chooser = new GhidraFileChooser(panel);
chooser.setTitle("Specify Old Language Output File");
chooser.setFileFilter(TRANSLATOR_FILTER);
chooser.setApproveButtonText("Create");
@ -278,8 +276,9 @@ public class GenerateOldLanguagePlugin extends Plugin implements ApplicationLeve
// chooser.setCurrentDirectory(LANGUAGE_DIR);
chooser.setCurrentDirectory(
Application.getApplicationRootDirectory().getFile(false));
}
transFile = chooser.getSelectedFile(true);
chooser.dispose();
if (transFile == null) {
return;
}
@ -533,7 +532,7 @@ public class GenerateOldLanguagePlugin extends Plugin implements ApplicationLeve
public List<LanguageDescription> getLanguageDescriptions(
boolean includeDeprecatedLanguages) {
// Include deprecated languages
List<LanguageDescription> list = new ArrayList<LanguageDescription>();
List<LanguageDescription> list = new ArrayList<>();
list.addAll(langService.getLanguageDescriptions(true));
if (includeOldLanguages) {
list.addAll(Arrays.asList(oldLangFactory.getLatestOldLanaguageDescriptions()));

View file

@ -2044,7 +2044,7 @@ public abstract class GhidraScript extends FlatProgramAPI {
chooser.setApproveButtonText(approveButtonText);
chooser.setFileSelectionMode(GhidraFileChooserMode.FILES_ONLY);
File file = chooser.getSelectedFile();
chooser.dispose();
if (chooser.wasCancelled()) {
throw new CancelledException();
}
@ -2121,7 +2121,7 @@ public abstract class GhidraScript extends FlatProgramAPI {
chooser.setApproveButtonText(approveButtonText);
chooser.setFileSelectionMode(GhidraFileChooserMode.DIRECTORIES_ONLY);
File file = chooser.getSelectedFile();
chooser.dispose();
if (chooser.wasCancelled()) {
throw new CancelledException();
}

View file

@ -15,13 +15,6 @@
*/
package ghidra.app.util;
import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.data.DataType;
import ghidra.program.model.data.DataTypeComponent;
import ghidra.program.model.listing.Program;
import ghidra.util.HelpLocation;
import ghidra.util.exception.DuplicateNameException;
import java.awt.*;
import javax.swing.*;
@ -30,6 +23,12 @@ import javax.swing.border.TitledBorder;
import docking.ComponentProvider;
import docking.DialogComponentProvider;
import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.data.DataType;
import ghidra.program.model.data.DataTypeComponent;
import ghidra.program.model.listing.Program;
import ghidra.util.HelpLocation;
import ghidra.util.exception.DuplicateNameException;
public class EditFieldNameDialog extends DialogComponentProvider {
@ -63,8 +62,6 @@ public class EditFieldNameDialog extends DialogComponentProvider {
setMinimumSize(new Dimension(300, 50));
}
private String getCurrentFieldName() {
String name = dtComp.getFieldName();
if (name == null) {
@ -97,9 +94,11 @@ public class EditFieldNameDialog extends DialogComponentProvider {
parent.setLastChangeTime(timeNow);
}
success = true;
} catch (DuplicateNameException e) {
}
catch (DuplicateNameException e) {
setStatusText(e.getMessage());
} finally {
}
finally {
program.endTransaction(txId, true);
}
@ -111,12 +110,14 @@ public class EditFieldNameDialog extends DialogComponentProvider {
}
public void editField(DataTypeComponent dataTypeComponent, Program p) {
ComponentProvider componentProvider = tool.getComponentProvider(PluginConstants.CODE_BROWSER);
ComponentProvider componentProvider =
tool.getComponentProvider(PluginConstants.CODE_BROWSER);
JComponent component = componentProvider.getComponent();
editField(dataTypeComponent, p, component);
}
public void editField(DataTypeComponent dataTypeComponent, Program p, Component centeredOverComponent ) {
public void editField(DataTypeComponent dataTypeComponent, Program p,
Component centeredOverComponent) {
this.dtComp = dataTypeComponent;
this.program = p;
String name = getCurrentFieldName();

View file

@ -31,7 +31,7 @@ public class OptionsDialog extends DialogComponentProvider implements OptionList
private OptionValidator validator;
/**
* Contructs a new OptionsDialog for editing the options associated with a specific import format
* Constructs a new OptionsDialog for editing the options associated with a specific import format
* such as PE, ELF, XML, etc.
*
* @param originalOptions the list of options generated from the specific import format selected.

View file

@ -15,12 +15,11 @@
*/
package ghidra.app.util.bin.format.dwarf4.external;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.io.File;
import docking.action.builder.ActionBuilder;
import docking.tool.ToolConstants;
import docking.widgets.filechooser.GhidraFileChooser;
@ -70,6 +69,7 @@ public class DWARFExternalDebugFilesPlugin extends Plugin {
chooser.setFileSelectionMode(GhidraFileChooserMode.DIRECTORIES_ONLY);
chooser.setTitle("Select External Debug Files Directory");
File selectedDir = chooser.getSelectedFile();
chooser.dispose();
if (selectedDir == null) {
return;
}

View file

@ -62,8 +62,6 @@ import ghidra.util.task.TaskBuilder;
*/
public class ImporterDialog extends DialogComponentProvider {
public static final String LAST_IMPORTFILE_PREFERENCE_KEY = "Importer.LastFile";
protected PluginTool tool;
private ProgramManager programManager;
protected FSRL fsrl;
@ -118,7 +116,7 @@ public class ImporterDialog extends DialogComponentProvider {
// only save the imported file's path if its a local filesystem path that
// will be valid when used later. FSRL paths that drill into container files
// aren't widely supported yet.
Preferences.setProperty(LAST_IMPORTFILE_PREFERENCE_KEY, fsrl.getPath());
Preferences.setProperty(Preferences.LAST_IMPORT_FILE, fsrl.getPath());
}
addWorkPanel(buildWorkPanel());

View file

@ -15,12 +15,11 @@
*/
package ghidra.plugin.importer;
import java.util.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import java.util.*;
import docking.ActionContext;
import docking.action.*;
@ -139,7 +138,10 @@ public class ImporterPlugin extends Plugin
frontEndService.removeProjectListener(this);
frontEndService = null;
}
chooser = null;
if (chooser != null) {
chooser.dispose();
}
}
@Override
@ -327,7 +329,7 @@ public class ImporterPlugin extends Plugin
chooser.setTitle(title);
chooser.setApproveButtonText(buttonText);
String lastFile = Preferences.getProperty(ImporterDialog.LAST_IMPORTFILE_PREFERENCE_KEY);
String lastFile = Preferences.getProperty(Preferences.LAST_IMPORT_FILE);
if (lastFile != null) {
chooser.setSelectedFile(new File(lastFile));
}

View file

@ -144,6 +144,15 @@ class FSBActionManager {
}
public void dispose() {
if (chooserExport != null) {
chooserExport.dispose();
}
if (chooserExportAll != null) {
chooserExportAll.dispose();
}
removeActions();
}

View file

@ -15,13 +15,12 @@
*/
package ghidra.plugins.fsbrowser;
import java.util.*;
import java.awt.Component;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import java.util.*;
import javax.swing.KeyStroke;
@ -37,8 +36,8 @@ import ghidra.app.plugin.PluginCategoryNames;
import ghidra.app.services.*;
import ghidra.app.util.opinion.LoaderService;
import ghidra.formats.gfilesystem.*;
import ghidra.framework.main.FrontEndService;
import ghidra.framework.main.ApplicationLevelPlugin;
import ghidra.framework.main.FrontEndService;
import ghidra.framework.model.Project;
import ghidra.framework.model.ProjectListener;
import ghidra.framework.plugintool.*;
@ -70,7 +69,8 @@ import utilities.util.FileUtilities;
eventsConsumed = { ProgramActivatedPluginEvent.class }
)
//@formatter:on
public class FileSystemBrowserPlugin extends Plugin implements ApplicationLevelPlugin, ProjectListener,
public class FileSystemBrowserPlugin extends Plugin
implements ApplicationLevelPlugin, ProjectListener,
FileSystemBrowserService {
/* package */ DockingAction openFilesystemAction;
@ -128,7 +128,10 @@ public class FileSystemBrowserPlugin extends Plugin implements ApplicationLevelP
frontEndService.removeProjectListener(this);
frontEndService = null;
}
chooserOpen = null;
if (chooserOpen != null) {
chooserOpen.dispose();
}
for (FileSystemBrowserComponentProvider provider : currentBrowsers.values()) {
provider.dispose();

View file

@ -53,6 +53,8 @@ import ghidra.util.task.TaskLauncher;
public class BatchImportDialog extends DialogComponentProvider {
private static final String LAST_IMPORT_DIR = "LastBatchImportDir";
/**
* Shows the batch import dialog (via runSwingLater) and prompts the user to select
* a file if the supplied {@code batchInfo} is empty.
@ -96,7 +98,6 @@ public class BatchImportDialog extends DialogComponentProvider {
private JButton rescanButton;
private JSpinner maxDepthSpinner;
private GhidraFileChooser fileChooser;
private SourcesListModel sourceListModel;
private BatchImportDialog(BatchInfo batchInfo, DomainFolder defaultFolder) {
@ -387,20 +388,21 @@ public class BatchImportDialog extends DialogComponentProvider {
}
private boolean addSources() {
if (fileChooser == null) {
fileChooser = new GhidraFileChooser(getComponent());
fileChooser.setMultiSelectionEnabled(true);
fileChooser.setTitle("Choose File to Batch Import");
fileChooser.setApproveButtonText("Select files");
fileChooser.setFileSelectionMode(GhidraFileChooserMode.FILES_AND_DIRECTORIES);
fileChooser.addFileFilter(ImporterUtilities.LOADABLE_FILES_FILTER);
fileChooser.addFileFilter(ImporterUtilities.CONTAINER_FILES_FILTER);
fileChooser.setSelectedFileFilter(GhidraFileFilter.ALL);
}
List<File> selectedFiles = fileChooser.getSelectedFiles();
GhidraFileChooser chooser = new GhidraFileChooser(getComponent());
chooser.setMultiSelectionEnabled(true);
chooser.setTitle("Choose File to Batch Import");
chooser.setApproveButtonText("Select files");
chooser.setFileSelectionMode(GhidraFileChooserMode.FILES_AND_DIRECTORIES);
chooser.addFileFilter(ImporterUtilities.LOADABLE_FILES_FILTER);
chooser.addFileFilter(ImporterUtilities.CONTAINER_FILES_FILTER);
chooser.setSelectedFileFilter(GhidraFileFilter.ALL);
chooser.setLastDirectoryPreference(LAST_IMPORT_DIR);
List<File> selectedFiles = chooser.getSelectedFiles();
if (selectedFiles.isEmpty()) {
return !fileChooser.wasCancelled();
return !chooser.wasCancelled();
}
List<FSRL> filesToAdd = new ArrayList<>();
@ -408,6 +410,8 @@ public class BatchImportDialog extends DialogComponentProvider {
filesToAdd.add(FileSystemService.getInstance().getLocalFSRL(selectedFile));
}
chooser.dispose();
return addSources(filesToAdd);
}

View file

@ -29,7 +29,6 @@ class BatchProjectDestinationPanel extends JPanel {
private JComponent parent;
private JTextField folderNameTextField;
private DataTreeDialog dataTreeDialog;
private DomainFolder selectedDomainFolder;
public BatchProjectDestinationPanel(JComponent parent, DomainFolder defaultFolder) {
@ -96,7 +95,7 @@ class BatchProjectDestinationPanel extends JPanel {
}
private void browseFolders() {
dataTreeDialog =
DataTreeDialog dataTreeDialog =
new DataTreeDialog(parent, "Choose a project folder", DataTreeDialog.CHOOSE_FOLDER);
dataTreeDialog.addOkActionListener(e -> {
dataTreeDialog.close();
@ -107,9 +106,6 @@ class BatchProjectDestinationPanel extends JPanel {
}
public void setFolder(DomainFolder folder) {
if (dataTreeDialog != null) {
dataTreeDialog.setSelectedFolder(folder);
}
folderNameTextField.setText(folder != null ? folder.toString() : "< Choose a folder >");
this.selectedDomainFolder = folder;
onProjectDestinationChange(selectedDomainFolder);

View file

@ -15,7 +15,7 @@
*/
package ghidra.app.plugin.core.label;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.*;
import org.junit.*;
@ -37,8 +37,6 @@ public class OperandLabelDialogTest extends AbstractGhidraHeadedIntegrationTest
private LabelMgrPlugin plugin;
private CodeBrowserPlugin cb;
private Program program;
private OperandLabelDialog dialog;
private GhidraComboBox<?> combo;
private SetOperandLabelAction setLabelAction;
@Before
@ -51,10 +49,6 @@ public class OperandLabelDialogTest extends AbstractGhidraHeadedIntegrationTest
plugin = getPlugin(tool, LabelMgrPlugin.class);
cb = getPlugin(tool, CodeBrowserPlugin.class);
dialog = runSwing(() -> plugin.getOperandLabelDialog());
combo = (GhidraComboBox<?>) findComponentByName(dialog, "MYCHOICE");
setLabelAction = (SetOperandLabelAction) getAction(plugin, "Set Operand Label");
}
@ -80,7 +74,10 @@ public class OperandLabelDialogTest extends AbstractGhidraHeadedIntegrationTest
performAction(setLabelAction, context, false);
waitForSwing();
runSwing(() -> combo.setSelectedItem("bob"));
OperandLabelDialog dialog = waitForDialogComponent(OperandLabelDialog.class);
GhidraComboBox<?> combo = (GhidraComboBox<?>) findComponentByName(dialog, "MYCHOICE");
setSelectedItem(combo, "bob");
pressButtonByText(dialog, "OK");
waitForSwing();
@ -94,7 +91,10 @@ public class OperandLabelDialogTest extends AbstractGhidraHeadedIntegrationTest
performAction(setLabelAction, context, false);
waitForSwing();
runSwing(() -> combo.setSelectedItem("b"));
dialog = waitForDialogComponent(OperandLabelDialog.class);
combo = (GhidraComboBox<?>) findComponentByName(dialog, "MYCHOICE");
setSelectedItem(combo, "b");
pressButtonByText(dialog, "OK");
program.flushEvents();
@ -108,4 +108,7 @@ public class OperandLabelDialogTest extends AbstractGhidraHeadedIntegrationTest
assertEquals("dword ptr [b]", cb.getCurrentFieldText());
}
private void setSelectedItem(GhidraComboBox<?> combo, String s) {
runSwing(() -> combo.setSelectedItem(s));
}
}

View file

@ -24,6 +24,7 @@ import java.util.List;
import java.util.Objects;
import docking.widgets.filechooser.GhidraFileChooser;
import docking.widgets.filechooser.GhidraFileChooserMode;
import ghidra.bitpatterns.info.ContextRegisterFilter;
import ghidra.bitpatterns.info.PatternType;
import ghidra.framework.preferences.Preferences;
@ -88,7 +89,7 @@ public class ExportPatternFileActionListener implements ActionListener {
return;
}
GhidraFileChooser gFileChooser = new GhidraFileChooser(component);
gFileChooser.setFileSelectionMode(GhidraFileChooser.FILES_ONLY);
gFileChooser.setFileSelectionMode(GhidraFileChooserMode.FILES_ONLY);
ExtensionFileFilter xmlFilter = new ExtensionFileFilter("xml", "XML Files");
gFileChooser.setFileFilter(xmlFilter);
String baseDir = Preferences.getProperty(XML_EXPORT_DIR_PROPERTY);
@ -97,11 +98,13 @@ public class ExportPatternFileActionListener implements ActionListener {
}
gFileChooser.setTitle("Select Export File");
File outFile = gFileChooser.getSelectedFile();
String lastDirPath = gFileChooser.getCurrentDirectory().getAbsolutePath();
gFileChooser.dispose();
if (gFileChooser.wasCancelled() || outFile == null) {
return;
}
Preferences.setProperty(XML_EXPORT_DIR_PROPERTY,
gFileChooser.getCurrentDirectory().getAbsolutePath());
Preferences.setProperty(XML_EXPORT_DIR_PROPERTY, lastDirPath);
Preferences.store();
BitsInputDialogComponentProvider bitsProvider =
new BitsInputDialogComponentProvider(BITS_PROVIDER_MESSAGE);
@ -115,7 +118,6 @@ public class ExportPatternFileActionListener implements ActionListener {
}
catch (IOException e1) {
Msg.showError(this, component, "IO Error", "IO error exporting pattern xml file", e1);
e1.printStackTrace();
}
}

View file

@ -28,6 +28,7 @@ import docking.action.DockingAction;
import docking.action.MenuData;
import docking.tool.ToolConstants;
import docking.widgets.filechooser.GhidraFileChooser;
import docking.widgets.filechooser.GhidraFileChooserMode;
import docking.widgets.label.GLabel;
import ghidra.bitpatterns.info.*;
import ghidra.framework.options.OptionsChangeListener;
@ -227,13 +228,14 @@ public class FunctionBitPatternsMainProvider extends ComponentProviderAdapter
@Override
public void actionPerformed(ActionEvent e) {
GhidraFileChooser fileChooser = new GhidraFileChooser(component);
fileChooser.setFileSelectionMode(GhidraFileChooser.DIRECTORIES_ONLY);
fileChooser.setFileSelectionMode(GhidraFileChooserMode.DIRECTORIES_ONLY);
fileChooser.setTitle("Select Directory Containing XML Files");
String baseDir = Preferences.getProperty(PATTERN_INFO_DIR);
if (baseDir != null) {
fileChooser.setCurrentDirectory(new File(baseDir));
}
File xmlDir = fileChooser.getSelectedFile();
fileChooser.dispose();
if (xmlDir == null) {
return;
}

View file

@ -25,6 +25,7 @@ import java.math.BigInteger;
import org.xml.sax.SAXException;
import docking.widgets.filechooser.GhidraFileChooser;
import docking.widgets.filechooser.GhidraFileChooserMode;
import generic.jar.ResourceFile;
import ghidra.app.analyzers.FunctionStartAnalyzer.ContextAction;
import ghidra.bitpatterns.info.ContextRegisterFilter;
@ -59,7 +60,7 @@ public class ImportPatternFileActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
GhidraFileChooser fileChooser = new GhidraFileChooser(component);
fileChooser.setFileSelectionMode(GhidraFileChooser.FILES_ONLY);
fileChooser.setFileSelectionMode(GhidraFileChooserMode.FILES_ONLY);
fileChooser.setTitle("Select Pattern File");
String baseDir = Preferences.getProperty(XML_IMPORT_DIR_PROPERTY);
if (baseDir != null) {
@ -68,11 +69,13 @@ public class ImportPatternFileActionListener implements ActionListener {
ExtensionFileFilter xmlFilter = new ExtensionFileFilter("xml", "XML Files");
fileChooser.setFileFilter(xmlFilter);
File patternFile = fileChooser.getSelectedFile();
String lastDirPath = fileChooser.getCurrentDirectory().getAbsolutePath();
fileChooser.dispose();
if (fileChooser.wasCancelled() || patternFile == null) {
return;
}
Preferences.setProperty(XML_IMPORT_DIR_PROPERTY,
fileChooser.getCurrentDirectory().getAbsolutePath());
Preferences.setProperty(XML_IMPORT_DIR_PROPERTY, lastDirPath);
Preferences.store();
//only clear the patterns if new patterns are loaded from a file
ResourceFile resource = new ResourceFile(patternFile);

View file

@ -146,6 +146,7 @@ public class ProgramByteViewerComponentProvider extends ByteViewerComponentProvi
@Override
public void closeComponent() {
// overridden to handle snapshots
super.closeComponent();
plugin.closeProvider(this);
}

Some files were not shown because too many files have changed in this diff Show more