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 javax.swing.*;
import docking.DialogComponentProvider; import docking.ReusableDialogComponentProvider;
import docking.widgets.table.EnumeratedColumnTableModel; import docking.widgets.table.EnumeratedColumnTableModel;
import docking.widgets.table.GTable; import docking.widgets.table.GTable;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
import ghidra.util.table.GhidraTableFilterPanel; 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 final EnumeratedColumnTableModel<R> tableModel;
protected GTable table; protected GTable table;

View file

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

View file

@ -42,14 +42,10 @@ public abstract class DebuggerGoToTrait {
protected DebuggerCoordinates current = DebuggerCoordinates.NOWHERE; protected DebuggerCoordinates current = DebuggerCoordinates.NOWHERE;
protected final DebuggerGoToDialog goToDialog;
public DebuggerGoToTrait(PluginTool tool, Plugin plugin, ComponentProvider provider) { public DebuggerGoToTrait(PluginTool tool, Plugin plugin, ComponentProvider provider) {
this.tool = tool; this.tool = tool;
this.plugin = plugin; this.plugin = plugin;
this.provider = provider; this.provider = provider;
goToDialog = new DebuggerGoToDialog(this);
} }
protected abstract boolean goToAddress(Address address); protected abstract boolean goToAddress(Address address);
@ -68,6 +64,7 @@ public abstract class DebuggerGoToTrait {
} }
private void activatedGoTo(ActionContext context) { private void activatedGoTo(ActionContext context) {
DebuggerGoToDialog goToDialog = new DebuggerGoToDialog(this);
TracePlatform platform = current.getPlatform(); TracePlatform platform = current.getPlatform();
goToDialog.show((SleighLanguage) platform.getLanguage()); 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.TraceProgramView;
import ghidra.trace.model.program.TraceVariableSnapProgramView; import ghidra.trace.model.program.TraceVariableSnapProgramView;
@PluginInfo( @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 = {
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, DebuggerStaticMappingService.class,
ProgramManager.class, ProgramManager.class,
}, }, servicesProvided = {})
servicesProvided = {})
public class DebuggerCopyActionsPlugin extends AbstractDebuggerPlugin { public class DebuggerCopyActionsPlugin extends AbstractDebuggerPlugin {
protected static ProgramSelection getSelectionFromContext(ActionContext context) { protected static ProgramSelection getSelectionFromContext(ActionContext context) {
@ -75,6 +66,13 @@ public class DebuggerCopyActionsPlugin extends AbstractDebuggerPlugin {
createActions(); createActions();
} }
@Override
protected void dispose() {
super.dispose();
copyDialog.dispose();
}
protected void createActions() { protected void createActions() {
actionExportView = ExportTraceViewAction.builder(this) actionExportView = ExportTraceViewAction.builder(this)
.enabled(false) .enabled(false)

View file

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

View file

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

View file

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

View file

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

View file

@ -418,7 +418,6 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
private final DebuggerBlockChooserDialog blockChooserDialog; private final DebuggerBlockChooserDialog blockChooserDialog;
private final DebuggerModuleMapProposalDialog moduleProposalDialog; private final DebuggerModuleMapProposalDialog moduleProposalDialog;
private final DebuggerSectionMapProposalDialog sectionProposalDialog; private final DebuggerSectionMapProposalDialog sectionProposalDialog;
private DataTreeDialog programChooserDialog; // Already lazy
private DebuggerCoordinates current = DebuggerCoordinates.NOWHERE; private DebuggerCoordinates current = DebuggerCoordinates.NOWHERE;
private Program currentProgram; private Program currentProgram;
@ -470,6 +469,7 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
GhidraFileChooser chooser = new GhidraFileChooser(getComponent()); GhidraFileChooser chooser = new GhidraFileChooser(getComponent());
chooser.setSelectedFile(new File(module.getName())); chooser.setSelectedFile(new File(module.getName()));
File file = chooser.getSelectedFile(); File file = chooser.getSelectedFile();
chooser.dispose();
if (file == null) { // Perhaps cancelled if (file == null) { // Perhaps cancelled
return; return;
} }
@ -511,6 +511,10 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
consoleService.removeResolutionAction(actionMapMissingModule); consoleService.removeResolutionAction(actionMapMissingModule);
} }
} }
blockChooserDialog.dispose();
moduleProposalDialog.dispose();
sectionProposalDialog.dispose();
} }
@Override @Override
@ -1071,14 +1075,11 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
} }
private DataTreeDialog getProgramChooserDialog() { private DataTreeDialog getProgramChooserDialog() {
if (programChooserDialog != null) {
return programChooserDialog;
}
DomainFileFilter filter = df -> Program.class.isAssignableFrom(df.getDomainObjectClass()); 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 // TODO regarding the hack note below, I believe it's fixed, but not sure how to test
return programChooserDialog = return new DataTreeDialog(null, "Map Module to Program", DataTreeDialog.OPEN, filter) {
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. { // TODO/HACK: I get an NPE setting the default selection if I don't fake this.
dialogShown(); dialogShown();
} }
@ -1086,12 +1087,12 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
} }
public DomainFile askProgram(Program program) { public DomainFile askProgram(Program program) {
getProgramChooserDialog(); DataTreeDialog dialog = getProgramChooserDialog();
if (program != null) { if (program != null) {
programChooserDialog.selectDomainFile(program.getDomainFile()); dialog.selectDomainFile(program.getDomainFile());
} }
tool.showDialog(programChooserDialog); tool.showDialog(dialog);
return programChooserDialog.getDomainFile(); return dialog.getDomainFile();
} }
public Entry<Program, MemoryBlock> askBlock(TraceSection section, Program program, 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.*;
import ghidra.framework.plugintool.util.PluginStatus; import ghidra.framework.plugintool.util.PluginStatus;
@PluginInfo( @PluginInfo(shortDescription = "Debugger static mapping manager", description = "GUI to manage static mappings", category = PluginCategoryNames.DEBUGGER, packageName = DebuggerPluginPackage.NAME, status = PluginStatus.RELEASED, eventsConsumed = {
shortDescription = "Debugger static mapping manager",
description = "GUI to manage static mappings",
category = PluginCategoryNames.DEBUGGER,
packageName = DebuggerPluginPackage.NAME,
status = PluginStatus.RELEASED,
eventsConsumed = {
TraceActivatedPluginEvent.class, TraceActivatedPluginEvent.class,
ProgramActivatedPluginEvent.class, ProgramActivatedPluginEvent.class,
}, }, servicesRequired = {
servicesRequired = {
DebuggerStaticMappingService.class, DebuggerStaticMappingService.class,
DebuggerTraceManagerService.class, DebuggerTraceManagerService.class,
}) })
@ -55,6 +48,7 @@ public class DebuggerStaticMappingPlugin extends AbstractDebuggerPlugin {
@Override @Override
protected void dispose() { protected void dispose() {
tool.removeComponentProvider(provider); tool.removeComponentProvider(provider);
provider.dispose();
super.dispose(); super.dispose();
} }

View file

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

View file

@ -132,9 +132,7 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final AutoService.Wiring autoServiceWiring; private final AutoService.Wiring autoServiceWiring;
@AutoOptionDefined( @AutoOptionDefined(name = "Default Extended Step", description = "The default string for the extended step command")
name = "Default Extended Step",
description = "The default string for the extended step command")
String extendedStep = ""; String extendedStep = "";
@SuppressWarnings("unused") @SuppressWarnings("unused")
@ -244,6 +242,16 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter
repeatLastSet.run(); 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 @Override
public void addLocalAction(DockingActionIf action) { public void addLocalAction(DockingActionIf action) {
super.addLocalAction(action); super.addLocalAction(action);

View file

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

View file

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

View file

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

View file

@ -553,6 +553,8 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
@Override @Override
public void removeFromTool() { public void removeFromTool() {
availableRegsDialog.dispose();
plugin.providerRemoved(this); plugin.providerRemoved(this);
plugin.getTool().removePopupActionProvider(this); plugin.getTool().removePopupActionProvider(this);
super.removeFromTool(); super.removeFromTool();
@ -1296,7 +1298,8 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
return AsyncUtils.NIL; return AsyncUtils.NIL;
} }
toRead.retainAll(regMapper.getRegistersOnTarget()); 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()) { if (banks == null || banks.isEmpty()) {
Msg.error(this, "Current frame's bank does not exist"); Msg.error(this, "Current frame's bank does not exist");
return AsyncUtils.NIL; 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;
import org.apache.commons.collections4.bidimap.DualLinkedHashBidiMap; 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.gui.DebuggerResources.AbstractConnectAction;
import ghidra.app.plugin.core.debug.utils.MiscellaneousUtils; import ghidra.app.plugin.core.debug.utils.MiscellaneousUtils;
import ghidra.app.services.DebuggerModelService; import ghidra.app.services.DebuggerModelService;
@ -45,7 +45,7 @@ import ghidra.program.model.listing.Program;
import ghidra.util.*; import ghidra.util.*;
import ghidra.util.datastruct.CollectionChangeListener; import ghidra.util.datastruct.CollectionChangeListener;
public class DebuggerConnectDialog extends DialogComponentProvider public class DebuggerConnectDialog extends ReusableDialogComponentProvider
implements PropertyChangeListener { implements PropertyChangeListener {
private static final String KEY_CURRENT_FACTORY_CLASSNAME = "currentFactoryCls"; private static final String KEY_CURRENT_FACTORY_CLASSNAME = "currentFactoryCls";
private static final String KEY_SUCCESS_FACTORY_CLASSNAME = "successFactoryCls"; 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.CollectionChangeListener;
import ghidra.util.datastruct.ListenerSet; import ghidra.util.datastruct.ListenerSet;
@PluginInfo( @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 = {
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, }) DebuggerModelService.class, })
public class DebuggerModelServicePlugin extends Plugin public class DebuggerModelServicePlugin extends Plugin
implements DebuggerModelServiceInternal, ApplicationLevelOnlyPlugin { implements DebuggerModelServiceInternal, ApplicationLevelOnlyPlugin {
@ -184,6 +177,14 @@ public class DebuggerModelServicePlugin extends Plugin
createActions(); createActions();
} }
@Override
protected void dispose() {
super.dispose();
connectDialog.dispose();
offerDialog.dispose();
}
protected void createActions() { protected void createActions() {
actionDisconnectAll = DisconnectAllAction.builder(this, this) actionDisconnectAll = DisconnectAllAction.builder(this, this)
.menuPath("Debugger", DisconnectAllAction.NAME) .menuPath("Debugger", DisconnectAllAction.NAME)

View file

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

View file

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

View file

@ -24,7 +24,7 @@ import javax.swing.*;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import docking.DialogComponentProvider; import docking.ReusableDialogComponentProvider;
import docking.action.DockingAction; import docking.action.DockingAction;
import docking.action.builder.ActionBuilder; import docking.action.builder.ActionBuilder;
import docking.widgets.combobox.GComboBox; import docking.widgets.combobox.GComboBox;
@ -50,7 +50,7 @@ import ghidra.util.task.*;
* for learning function starts, train models, see performance statistics, and * for learning function starts, train models, see performance statistics, and
* apply the models. * 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_TEXT = "Number of Initial Bytes (CSV)";
private static final String INITIAL_BYTES_TIP = 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")); initOptions(getTool().getOptions("Random Forest Function Finder"));
} }
@Override
protected void dispose() {
super.dispose();
if (paramsDialog != null) {
paramsDialog.dispose();
}
}
@Override @Override
public void optionsChanged(ToolOptions options, String optionName, Object oldValue, public void optionsChanged(ToolOptions options, String optionName, Object oldValue,
Object newValue) throws OptionsVetoException { Object newValue) throws OptionsVetoException {

View file

@ -69,6 +69,7 @@ public class SampleTableProvider extends ComponentProviderAdapter implements Opt
void dispose() { void dispose() {
filterTable.dispose(); filterTable.dispose();
fileChooserPanel.dispose();
removeFromTool(); 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_description.htm||GHIDRA||||END|
src/main/help/help/topics/DataTypeManagerPlugin/data_type_manager_window.html||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/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/DataTypeManager.png||GHIDRA||||END|
src/main/help/help/topics/DataTypeManagerPlugin/images/DisassociateDialog.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| src/main/help/help/topics/DataTypeManagerPlugin/images/EditPaths.png||GHIDRA||||END|

View file

@ -991,35 +991,6 @@
</BLOCKQUOTE> </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> <H3><A name="ReplaceDataType"></A>Replacing a Data Type</H3>
<BLOCKQUOTE> <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 javax.swing.*;
import docking.DialogComponentProvider; import docking.ReusableDialogComponentProvider;
import docking.widgets.OptionDialog; import docking.widgets.OptionDialog;
import docking.widgets.filechooser.GhidraFileChooser; import docking.widgets.filechooser.GhidraFileChooser;
import docking.widgets.filechooser.GhidraFileChooserMode;
import docking.widgets.label.GDLabel; import docking.widgets.label.GDLabel;
import ghidra.framework.GenericRunInfo; import ghidra.framework.GenericRunInfo;
import ghidra.framework.model.ProjectLocator; import ghidra.framework.model.ProjectLocator;
@ -32,10 +33,9 @@ import ghidra.util.filechooser.GhidraFileChooserModel;
import ghidra.util.filechooser.GhidraFileFilter; import ghidra.util.filechooser.GhidraFileFilter;
/** /**
* Dialog to prompt the user for the project to archive and the file to archive * Dialog to prompt the user for the project to archive and the file to archive it to.
* it to.
*/ */
public class ArchiveDialog extends DialogComponentProvider { public class ArchiveDialog extends ReusableDialogComponentProvider {
private static final int NUM_TEXT_COLUMNS = 40; private static final int NUM_TEXT_COLUMNS = 40;
private boolean actionComplete; private boolean actionComplete;
@ -43,14 +43,12 @@ public class ArchiveDialog extends DialogComponentProvider {
private JTextField archiveField; private JTextField archiveField;
private JButton archiveBrowse; private JButton archiveBrowse;
private GhidraFileChooser jarFileChooser;
private ProjectLocator projectLocator; private ProjectLocator projectLocator;
private String archivePathName; private String archivePathName;
/** /**
* Constructor * Constructor
* *
* @param parent the parent frame of the NumberInputDialog.
* @param plugin the archive plugin using this dialog. * @param plugin the archive plugin using this dialog.
*/ */
ArchiveDialog(ArchivePlugin plugin) { ArchiveDialog(ArchivePlugin plugin) {
@ -179,6 +177,7 @@ public class ArchiveDialog extends DialogComponentProvider {
* Display this dialog. * Display this dialog.
* @param pProjectLocator the project URL to display when the dialog pops up. * @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 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 * @return true if the user submitted valid values for the project and
* archive file, false if user cancelled. * archive file, false if user cancelled.
@ -237,7 +236,7 @@ public class ArchiveDialog extends DialogComponentProvider {
File file = new File(pathname); File file = new File(pathname);
String name = file.getName(); String name = file.getName();
if (!isValidName(name)) { if (!NamingUtilities.isValidProjectName(name)) {
setStatusText("Archive name contains invalid characters."); setStatusText("Archive name contains invalid characters.");
return false; return false;
} }
@ -256,8 +255,7 @@ public class ArchiveDialog extends DialogComponentProvider {
String filePathName) { String filePathName) {
GhidraFileChooser fileChooser = new GhidraFileChooser(getComponent()); GhidraFileChooser fileChooser = new GhidraFileChooser(getComponent());
fileChooser.setFileSelectionMode(GhidraFileChooserMode.FILES_ONLY);
fileChooser.setFileSelectionMode(GhidraFileChooser.FILES_ONLY);
fileChooser.setFileFilter(new GhidraFileFilter() { fileChooser.setFileFilter(new GhidraFileFilter() {
@Override @Override
public boolean accept(File file, GhidraFileChooserModel model) { 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 * @param approveToolTip The tool tip for the "Open" button on the file chooser
* @return the archive file path. * @return the archive file path.
*/ */
String chooseArchiveFile(String approveButtonText, String approveToolTip) { private 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); archivePathName);
jarFileChooser.setTitle("Archive a Ghidra Project"); jarFileChooser.setTitle("Archive a Ghidra Project");
}
File jarFile = null; File jarFile = null;
if (archivePathName != null && archivePathName.length() != 0) { if (archivePathName != null && archivePathName.length() != 0) {
jarFile = new File(archivePathName); jarFile = new File(archivePathName);
@ -338,7 +336,7 @@ public class ArchiveDialog extends DialogComponentProvider {
File file = selectedFile; File file = selectedFile;
String chosenPathname = file.getAbsolutePath(); String chosenPathname = file.getAbsolutePath();
String name = file.getName(); String name = file.getName();
if (!NamingUtilities.isValidName(name)) { if (!NamingUtilities.isValidProjectName(name)) {
Msg.showError(getClass(), null, "Invalid Archive Name", Msg.showError(getClass(), null, "Invalid Archive Name",
name + " is not a valid archive name"); name + " is not a valid archive name");
continue; continue;
@ -354,32 +352,7 @@ public class ArchiveDialog extends DialogComponentProvider {
pathname = chosenPathname; pathname = chosenPathname;
} }
jarFileChooser.dispose();
return pathname; 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 archivingListener;
private TaskListener restoringListener; private TaskListener restoringListener;
//////////////////////////////////////////////////////////////////
/** /**
* The archive plugin provides menu action from the front end allowing the * The archive plugin provides menu action from the front end allowing the
* user to archive a project or restore an archived project. * user to archive a project or restore an archived project.
@ -112,36 +110,34 @@ public class ArchivePlugin extends Plugin implements ApplicationLevelOnlyPlugin,
@Override @Override
public void dispose() { public void dispose() {
super.dispose(); super.dispose();
if (archiveDialog != null) {
archiveDialog.dispose();
}
if (restoreDialog != null) {
restoreDialog.dispose();
}
} }
/////////////////////////////////////////////////////////////////////
/**
* @see ghidra.framework.model.ProjectListener#projectClosed(Project)
*/
@Override @Override
public void projectClosed(Project project) { public void projectClosed(Project project) {
archiveAction.setEnabled(false); archiveAction.setEnabled(false);
restoreAction.setEnabled(true); restoreAction.setEnabled(true);
} }
/**
* @see ghidra.framework.model.ProjectListener#projectOpened(Project)
*/
@Override @Override
public void projectOpened(Project project) { public void projectOpened(Project project) {
archiveAction.setEnabled(true); archiveAction.setEnabled(true);
restoreAction.setEnabled(false); restoreAction.setEnabled(false);
} }
/** /*
* for JUnits... * for JUnits...
*/ */
boolean isArchiving() { boolean isArchiving() {
return isArchiving; return isArchiving;
} }
/** /*
* for JUnits... * for JUnits...
*/ */
boolean isRestoring() { boolean isRestoring() {
@ -300,12 +296,6 @@ public class ArchivePlugin extends Plugin implements ApplicationLevelOnlyPlugin,
new TaskLauncher(task, tool.getToolFrame()); 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 { private boolean isJarFormat(File jarFile) throws IOException {
JarInputStream jarIn = new JarInputStream(new FileInputStream(jarFile)); JarInputStream jarIn = new JarInputStream(new FileInputStream(jarFile));
JarEntry entry = jarIn.getNextJarEntry(); JarEntry entry = jarIn.getNextJarEntry();

View file

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

View file

@ -77,7 +77,6 @@ public class BookmarkPlugin extends ProgramPlugin
private BookmarkProvider provider; private BookmarkProvider provider;
private DockingAction addAction; private DockingAction addAction;
private DockingAction deleteAction; private DockingAction deleteAction;
private CreateBookmarkDialog createDialog;
private GoToService goToService; private GoToService goToService;
private MarkerService markerService; private MarkerService markerService;
private BookmarkManager bookmarkMgr; private BookmarkManager bookmarkMgr;
@ -206,10 +205,6 @@ public class BookmarkPlugin extends ProgramPlugin
provider.dispose(); provider.dispose();
provider = null; provider = null;
} }
if (createDialog != null) {
createDialog.dispose();
createDialog = null;
}
goToService = null; goToService = null;
disposeAllBookmarkers(); disposeAllBookmarkers();
@ -444,7 +439,7 @@ public class BookmarkPlugin extends ProgramPlugin
return; return;
} }
boolean hasSelection = currentSelection != null && !currentSelection.isEmpty(); boolean hasSelection = currentSelection != null && !currentSelection.isEmpty();
createDialog = new CreateBookmarkDialog(this, currCU, hasSelection); CreateBookmarkDialog createDialog = new CreateBookmarkDialog(this, currCU, hasSelection);
tool.showDialog(createDialog); 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_CODE_BYTES_NAME = "Clear Code Bytes";
private static final String CLEAR_FLOW_AND_REPAIR = "Clear Flow and Repair"; private static final String CLEAR_FLOW_AND_REPAIR = "Clear Flow and Repair";
private ClearDialog clearDialog;
private ClearFlowDialog clearFlowDialog;
/**
* Constructor
*/
public ClearPlugin(PluginTool tool) { public ClearPlugin(PluginTool tool) {
super(tool); super(tool);
createActions(); createActions();
} }
// /////////////////////////////////////////////////////////////////////
/**
* Clear the flow and repair disassembly at the current location
*/
void clearFlowAndRepair(ListingActionContext context, boolean clearSymbols, boolean clearData, void clearFlowAndRepair(ListingActionContext context, boolean clearSymbols, boolean clearData,
boolean repair) { boolean repair) {
ClearFlowAndRepairCmd cmd; ClearFlowAndRepairCmd cmd;
@ -76,10 +65,6 @@ public class ClearPlugin extends Plugin {
tool.executeBackgroundCommand(cmd, context.getProgram()); 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) { void clear(ClearOptions options, ListingActionContext context) {
if (!options.clearAny()) { if (!options.clearAny()) {
return; return;
@ -258,13 +243,12 @@ public class ClearPlugin extends Plugin {
clear(opts, context); clear(opts, context);
} }
/** /**
* Pop up the clear with options dialog. * Pop up the clear with options dialog.
*/ */
private void showClearAllDialog(ListingActionContext programActionContext) { private void showClearAllDialog(ListingActionContext programActionContext) {
if (clearDialog == null) { ClearDialog clearDialog = new ClearDialog(this);
clearDialog = new ClearDialog(this);
}
clearDialog.setProgramActionContext(programActionContext); clearDialog.setProgramActionContext(programActionContext);
tool.showDialog(clearDialog); tool.showDialog(clearDialog);
} }
@ -273,9 +257,7 @@ public class ClearPlugin extends Plugin {
* Pop up the clear flows dialog * Pop up the clear flows dialog
*/ */
private void showClearFlowDialog(ListingActionContext context) { private void showClearFlowDialog(ListingActionContext context) {
if (clearFlowDialog == null) { ClearFlowDialog clearFlowDialog = new ClearFlowDialog(this);
clearFlowDialog = new ClearFlowDialog(this);
}
clearFlowDialog.setProgramActionContext(context); clearFlowDialog.setProgramActionContext(context);
tool.showDialog(clearFlowDialog); tool.showDialog(clearFlowDialog);
} }

View file

@ -38,7 +38,7 @@ import ghidra.util.HelpLocation;
/** /**
* Dialog for setting the comments for a CodeUnit. * 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 eolField;
private JTextArea preField; private JTextArea preField;

View file

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

View file

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

View file

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

View file

@ -42,14 +42,9 @@ class CreateStructureAction extends ListingContextAction {
private DataPlugin plugin; private DataPlugin plugin;
private CreateStructureDialog createStructureDialog; private CreateStructureDialog createStructureDialog;
/**
* Constructor
* @param name action name
* @param owner owner of this action (the plugin name)
*/
public CreateStructureAction(DataPlugin plugin) { public CreateStructureAction(DataPlugin plugin) {
super("Create Structure", plugin.getName()); super("Create Structure", plugin.getName());
// ACTIONS - auto generated
setPopupMenuData(new MenuData(CREATE_STRUCTURE_POPUP_MENU, null, "BasicData")); setPopupMenuData(new MenuData(CREATE_STRUCTURE_POPUP_MENU, null, "BasicData"));
setKeyBindingData(new KeyBindingData(KeyEvent.VK_OPEN_BRACKET, InputEvent.SHIFT_DOWN_MASK)); 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.BadLocationException;
import javax.swing.text.Document; import javax.swing.text.Document;
import docking.DialogComponentProvider; import docking.ReusableDialogComponentProvider;
import docking.widgets.button.GRadioButton; import docking.widgets.button.GRadioButton;
import docking.widgets.table.*; import docking.widgets.table.*;
import generic.theme.GThemeDefaults.Colors; 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 NEW_STRUCTURE_STATUS_PREFIX = "Creating new structure: ";
private static final String EXISITING_STRUCTURE_STATUS_PREFIX = "Using existing 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 { class RenameDataFieldAction extends ListingContextAction {
private DataPlugin plugin; private DataPlugin plugin;
private RenameDataFieldDialog dialog;
public RenameDataFieldAction(DataPlugin plugin) { public RenameDataFieldAction(DataPlugin plugin) {
super("Rename Data Field", plugin.getName()); super("Rename Data Field", plugin.getName());
dialog = new RenameDataFieldDialog(plugin);
setPopupMenuData( setPopupMenuData(
new MenuData( new MenuData(
@ -54,7 +52,8 @@ class RenameDataFieldAction extends ListingContextAction {
@Override @Override
protected void actionPerformed(ListingActionContext context) { protected void actionPerformed(ListingActionContext context) {
ListingActionContext programActionContext = (ListingActionContext) context.getContextObject(); ListingActionContext programActionContext =
(ListingActionContext) context.getContextObject();
PluginTool tool = plugin.getTool(); PluginTool tool = plugin.getTool();
Program program = programActionContext.getProgram(); Program program = programActionContext.getProgram();
ProgramLocation loc = programActionContext.getLocation(); ProgramLocation loc = programActionContext.getLocation();
@ -67,14 +66,17 @@ class RenameDataFieldAction extends ListingContextAction {
for (int i = 0; i < compPath.length - 1; i++) { for (int i = 0; i < compPath.length - 1; i++) {
DataTypeComponent subComp = comp.getComponent(compPath[i]); DataTypeComponent subComp = comp.getComponent(compPath[i]);
type = subComp.getDataType(); type = subComp.getDataType();
if (type instanceof Composite) if (type instanceof Composite) {
comp = (Composite) type; comp = (Composite) type;
else }
else {
return; return;
} }
}
Data instance = data.getComponent(compPath); Data instance = data.getComponent(compPath);
DataTypeComponent subComp = comp.getComponent(compPath[compPath.length - 1]); DataTypeComponent subComp = comp.getComponent(compPath[compPath.length - 1]);
RenameDataFieldDialog dialog = new RenameDataFieldDialog(plugin);
dialog.setDataComponent(program, subComp, instance.getFieldName()); dialog.setDataComponent(program, subComp, instance.getFieldName());
tool.showDialog(dialog, tool.getComponentProvider(PluginConstants.CODE_BROWSER)); 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.Component;
import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.Clipboard;
import java.awt.event.ActionListener;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
@ -95,7 +94,6 @@ public class DataTypeManagerPlugin extends ProgramPlugin
private DataTypeManagerHandler dataTypeManagerHandler; private DataTypeManagerHandler dataTypeManagerHandler;
private DataTypesProvider provider; private DataTypesProvider provider;
private OpenVersionedFileDialog<DataTypeArchive> openDialog;
private Map<String, DockingAction> recentlyOpenedArchiveMap; private Map<String, DockingAction> recentlyOpenedArchiveMap;
private Map<String, DockingAction> installArchiveMap; private Map<String, DockingAction> installArchiveMap;
@ -366,19 +364,10 @@ public class DataTypeManagerPlugin extends ProgramPlugin
newProvider.setIncludeDataTypeMembersInFilter(provider.includeDataMembersInSearch()); newProvider.setIncludeDataTypeMembersInFilter(provider.includeDataMembersInSearch());
newProvider.setFilteringArrays(provider.isFilteringArrays()); newProvider.setFilteringArrays(provider.isFilteringArrays());
newProvider.setFilteringPointers(provider.isFilteringPointers()); newProvider.setFilteringPointers(provider.isFilteringPointers());
newProvider.setTransient();
return newProvider; 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() { public Program getProgram() {
return currentProgram; return currentProgram;
} }
@ -574,25 +563,24 @@ public class DataTypeManagerPlugin extends ProgramPlugin
} }
public void openProjectDataTypeArchive() { public void openProjectDataTypeArchive() {
if (openDialog == null) {
ActionListener listener = ev -> { OpenVersionedFileDialog<DataTypeArchive> dialog =
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 =
new OpenVersionedFileDialog<>(tool, "Open Project Data Type Archive", new OpenVersionedFileDialog<>(tool, "Open Project Data Type Archive",
DataTypeArchive.class); DataTypeArchive.class);
openDialog.setHelpLocation(new HelpLocation(HelpTopics.PROGRAM, "Open_File_Dialog")); dialog.setHelpLocation(new HelpLocation(HelpTopics.PROGRAM, "Open_File_Dialog"));
openDialog.addOkActionListener(listener); 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 @Override

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -23,7 +23,7 @@ import javax.swing.*;
import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener; import javax.swing.event.DocumentListener;
import docking.DialogComponentProvider; import docking.ReusableDialogComponentProvider;
import docking.action.DockingAction; import docking.action.DockingAction;
import docking.widgets.checkbox.GCheckBox; import docking.widgets.checkbox.GCheckBox;
import docking.widgets.label.GDLabel; import docking.widgets.label.GDLabel;
@ -39,7 +39,7 @@ import ghidra.util.table.*;
import ghidra.util.table.actions.MakeProgramSelectionAction; import ghidra.util.table.actions.MakeProgramSelectionAction;
import ghidra.util.task.Task; 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 int DEFAULT_MINIMUM_TABLE_SIZE = 3;
private static final String DIALOG_NAME = "Search For Address Tables"; 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 TITLE = "Text Editor";
private static final String FONT_ID = "font.plugin.service.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 int MAX_UNDO_REDO_SIZE = 50;
private static final String LAST_SAVED_TEXT_FILE_DIR = "LastSavedTextFileDirectory";
private TextEditorManagerPlugin plugin; private TextEditorManagerPlugin plugin;
private GhidraFileChooser chooser;
private File textFile; private File textFile;
private String textFileName; private String textFileName;
private DockingAction saveAction; private DockingAction saveAction;
@ -146,17 +146,13 @@ public class TextEditorComponentProvider extends ComponentProviderAdapter {
} }
private String loadTextFile(InputStream inputStream) throws IOException { private String loadTextFile(InputStream inputStream) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
try {
return loadTextFile(reader); return loadTextFile(reader);
} }
finally {
reader.close();
}
} }
private String loadTextFile(BufferedReader reader) throws IOException { private String loadTextFile(BufferedReader reader) throws IOException {
StringBuffer buffer = new StringBuffer(); StringBuilder buffer = new StringBuilder();
while (true) { while (true) {
String line = reader.readLine(); String line = reader.readLine();
if (line == null) { if (line == null) {
@ -290,21 +286,25 @@ public class TextEditorComponentProvider extends ComponentProviderAdapter {
} }
catch (IOException e) { catch (IOException e) {
if (textFile.canWrite()) { 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 { else {
Msg.showError(getClass(), getComponent(), "Error Saving File", Msg.showError(getClass(), getComponent(), "Error Saving File",
"The file is not writable."); "The file is not writable");
} }
} }
} }
} }
private void saveAs() { 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(); File saveAsFile = chooser.getSelectedFile();
chooser.dispose();
if (saveAsFile == null) { if (saveAsFile == null) {
return; return;
} }
@ -344,6 +344,7 @@ public class TextEditorComponentProvider extends ComponentProviderAdapter {
public void closeComponent() { public void closeComponent() {
if (plugin.removeTextFile(this, textFileName)) { if (plugin.removeTextFile(this, textFileName)) {
clearUndoRedoStack(); clearUndoRedoStack();
super.closeComponent();
plugin.getTool().removeComponentProvider(this); plugin.getTool().removeComponentProvider(this);
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -25,7 +25,7 @@ import java.util.List;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import docking.DialogComponentProvider; import docking.ReusableDialogComponentProvider;
import generic.theme.GThemeDefaults.Colors.Messages; import generic.theme.GThemeDefaults.Colors.Messages;
import ghidra.app.plugin.core.instructionsearch.model.*; import ghidra.app.plugin.core.instructionsearch.model.*;
import ghidra.app.plugin.core.instructionsearch.ui.SelectionModeWidget.InputMode; 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}. * 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 input text area. This is a generic JTextArea but displays a textual 'hint' to inform
// the user of what type of input is required. // the user of what type of input is required.

View file

@ -22,7 +22,7 @@ import java.util.*;
import javax.swing.*; import javax.swing.*;
import docking.ComponentProvider; import docking.ComponentProvider;
import docking.DialogComponentProvider; import docking.ReusableDialogComponentProvider;
import generic.theme.GColor; import generic.theme.GColor;
import generic.theme.GThemeDefaults.Colors.Messages; import generic.theme.GThemeDefaults.Colors.Messages;
import ghidra.app.events.ProgramSelectionPluginEvent; 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 = private static final Color BG_COLOR_MARKERS =
new GColor("color.bg.plugin.instructionsearch.search.markers"); new GColor("color.bg.plugin.instructionsearch.search.markers");

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -50,7 +50,7 @@ import ghidra.util.task.Task;
* backward searching, proper endianness and whether to find just * backward searching, proper endianness and whether to find just
* the next occurrence or all of them in the program. * 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"; static final String ADVANCED_BUTTON_NAME = "mem.search.advanced";
private static final String CODE_UNIT_SCOPE_NAME = "Code Unit Scope"; 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. * 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; private static final int DEFAULT_MAX_ENTRIES = 10;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -15,13 +15,6 @@
*/ */
package ghidra.app.util; 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 java.awt.*;
import javax.swing.*; import javax.swing.*;
@ -30,6 +23,12 @@ import javax.swing.border.TitledBorder;
import docking.ComponentProvider; import docking.ComponentProvider;
import docking.DialogComponentProvider; 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 { public class EditFieldNameDialog extends DialogComponentProvider {
@ -63,8 +62,6 @@ public class EditFieldNameDialog extends DialogComponentProvider {
setMinimumSize(new Dimension(300, 50)); setMinimumSize(new Dimension(300, 50));
} }
private String getCurrentFieldName() { private String getCurrentFieldName() {
String name = dtComp.getFieldName(); String name = dtComp.getFieldName();
if (name == null) { if (name == null) {
@ -97,9 +94,11 @@ public class EditFieldNameDialog extends DialogComponentProvider {
parent.setLastChangeTime(timeNow); parent.setLastChangeTime(timeNow);
} }
success = true; success = true;
} catch (DuplicateNameException e) { }
catch (DuplicateNameException e) {
setStatusText(e.getMessage()); setStatusText(e.getMessage());
} finally { }
finally {
program.endTransaction(txId, true); program.endTransaction(txId, true);
} }
@ -111,12 +110,14 @@ public class EditFieldNameDialog extends DialogComponentProvider {
} }
public void editField(DataTypeComponent dataTypeComponent, Program p) { 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(); JComponent component = componentProvider.getComponent();
editField(dataTypeComponent, p, component); 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.dtComp = dataTypeComponent;
this.program = p; this.program = p;
String name = getCurrentFieldName(); String name = getCurrentFieldName();

View file

@ -31,7 +31,7 @@ public class OptionsDialog extends DialogComponentProvider implements OptionList
private OptionValidator validator; 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. * such as PE, ELF, XML, etc.
* *
* @param originalOptions the list of options generated from the specific import format selected. * @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; package ghidra.app.util.bin.format.dwarf4.external;
import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.io.File;
import docking.action.builder.ActionBuilder; import docking.action.builder.ActionBuilder;
import docking.tool.ToolConstants; import docking.tool.ToolConstants;
import docking.widgets.filechooser.GhidraFileChooser; import docking.widgets.filechooser.GhidraFileChooser;
@ -70,6 +69,7 @@ public class DWARFExternalDebugFilesPlugin extends Plugin {
chooser.setFileSelectionMode(GhidraFileChooserMode.DIRECTORIES_ONLY); chooser.setFileSelectionMode(GhidraFileChooserMode.DIRECTORIES_ONLY);
chooser.setTitle("Select External Debug Files Directory"); chooser.setTitle("Select External Debug Files Directory");
File selectedDir = chooser.getSelectedFile(); File selectedDir = chooser.getSelectedFile();
chooser.dispose();
if (selectedDir == null) { if (selectedDir == null) {
return; return;
} }

View file

@ -62,8 +62,6 @@ import ghidra.util.task.TaskBuilder;
*/ */
public class ImporterDialog extends DialogComponentProvider { public class ImporterDialog extends DialogComponentProvider {
public static final String LAST_IMPORTFILE_PREFERENCE_KEY = "Importer.LastFile";
protected PluginTool tool; protected PluginTool tool;
private ProgramManager programManager; private ProgramManager programManager;
protected FSRL fsrl; 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 // 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 // will be valid when used later. FSRL paths that drill into container files
// aren't widely supported yet. // aren't widely supported yet.
Preferences.setProperty(LAST_IMPORTFILE_PREFERENCE_KEY, fsrl.getPath()); Preferences.setProperty(Preferences.LAST_IMPORT_FILE, fsrl.getPath());
} }
addWorkPanel(buildWorkPanel()); addWorkPanel(buildWorkPanel());

View file

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

View file

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

View file

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

View file

@ -53,6 +53,8 @@ import ghidra.util.task.TaskLauncher;
public class BatchImportDialog extends DialogComponentProvider { 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 * Shows the batch import dialog (via runSwingLater) and prompts the user to select
* a file if the supplied {@code batchInfo} is empty. * a file if the supplied {@code batchInfo} is empty.
@ -96,7 +98,6 @@ public class BatchImportDialog extends DialogComponentProvider {
private JButton rescanButton; private JButton rescanButton;
private JSpinner maxDepthSpinner; private JSpinner maxDepthSpinner;
private GhidraFileChooser fileChooser;
private SourcesListModel sourceListModel; private SourcesListModel sourceListModel;
private BatchImportDialog(BatchInfo batchInfo, DomainFolder defaultFolder) { private BatchImportDialog(BatchInfo batchInfo, DomainFolder defaultFolder) {
@ -387,20 +388,21 @@ public class BatchImportDialog extends DialogComponentProvider {
} }
private boolean addSources() { 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()) { if (selectedFiles.isEmpty()) {
return !fileChooser.wasCancelled(); return !chooser.wasCancelled();
} }
List<FSRL> filesToAdd = new ArrayList<>(); List<FSRL> filesToAdd = new ArrayList<>();
@ -408,6 +410,8 @@ public class BatchImportDialog extends DialogComponentProvider {
filesToAdd.add(FileSystemService.getInstance().getLocalFSRL(selectedFile)); filesToAdd.add(FileSystemService.getInstance().getLocalFSRL(selectedFile));
} }
chooser.dispose();
return addSources(filesToAdd); return addSources(filesToAdd);
} }

View file

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

View file

@ -15,7 +15,7 @@
*/ */
package ghidra.app.plugin.core.label; package ghidra.app.plugin.core.label;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.*;
import org.junit.*; import org.junit.*;
@ -37,8 +37,6 @@ public class OperandLabelDialogTest extends AbstractGhidraHeadedIntegrationTest
private LabelMgrPlugin plugin; private LabelMgrPlugin plugin;
private CodeBrowserPlugin cb; private CodeBrowserPlugin cb;
private Program program; private Program program;
private OperandLabelDialog dialog;
private GhidraComboBox<?> combo;
private SetOperandLabelAction setLabelAction; private SetOperandLabelAction setLabelAction;
@Before @Before
@ -51,10 +49,6 @@ public class OperandLabelDialogTest extends AbstractGhidraHeadedIntegrationTest
plugin = getPlugin(tool, LabelMgrPlugin.class); plugin = getPlugin(tool, LabelMgrPlugin.class);
cb = getPlugin(tool, CodeBrowserPlugin.class); cb = getPlugin(tool, CodeBrowserPlugin.class);
dialog = runSwing(() -> plugin.getOperandLabelDialog());
combo = (GhidraComboBox<?>) findComponentByName(dialog, "MYCHOICE");
setLabelAction = (SetOperandLabelAction) getAction(plugin, "Set Operand Label"); setLabelAction = (SetOperandLabelAction) getAction(plugin, "Set Operand Label");
} }
@ -80,7 +74,10 @@ public class OperandLabelDialogTest extends AbstractGhidraHeadedIntegrationTest
performAction(setLabelAction, context, false); performAction(setLabelAction, context, false);
waitForSwing(); waitForSwing();
runSwing(() -> combo.setSelectedItem("bob")); OperandLabelDialog dialog = waitForDialogComponent(OperandLabelDialog.class);
GhidraComboBox<?> combo = (GhidraComboBox<?>) findComponentByName(dialog, "MYCHOICE");
setSelectedItem(combo, "bob");
pressButtonByText(dialog, "OK"); pressButtonByText(dialog, "OK");
waitForSwing(); waitForSwing();
@ -94,7 +91,10 @@ public class OperandLabelDialogTest extends AbstractGhidraHeadedIntegrationTest
performAction(setLabelAction, context, false); performAction(setLabelAction, context, false);
waitForSwing(); waitForSwing();
runSwing(() -> combo.setSelectedItem("b")); dialog = waitForDialogComponent(OperandLabelDialog.class);
combo = (GhidraComboBox<?>) findComponentByName(dialog, "MYCHOICE");
setSelectedItem(combo, "b");
pressButtonByText(dialog, "OK"); pressButtonByText(dialog, "OK");
program.flushEvents(); program.flushEvents();
@ -108,4 +108,7 @@ public class OperandLabelDialogTest extends AbstractGhidraHeadedIntegrationTest
assertEquals("dword ptr [b]", cb.getCurrentFieldText()); 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 java.util.Objects;
import docking.widgets.filechooser.GhidraFileChooser; import docking.widgets.filechooser.GhidraFileChooser;
import docking.widgets.filechooser.GhidraFileChooserMode;
import ghidra.bitpatterns.info.ContextRegisterFilter; import ghidra.bitpatterns.info.ContextRegisterFilter;
import ghidra.bitpatterns.info.PatternType; import ghidra.bitpatterns.info.PatternType;
import ghidra.framework.preferences.Preferences; import ghidra.framework.preferences.Preferences;
@ -88,7 +89,7 @@ public class ExportPatternFileActionListener implements ActionListener {
return; return;
} }
GhidraFileChooser gFileChooser = new GhidraFileChooser(component); GhidraFileChooser gFileChooser = new GhidraFileChooser(component);
gFileChooser.setFileSelectionMode(GhidraFileChooser.FILES_ONLY); gFileChooser.setFileSelectionMode(GhidraFileChooserMode.FILES_ONLY);
ExtensionFileFilter xmlFilter = new ExtensionFileFilter("xml", "XML Files"); ExtensionFileFilter xmlFilter = new ExtensionFileFilter("xml", "XML Files");
gFileChooser.setFileFilter(xmlFilter); gFileChooser.setFileFilter(xmlFilter);
String baseDir = Preferences.getProperty(XML_EXPORT_DIR_PROPERTY); String baseDir = Preferences.getProperty(XML_EXPORT_DIR_PROPERTY);
@ -97,11 +98,13 @@ public class ExportPatternFileActionListener implements ActionListener {
} }
gFileChooser.setTitle("Select Export File"); gFileChooser.setTitle("Select Export File");
File outFile = gFileChooser.getSelectedFile(); File outFile = gFileChooser.getSelectedFile();
String lastDirPath = gFileChooser.getCurrentDirectory().getAbsolutePath();
gFileChooser.dispose();
if (gFileChooser.wasCancelled() || outFile == null) { if (gFileChooser.wasCancelled() || outFile == null) {
return; return;
} }
Preferences.setProperty(XML_EXPORT_DIR_PROPERTY,
gFileChooser.getCurrentDirectory().getAbsolutePath()); Preferences.setProperty(XML_EXPORT_DIR_PROPERTY, lastDirPath);
Preferences.store(); Preferences.store();
BitsInputDialogComponentProvider bitsProvider = BitsInputDialogComponentProvider bitsProvider =
new BitsInputDialogComponentProvider(BITS_PROVIDER_MESSAGE); new BitsInputDialogComponentProvider(BITS_PROVIDER_MESSAGE);
@ -115,7 +118,6 @@ public class ExportPatternFileActionListener implements ActionListener {
} }
catch (IOException e1) { catch (IOException e1) {
Msg.showError(this, component, "IO Error", "IO error exporting pattern xml file", 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.action.MenuData;
import docking.tool.ToolConstants; import docking.tool.ToolConstants;
import docking.widgets.filechooser.GhidraFileChooser; import docking.widgets.filechooser.GhidraFileChooser;
import docking.widgets.filechooser.GhidraFileChooserMode;
import docking.widgets.label.GLabel; import docking.widgets.label.GLabel;
import ghidra.bitpatterns.info.*; import ghidra.bitpatterns.info.*;
import ghidra.framework.options.OptionsChangeListener; import ghidra.framework.options.OptionsChangeListener;
@ -227,13 +228,14 @@ public class FunctionBitPatternsMainProvider extends ComponentProviderAdapter
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
GhidraFileChooser fileChooser = new GhidraFileChooser(component); GhidraFileChooser fileChooser = new GhidraFileChooser(component);
fileChooser.setFileSelectionMode(GhidraFileChooser.DIRECTORIES_ONLY); fileChooser.setFileSelectionMode(GhidraFileChooserMode.DIRECTORIES_ONLY);
fileChooser.setTitle("Select Directory Containing XML Files"); fileChooser.setTitle("Select Directory Containing XML Files");
String baseDir = Preferences.getProperty(PATTERN_INFO_DIR); String baseDir = Preferences.getProperty(PATTERN_INFO_DIR);
if (baseDir != null) { if (baseDir != null) {
fileChooser.setCurrentDirectory(new File(baseDir)); fileChooser.setCurrentDirectory(new File(baseDir));
} }
File xmlDir = fileChooser.getSelectedFile(); File xmlDir = fileChooser.getSelectedFile();
fileChooser.dispose();
if (xmlDir == null) { if (xmlDir == null) {
return; return;
} }

View file

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

View file

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

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