mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 02:09:44 +02:00
GP-2986 - ComponentProvder and dialog cleanup on dispose
This commit is contained in:
parent
e5a8f26347
commit
c252e3b905
174 changed files with 1418 additions and 1529 deletions
|
@ -20,13 +20,13 @@ import java.util.Collection;
|
|||
|
||||
import javax.swing.*;
|
||||
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.ReusableDialogComponentProvider;
|
||||
import docking.widgets.table.EnumeratedColumnTableModel;
|
||||
import docking.widgets.table.GTable;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.util.table.GhidraTableFilterPanel;
|
||||
|
||||
public abstract class AbstractDebuggerMapProposalDialog<R> extends DialogComponentProvider {
|
||||
public abstract class AbstractDebuggerMapProposalDialog<R> extends ReusableDialogComponentProvider {
|
||||
|
||||
protected final EnumeratedColumnTableModel<R> tableModel;
|
||||
protected GTable table;
|
||||
|
|
|
@ -24,7 +24,7 @@ import javax.swing.*;
|
|||
import javax.swing.table.TableColumn;
|
||||
import javax.swing.table.TableColumnModel;
|
||||
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.ReusableDialogComponentProvider;
|
||||
import docking.widgets.table.*;
|
||||
import docking.widgets.table.ColumnSortState.SortDirection;
|
||||
import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn;
|
||||
|
@ -38,7 +38,7 @@ import ghidra.trace.model.memory.TraceMemoryRegion;
|
|||
import ghidra.trace.model.modules.TraceSection;
|
||||
import ghidra.util.table.GhidraTableFilterPanel;
|
||||
|
||||
public class DebuggerBlockChooserDialog extends DialogComponentProvider {
|
||||
public class DebuggerBlockChooserDialog extends ReusableDialogComponentProvider {
|
||||
public static class MemoryBlockRow {
|
||||
private final Program program;
|
||||
private final MemoryBlock block;
|
||||
|
|
|
@ -42,14 +42,10 @@ public abstract class DebuggerGoToTrait {
|
|||
|
||||
protected DebuggerCoordinates current = DebuggerCoordinates.NOWHERE;
|
||||
|
||||
protected final DebuggerGoToDialog goToDialog;
|
||||
|
||||
public DebuggerGoToTrait(PluginTool tool, Plugin plugin, ComponentProvider provider) {
|
||||
this.tool = tool;
|
||||
this.plugin = plugin;
|
||||
this.provider = provider;
|
||||
|
||||
goToDialog = new DebuggerGoToDialog(this);
|
||||
}
|
||||
|
||||
protected abstract boolean goToAddress(Address address);
|
||||
|
@ -68,6 +64,7 @@ public abstract class DebuggerGoToTrait {
|
|||
}
|
||||
|
||||
private void activatedGoTo(ActionContext context) {
|
||||
DebuggerGoToDialog goToDialog = new DebuggerGoToDialog(this);
|
||||
TracePlatform platform = current.getPlatform();
|
||||
goToDialog.show((SleighLanguage) platform.getLanguage());
|
||||
}
|
||||
|
|
|
@ -32,19 +32,10 @@ import ghidra.program.util.ProgramSelection;
|
|||
import ghidra.trace.model.program.TraceProgramView;
|
||||
import ghidra.trace.model.program.TraceVariableSnapProgramView;
|
||||
|
||||
@PluginInfo(
|
||||
shortDescription = "Copy and export trace data",
|
||||
description = "Provides tool actions for moving data from traces to various destinations.",
|
||||
category = PluginCategoryNames.DEBUGGER,
|
||||
packageName = DebuggerPluginPackage.NAME,
|
||||
status = PluginStatus.RELEASED,
|
||||
eventsConsumed = {},
|
||||
eventsProduced = {},
|
||||
servicesRequired = {
|
||||
DebuggerStaticMappingService.class,
|
||||
ProgramManager.class,
|
||||
},
|
||||
servicesProvided = {})
|
||||
@PluginInfo(shortDescription = "Copy and export trace data", description = "Provides tool actions for moving data from traces to various destinations.", category = PluginCategoryNames.DEBUGGER, packageName = DebuggerPluginPackage.NAME, status = PluginStatus.RELEASED, eventsConsumed = {}, eventsProduced = {}, servicesRequired = {
|
||||
DebuggerStaticMappingService.class,
|
||||
ProgramManager.class,
|
||||
}, servicesProvided = {})
|
||||
public class DebuggerCopyActionsPlugin extends AbstractDebuggerPlugin {
|
||||
|
||||
protected static ProgramSelection getSelectionFromContext(ActionContext context) {
|
||||
|
@ -75,6 +66,13 @@ public class DebuggerCopyActionsPlugin extends AbstractDebuggerPlugin {
|
|||
createActions();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispose() {
|
||||
super.dispose();
|
||||
|
||||
copyDialog.dispose();
|
||||
}
|
||||
|
||||
protected void createActions() {
|
||||
actionExportView = ExportTraceViewAction.builder(this)
|
||||
.enabled(false)
|
||||
|
|
|
@ -27,7 +27,7 @@ import javax.swing.*;
|
|||
import javax.swing.table.TableColumn;
|
||||
import javax.swing.table.TableColumnModel;
|
||||
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.ReusableDialogComponentProvider;
|
||||
import docking.widgets.table.*;
|
||||
import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn;
|
||||
import ghidra.app.plugin.core.debug.DebuggerCoordinates;
|
||||
|
@ -52,7 +52,7 @@ import ghidra.util.exception.CancelledException;
|
|||
import ghidra.util.table.GhidraTableFilterPanel;
|
||||
import ghidra.util.task.*;
|
||||
|
||||
public class DebuggerCopyIntoProgramDialog extends DialogComponentProvider {
|
||||
public class DebuggerCopyIntoProgramDialog extends ReusableDialogComponentProvider {
|
||||
static final int GAP = 5;
|
||||
static final int BUTTON_SIZE = 32;
|
||||
|
||||
|
|
|
@ -24,24 +24,17 @@ import ghidra.app.services.*;
|
|||
import ghidra.framework.plugintool.*;
|
||||
import ghidra.framework.plugintool.util.PluginStatus;
|
||||
|
||||
@PluginInfo(
|
||||
shortDescription = "Debugger regions manager",
|
||||
description = "GUI to manage memory regions",
|
||||
category = PluginCategoryNames.DEBUGGER,
|
||||
packageName = DebuggerPluginPackage.NAME,
|
||||
status = PluginStatus.RELEASED,
|
||||
eventsConsumed = {
|
||||
ProgramActivatedPluginEvent.class,
|
||||
ProgramLocationPluginEvent.class,
|
||||
ProgramClosedPluginEvent.class,
|
||||
TraceActivatedPluginEvent.class,
|
||||
},
|
||||
servicesRequired = {
|
||||
DebuggerModelService.class,
|
||||
DebuggerStaticMappingService.class,
|
||||
DebuggerTraceManagerService.class,
|
||||
ProgramManager.class,
|
||||
})
|
||||
@PluginInfo(shortDescription = "Debugger regions manager", description = "GUI to manage memory regions", category = PluginCategoryNames.DEBUGGER, packageName = DebuggerPluginPackage.NAME, status = PluginStatus.RELEASED, eventsConsumed = {
|
||||
ProgramActivatedPluginEvent.class,
|
||||
ProgramLocationPluginEvent.class,
|
||||
ProgramClosedPluginEvent.class,
|
||||
TraceActivatedPluginEvent.class,
|
||||
}, servicesRequired = {
|
||||
DebuggerModelService.class,
|
||||
DebuggerStaticMappingService.class,
|
||||
DebuggerTraceManagerService.class,
|
||||
ProgramManager.class,
|
||||
})
|
||||
public class DebuggerRegionsPlugin extends AbstractDebuggerPlugin {
|
||||
protected DebuggerRegionsProvider provider;
|
||||
|
||||
|
@ -58,6 +51,7 @@ public class DebuggerRegionsPlugin extends AbstractDebuggerPlugin {
|
|||
@Override
|
||||
protected void dispose() {
|
||||
tool.removeComponentProvider(provider);
|
||||
provider.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
|
|
@ -204,6 +204,11 @@ public class DebuggerRegionsProvider extends ComponentProviderAdapter {
|
|||
createActions();
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
blockChooserDialog.dispose();
|
||||
regionProposalDialog.dispose();
|
||||
}
|
||||
|
||||
protected void buildMainPanel() {
|
||||
panel = new DebuggerRegionsPanel(this);
|
||||
mainPanel.add(panel);
|
||||
|
|
|
@ -23,7 +23,7 @@ import java.math.BigInteger;
|
|||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.ReusableDialogComponentProvider;
|
||||
import docking.widgets.model.GAddressRangeField;
|
||||
import docking.widgets.model.GSpanField;
|
||||
import ghidra.app.services.DebuggerStaticMappingService;
|
||||
|
@ -36,7 +36,7 @@ import ghidra.trace.model.modules.TraceConflictedMappingException;
|
|||
import ghidra.util.MathUtilities;
|
||||
import ghidra.util.layout.PairLayout;
|
||||
|
||||
public class DebuggerAddMappingDialog extends DialogComponentProvider {
|
||||
public class DebuggerAddMappingDialog extends ReusableDialogComponentProvider {
|
||||
private static final String HEX_BIT64 = "0x" + BigInteger.ONE.shiftLeft(64).toString(16);
|
||||
|
||||
private DebuggerStaticMappingService mappingService;
|
||||
|
|
|
@ -418,7 +418,6 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
|
|||
private final DebuggerBlockChooserDialog blockChooserDialog;
|
||||
private final DebuggerModuleMapProposalDialog moduleProposalDialog;
|
||||
private final DebuggerSectionMapProposalDialog sectionProposalDialog;
|
||||
private DataTreeDialog programChooserDialog; // Already lazy
|
||||
|
||||
private DebuggerCoordinates current = DebuggerCoordinates.NOWHERE;
|
||||
private Program currentProgram;
|
||||
|
@ -470,6 +469,7 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
|
|||
GhidraFileChooser chooser = new GhidraFileChooser(getComponent());
|
||||
chooser.setSelectedFile(new File(module.getName()));
|
||||
File file = chooser.getSelectedFile();
|
||||
chooser.dispose();
|
||||
if (file == null) { // Perhaps cancelled
|
||||
return;
|
||||
}
|
||||
|
@ -511,6 +511,10 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
|
|||
consoleService.removeResolutionAction(actionMapMissingModule);
|
||||
}
|
||||
}
|
||||
|
||||
blockChooserDialog.dispose();
|
||||
moduleProposalDialog.dispose();
|
||||
sectionProposalDialog.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1071,27 +1075,24 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
|
|||
}
|
||||
|
||||
private DataTreeDialog getProgramChooserDialog() {
|
||||
if (programChooserDialog != null) {
|
||||
return programChooserDialog;
|
||||
}
|
||||
|
||||
DomainFileFilter filter = df -> Program.class.isAssignableFrom(df.getDomainObjectClass());
|
||||
|
||||
// TODO regarding the hack note below, I believe it's fixed, but not sure how to test
|
||||
return programChooserDialog =
|
||||
new DataTreeDialog(null, "Map Module to Program", DataTreeDialog.OPEN, filter) {
|
||||
{ // TODO/HACK: I get an NPE setting the default selection if I don't fake this.
|
||||
dialogShown();
|
||||
}
|
||||
};
|
||||
return new DataTreeDialog(null, "Map Module to Program", DataTreeDialog.OPEN, filter) {
|
||||
{ // TODO/HACK: I get an NPE setting the default selection if I don't fake this.
|
||||
dialogShown();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public DomainFile askProgram(Program program) {
|
||||
getProgramChooserDialog();
|
||||
DataTreeDialog dialog = getProgramChooserDialog();
|
||||
if (program != null) {
|
||||
programChooserDialog.selectDomainFile(program.getDomainFile());
|
||||
dialog.selectDomainFile(program.getDomainFile());
|
||||
}
|
||||
tool.showDialog(programChooserDialog);
|
||||
return programChooserDialog.getDomainFile();
|
||||
tool.showDialog(dialog);
|
||||
return dialog.getDomainFile();
|
||||
}
|
||||
|
||||
public Entry<Program, MemoryBlock> askBlock(TraceSection section, Program program,
|
||||
|
|
|
@ -25,20 +25,13 @@ import ghidra.app.services.DebuggerTraceManagerService;
|
|||
import ghidra.framework.plugintool.*;
|
||||
import ghidra.framework.plugintool.util.PluginStatus;
|
||||
|
||||
@PluginInfo(
|
||||
shortDescription = "Debugger static mapping manager",
|
||||
description = "GUI to manage static mappings",
|
||||
category = PluginCategoryNames.DEBUGGER,
|
||||
packageName = DebuggerPluginPackage.NAME,
|
||||
status = PluginStatus.RELEASED,
|
||||
eventsConsumed = {
|
||||
TraceActivatedPluginEvent.class,
|
||||
ProgramActivatedPluginEvent.class,
|
||||
},
|
||||
servicesRequired = {
|
||||
DebuggerStaticMappingService.class,
|
||||
DebuggerTraceManagerService.class,
|
||||
})
|
||||
@PluginInfo(shortDescription = "Debugger static mapping manager", description = "GUI to manage static mappings", category = PluginCategoryNames.DEBUGGER, packageName = DebuggerPluginPackage.NAME, status = PluginStatus.RELEASED, eventsConsumed = {
|
||||
TraceActivatedPluginEvent.class,
|
||||
ProgramActivatedPluginEvent.class,
|
||||
}, servicesRequired = {
|
||||
DebuggerStaticMappingService.class,
|
||||
DebuggerTraceManagerService.class,
|
||||
})
|
||||
public class DebuggerStaticMappingPlugin extends AbstractDebuggerPlugin {
|
||||
protected DebuggerStaticMappingProvider provider;
|
||||
|
||||
|
@ -55,6 +48,7 @@ public class DebuggerStaticMappingPlugin extends AbstractDebuggerPlugin {
|
|||
@Override
|
||||
protected void dispose() {
|
||||
tool.removeComponentProvider(provider);
|
||||
provider.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
|
|
@ -176,6 +176,10 @@ public class DebuggerStaticMappingProvider extends ComponentProviderAdapter
|
|||
createActions();
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
addMappingDialog.dispose();
|
||||
}
|
||||
|
||||
@AutoServiceConsumed
|
||||
private void setMappingService(DebuggerStaticMappingService mappingService) {
|
||||
addMappingDialog.setMappingService(mappingService);
|
||||
|
|
|
@ -132,9 +132,7 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter
|
|||
@SuppressWarnings("unused")
|
||||
private final AutoService.Wiring autoServiceWiring;
|
||||
|
||||
@AutoOptionDefined(
|
||||
name = "Default Extended Step",
|
||||
description = "The default string for the extended step command")
|
||||
@AutoOptionDefined(name = "Default Extended Step", description = "The default string for the extended step command")
|
||||
String extendedStep = "";
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
|
@ -244,6 +242,16 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter
|
|||
repeatLastSet.run();
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
// TODO This is not currently called, since the clients of this provider to not hold onto
|
||||
// the provider after creation. Ideally, these providers should either be tracked and
|
||||
// disposed, or this provider should perform cleanup on itself when it is no longer used.
|
||||
configDialog.dispose();
|
||||
methodDialog.dispose();
|
||||
attachDialog.dispose();
|
||||
breakpointDialog.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLocalAction(DockingActionIf action) {
|
||||
super.addLocalAction(action);
|
||||
|
|
|
@ -78,6 +78,7 @@ public abstract class ImportExportAsAction extends DockingAction {
|
|||
chooser.setCurrentDirectory(Application.getUserSettingsDirectory());
|
||||
|
||||
File f = chooser.getSelectedFile();
|
||||
chooser.dispose();
|
||||
if (chooser.wasCancelled() || f == null) { // Redundant? Meh, it's cheap.
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
*/
|
||||
package ghidra.app.plugin.core.debug.gui.objects.components;
|
||||
|
||||
import static ghidra.app.plugin.core.debug.gui.DebuggerResources.GROUP_GENERAL;
|
||||
import static ghidra.app.plugin.core.debug.gui.DebuggerResources.tableRowActivationAction;
|
||||
import static ghidra.app.plugin.core.debug.gui.DebuggerResources.*;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.util.List;
|
||||
|
@ -26,7 +25,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||
import javax.swing.*;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.ReusableDialogComponentProvider;
|
||||
import docking.action.ToolBarData;
|
||||
import docking.widgets.table.*;
|
||||
import ghidra.app.plugin.core.debug.gui.DebuggerResources.AbstractAttachAction;
|
||||
|
@ -40,7 +39,7 @@ import ghidra.util.MessageType;
|
|||
import ghidra.util.Msg;
|
||||
import ghidra.util.table.GhidraTableFilterPanel;
|
||||
|
||||
public class DebuggerAttachDialog extends DialogComponentProvider {
|
||||
public class DebuggerAttachDialog extends ReusableDialogComponentProvider {
|
||||
|
||||
protected class RefreshAction extends AbstractRefreshAction {
|
||||
public static final String GROUP = GROUP_GENERAL;
|
||||
|
|
|
@ -26,7 +26,7 @@ import javax.swing.table.TableColumn;
|
|||
import javax.swing.table.TableColumnModel;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.ReusableDialogComponentProvider;
|
||||
import docking.action.DockingAction;
|
||||
import docking.widgets.table.DefaultEnumeratedColumnTableModel;
|
||||
import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn;
|
||||
|
@ -37,7 +37,7 @@ import ghidra.program.model.lang.Language;
|
|||
import ghidra.program.model.lang.Register;
|
||||
import ghidra.util.table.GhidraTableFilterPanel;
|
||||
|
||||
public class DebuggerAvailableRegistersDialog extends DialogComponentProvider {
|
||||
public class DebuggerAvailableRegistersDialog extends ReusableDialogComponentProvider {
|
||||
|
||||
protected enum AvailableRegisterTableColumns
|
||||
implements EnumeratedTableColumn<AvailableRegisterTableColumns, AvailableRegisterRow> {
|
||||
|
|
|
@ -553,6 +553,8 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
|
|||
|
||||
@Override
|
||||
public void removeFromTool() {
|
||||
availableRegsDialog.dispose();
|
||||
|
||||
plugin.providerRemoved(this);
|
||||
plugin.getTool().removePopupActionProvider(this);
|
||||
super.removeFromTool();
|
||||
|
@ -1296,7 +1298,8 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
|
|||
return AsyncUtils.NIL;
|
||||
}
|
||||
toRead.retainAll(regMapper.getRegistersOnTarget());
|
||||
Set<TargetRegisterBank> banks = recorder.getTargetRegisterBanks(traceThread, current.getFrame());
|
||||
Set<TargetRegisterBank> banks =
|
||||
recorder.getTargetRegisterBanks(traceThread, current.getFrame());
|
||||
if (banks == null || banks.isEmpty()) {
|
||||
Msg.error(this, "Current frame's bank does not exist");
|
||||
return AsyncUtils.NIL;
|
||||
|
|
|
@ -31,7 +31,7 @@ import javax.swing.text.View;
|
|||
import org.apache.commons.collections4.BidiMap;
|
||||
import org.apache.commons.collections4.bidimap.DualLinkedHashBidiMap;
|
||||
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.ReusableDialogComponentProvider;
|
||||
import ghidra.app.plugin.core.debug.gui.DebuggerResources.AbstractConnectAction;
|
||||
import ghidra.app.plugin.core.debug.utils.MiscellaneousUtils;
|
||||
import ghidra.app.services.DebuggerModelService;
|
||||
|
@ -45,7 +45,7 @@ import ghidra.program.model.listing.Program;
|
|||
import ghidra.util.*;
|
||||
import ghidra.util.datastruct.CollectionChangeListener;
|
||||
|
||||
public class DebuggerConnectDialog extends DialogComponentProvider
|
||||
public class DebuggerConnectDialog extends ReusableDialogComponentProvider
|
||||
implements PropertyChangeListener {
|
||||
private static final String KEY_CURRENT_FACTORY_CLASSNAME = "currentFactoryCls";
|
||||
private static final String KEY_SUCCESS_FACTORY_CLASSNAME = "successFactoryCls";
|
||||
|
|
|
@ -62,15 +62,8 @@ import ghidra.util.classfinder.ClassSearcher;
|
|||
import ghidra.util.datastruct.CollectionChangeListener;
|
||||
import ghidra.util.datastruct.ListenerSet;
|
||||
|
||||
@PluginInfo(
|
||||
shortDescription = "Debugger models manager service",
|
||||
description = "Manage debug sessions, connections, and trace recording",
|
||||
category = PluginCategoryNames.DEBUGGER,
|
||||
packageName = DebuggerPluginPackage.NAME,
|
||||
status = PluginStatus.HIDDEN,
|
||||
servicesRequired = {},
|
||||
servicesProvided = {
|
||||
DebuggerModelService.class, })
|
||||
@PluginInfo(shortDescription = "Debugger models manager service", description = "Manage debug sessions, connections, and trace recording", category = PluginCategoryNames.DEBUGGER, packageName = DebuggerPluginPackage.NAME, status = PluginStatus.HIDDEN, servicesRequired = {}, servicesProvided = {
|
||||
DebuggerModelService.class, })
|
||||
public class DebuggerModelServicePlugin extends Plugin
|
||||
implements DebuggerModelServiceInternal, ApplicationLevelOnlyPlugin {
|
||||
|
||||
|
@ -184,6 +177,14 @@ public class DebuggerModelServicePlugin extends Plugin
|
|||
createActions();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispose() {
|
||||
super.dispose();
|
||||
|
||||
connectDialog.dispose();
|
||||
offerDialog.dispose();
|
||||
}
|
||||
|
||||
protected void createActions() {
|
||||
actionDisconnectAll = DisconnectAllAction.builder(this, this)
|
||||
.menuPath("Debugger", DisconnectAllAction.NAME)
|
||||
|
|
|
@ -23,7 +23,7 @@ import java.util.function.Function;
|
|||
|
||||
import javax.swing.*;
|
||||
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.ReusableDialogComponentProvider;
|
||||
import docking.widgets.table.*;
|
||||
import docking.widgets.table.ColumnSortState.SortDirection;
|
||||
import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn;
|
||||
|
@ -35,7 +35,7 @@ import ghidra.program.util.DefaultLanguageService;
|
|||
import ghidra.util.table.GhidraTable;
|
||||
import ghidra.util.table.GhidraTableFilterPanel;
|
||||
|
||||
public class DebuggerSelectMappingOfferDialog extends DialogComponentProvider {
|
||||
public class DebuggerSelectMappingOfferDialog extends ReusableDialogComponentProvider {
|
||||
|
||||
protected enum OfferTableColumns
|
||||
implements EnumeratedTableColumn<OfferTableColumns, DebuggerMappingOffer> {
|
||||
|
|
|
@ -66,26 +66,17 @@ import ghidra.util.datastruct.CollectionChangeListener;
|
|||
import ghidra.util.exception.*;
|
||||
import ghidra.util.task.*;
|
||||
|
||||
@PluginInfo(
|
||||
shortDescription = "Debugger Trace View Management Plugin",
|
||||
description = "Manages UI Components, Wrappers, Focus, etc.",
|
||||
category = PluginCategoryNames.DEBUGGER,
|
||||
packageName = DebuggerPluginPackage.NAME,
|
||||
status = PluginStatus.RELEASED,
|
||||
eventsProduced = {
|
||||
TraceActivatedPluginEvent.class,
|
||||
},
|
||||
eventsConsumed = {
|
||||
TraceActivatedPluginEvent.class,
|
||||
TraceClosedPluginEvent.class,
|
||||
ModelObjectFocusedPluginEvent.class,
|
||||
TraceRecorderAdvancedPluginEvent.class,
|
||||
DebuggerPlatformPluginEvent.class,
|
||||
},
|
||||
servicesRequired = {},
|
||||
servicesProvided = {
|
||||
DebuggerTraceManagerService.class,
|
||||
})
|
||||
@PluginInfo(shortDescription = "Debugger Trace View Management Plugin", description = "Manages UI Components, Wrappers, Focus, etc.", category = PluginCategoryNames.DEBUGGER, packageName = DebuggerPluginPackage.NAME, status = PluginStatus.RELEASED, eventsProduced = {
|
||||
TraceActivatedPluginEvent.class,
|
||||
}, eventsConsumed = {
|
||||
TraceActivatedPluginEvent.class,
|
||||
TraceClosedPluginEvent.class,
|
||||
ModelObjectFocusedPluginEvent.class,
|
||||
TraceRecorderAdvancedPluginEvent.class,
|
||||
DebuggerPlatformPluginEvent.class,
|
||||
}, servicesRequired = {}, servicesProvided = {
|
||||
DebuggerTraceManagerService.class,
|
||||
})
|
||||
public class DebuggerTraceManagerServicePlugin extends Plugin
|
||||
implements DebuggerTraceManagerService {
|
||||
|
||||
|
@ -277,8 +268,6 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
|
|||
@SuppressWarnings("unused")
|
||||
private final AutoService.Wiring autoServiceWiring;
|
||||
|
||||
private DataTreeDialog traceChooserDialog;
|
||||
|
||||
DockingAction actionCloseTrace;
|
||||
DockingAction actionCloseAllTraces;
|
||||
DockingAction actionCloseOtherTraces;
|
||||
|
@ -388,9 +377,7 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
|
|||
}
|
||||
|
||||
protected DataTreeDialog getTraceChooserDialog() {
|
||||
if (traceChooserDialog != null) {
|
||||
return traceChooserDialog;
|
||||
}
|
||||
|
||||
DomainFileFilter filter = new DomainFileFilter() {
|
||||
|
||||
@Override
|
||||
|
@ -405,21 +392,20 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
|
|||
};
|
||||
|
||||
// TODO regarding the hack note below, I believe this issue ahs been fixed, but not sure how to test
|
||||
return traceChooserDialog =
|
||||
new DataTreeDialog(null, OpenTraceAction.NAME, DataTreeDialog.OPEN, filter) {
|
||||
{ // TODO/HACK: Why the NPE if I don't do this?
|
||||
dialogShown();
|
||||
}
|
||||
};
|
||||
return new DataTreeDialog(null, OpenTraceAction.NAME, DataTreeDialog.OPEN, filter) {
|
||||
{ // TODO/HACK: Why the NPE if I don't do this?
|
||||
dialogShown();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public DomainFile askTrace(Trace trace) {
|
||||
getTraceChooserDialog();
|
||||
DataTreeDialog dialog = getTraceChooserDialog();
|
||||
if (trace != null) {
|
||||
traceChooserDialog.selectDomainFile(trace.getDomainFile());
|
||||
dialog.selectDomainFile(trace.getDomainFile());
|
||||
}
|
||||
tool.showDialog(traceChooserDialog);
|
||||
return traceChooserDialog.getDomainFile();
|
||||
tool.showDialog(dialog);
|
||||
return dialog.getDomainFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -24,7 +24,7 @@ import javax.swing.*;
|
|||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.ReusableDialogComponentProvider;
|
||||
import docking.action.DockingAction;
|
||||
import docking.action.builder.ActionBuilder;
|
||||
import docking.widgets.combobox.GComboBox;
|
||||
|
@ -50,7 +50,7 @@ import ghidra.util.task.*;
|
|||
* for learning function starts, train models, see performance statistics, and
|
||||
* apply the models.
|
||||
*/
|
||||
public class FunctionStartRFParamsDialog extends DialogComponentProvider {
|
||||
public class FunctionStartRFParamsDialog extends ReusableDialogComponentProvider {
|
||||
|
||||
private static final String INITIAL_BYTES_TEXT = "Number of Initial Bytes (CSV)";
|
||||
private static final String INITIAL_BYTES_TIP =
|
||||
|
|
|
@ -96,6 +96,15 @@ public class RandomForestFunctionFinderPlugin extends ProgramPlugin
|
|||
initOptions(getTool().getOptions("Random Forest Function Finder"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispose() {
|
||||
super.dispose();
|
||||
|
||||
if (paramsDialog != null) {
|
||||
paramsDialog.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void optionsChanged(ToolOptions options, String optionName, Object oldValue,
|
||||
Object newValue) throws OptionsVetoException {
|
||||
|
|
|
@ -69,6 +69,7 @@ public class SampleTableProvider extends ComponentProviderAdapter implements Opt
|
|||
|
||||
void dispose() {
|
||||
filterTable.dispose();
|
||||
fileChooserPanel.dispose();
|
||||
removeFromTool();
|
||||
}
|
||||
|
||||
|
|
|
@ -192,7 +192,6 @@ src/main/help/help/topics/DataTypeManagerPlugin/data_type_manager_archives.html|
|
|||
src/main/help/help/topics/DataTypeManagerPlugin/data_type_manager_description.htm||GHIDRA||||END|
|
||||
src/main/help/help/topics/DataTypeManagerPlugin/data_type_manager_window.html||GHIDRA||||END|
|
||||
src/main/help/help/topics/DataTypeManagerPlugin/images/CommitDialog.png||GHIDRA||||END|
|
||||
src/main/help/help/topics/DataTypeManagerPlugin/images/DataTypeConflict.png||GHIDRA||||END|
|
||||
src/main/help/help/topics/DataTypeManagerPlugin/images/DataTypeManager.png||GHIDRA||||END|
|
||||
src/main/help/help/topics/DataTypeManagerPlugin/images/DisassociateDialog.png||GHIDRA||||END|
|
||||
src/main/help/help/topics/DataTypeManagerPlugin/images/EditPaths.png||GHIDRA||||END|
|
||||
|
|
|
@ -991,35 +991,6 @@
|
|||
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<H3><A name="DataTypeConflicts"></A>Handling Data Type Conflicts</H3>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<P>When you move or copy a data type to a category that has a data type with the same
|
||||
name, a conflict occurs. If the data types are not the same, then a dialog is displayed
|
||||
in order to resolve the conflict, as shown below:</P>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<P align="center"><IMG src="images/DataTypeConflict.png" alt="" border="0"></P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<P>In this example, you dragged (or pasted) the data type "SIZE_T" from one category to
|
||||
the /basetsd.h category; the one being dragged is different from the one that already
|
||||
exists in the /basetsd.h category. The choices to resolve the conflict are:</P>
|
||||
|
||||
<OL>
|
||||
<LI><I>Rename</I> the data type that you are dragging to have ".conflict" appended to
|
||||
it to make a unique name.</LI>
|
||||
|
||||
<LI><I>Replace</I> the existing data type with the new one;
|
||||
this means any use of the existing data types is <B><I>replaced</I></B> with the new
|
||||
data type; the existing data type is deleted.</LI>
|
||||
|
||||
<LI>Use the existing data type; if you did a cut/paste or drag/move operation, the
|
||||
"cut" or "dragged" data type is removed from its original category; the destination
|
||||
category is unaffected.</LI>
|
||||
</OL>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<H3><A name="ReplaceDataType"></A>Replacing a Data Type</H3>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 14 KiB |
|
@ -20,9 +20,10 @@ import java.io.File;
|
|||
|
||||
import javax.swing.*;
|
||||
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.ReusableDialogComponentProvider;
|
||||
import docking.widgets.OptionDialog;
|
||||
import docking.widgets.filechooser.GhidraFileChooser;
|
||||
import docking.widgets.filechooser.GhidraFileChooserMode;
|
||||
import docking.widgets.label.GDLabel;
|
||||
import ghidra.framework.GenericRunInfo;
|
||||
import ghidra.framework.model.ProjectLocator;
|
||||
|
@ -32,10 +33,9 @@ import ghidra.util.filechooser.GhidraFileChooserModel;
|
|||
import ghidra.util.filechooser.GhidraFileFilter;
|
||||
|
||||
/**
|
||||
* Dialog to prompt the user for the project to archive and the file to archive
|
||||
* it to.
|
||||
* Dialog to prompt the user for the project to archive and the file to archive it to.
|
||||
*/
|
||||
public class ArchiveDialog extends DialogComponentProvider {
|
||||
public class ArchiveDialog extends ReusableDialogComponentProvider {
|
||||
private static final int NUM_TEXT_COLUMNS = 40;
|
||||
|
||||
private boolean actionComplete;
|
||||
|
@ -43,14 +43,12 @@ public class ArchiveDialog extends DialogComponentProvider {
|
|||
private JTextField archiveField;
|
||||
private JButton archiveBrowse;
|
||||
|
||||
private GhidraFileChooser jarFileChooser;
|
||||
private ProjectLocator projectLocator;
|
||||
private String archivePathName;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param parent the parent frame of the NumberInputDialog.
|
||||
* @param plugin the archive plugin using this dialog.
|
||||
*/
|
||||
ArchiveDialog(ArchivePlugin plugin) {
|
||||
|
@ -179,6 +177,7 @@ public class ArchiveDialog extends DialogComponentProvider {
|
|||
* Display this dialog.
|
||||
* @param pProjectLocator the project URL to display when the dialog pops up.
|
||||
* @param pArchivePathName the archive file name to display when the dialog pops up.
|
||||
* @param tool the tool
|
||||
*
|
||||
* @return true if the user submitted valid values for the project and
|
||||
* archive file, false if user cancelled.
|
||||
|
@ -237,7 +236,7 @@ public class ArchiveDialog extends DialogComponentProvider {
|
|||
|
||||
File file = new File(pathname);
|
||||
String name = file.getName();
|
||||
if (!isValidName(name)) {
|
||||
if (!NamingUtilities.isValidProjectName(name)) {
|
||||
setStatusText("Archive name contains invalid characters.");
|
||||
return false;
|
||||
}
|
||||
|
@ -256,8 +255,7 @@ public class ArchiveDialog extends DialogComponentProvider {
|
|||
String filePathName) {
|
||||
|
||||
GhidraFileChooser fileChooser = new GhidraFileChooser(getComponent());
|
||||
|
||||
fileChooser.setFileSelectionMode(GhidraFileChooser.FILES_ONLY);
|
||||
fileChooser.setFileSelectionMode(GhidraFileChooserMode.FILES_ONLY);
|
||||
fileChooser.setFileFilter(new GhidraFileFilter() {
|
||||
@Override
|
||||
public boolean accept(File file, GhidraFileChooserModel model) {
|
||||
|
@ -310,12 +308,12 @@ public class ArchiveDialog extends DialogComponentProvider {
|
|||
* @param approveToolTip The tool tip for the "Open" button on the file chooser
|
||||
* @return the archive file path.
|
||||
*/
|
||||
String chooseArchiveFile(String approveButtonText, String approveToolTip) {
|
||||
if (jarFileChooser == null) {
|
||||
jarFileChooser = createFileChooser(ArchivePlugin.ARCHIVE_EXTENSION, "Ghidra Archives",
|
||||
private String chooseArchiveFile(String approveButtonText, String approveToolTip) {
|
||||
|
||||
GhidraFileChooser jarFileChooser =
|
||||
createFileChooser(ArchivePlugin.ARCHIVE_EXTENSION, "Ghidra Archives",
|
||||
archivePathName);
|
||||
jarFileChooser.setTitle("Archive a Ghidra Project");
|
||||
}
|
||||
jarFileChooser.setTitle("Archive a Ghidra Project");
|
||||
File jarFile = null;
|
||||
if (archivePathName != null && archivePathName.length() != 0) {
|
||||
jarFile = new File(archivePathName);
|
||||
|
@ -338,7 +336,7 @@ public class ArchiveDialog extends DialogComponentProvider {
|
|||
File file = selectedFile;
|
||||
String chosenPathname = file.getAbsolutePath();
|
||||
String name = file.getName();
|
||||
if (!NamingUtilities.isValidName(name)) {
|
||||
if (!NamingUtilities.isValidProjectName(name)) {
|
||||
Msg.showError(getClass(), null, "Invalid Archive Name",
|
||||
name + " is not a valid archive name");
|
||||
continue;
|
||||
|
@ -354,32 +352,7 @@ public class ArchiveDialog extends DialogComponentProvider {
|
|||
|
||||
pathname = chosenPathname;
|
||||
}
|
||||
|
||||
jarFileChooser.dispose();
|
||||
return pathname;
|
||||
}
|
||||
|
||||
/**
|
||||
* tests whether the given string is a valid name.
|
||||
* @param name name to validate
|
||||
*/
|
||||
public boolean isValidName(String name) {
|
||||
if (name == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((name.length() < 1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < name.length(); i++) {
|
||||
char c = name.charAt(i);
|
||||
if (!Character.isLetterOrDigit(c) && c != '.' && c != '-' && c != ' ' && c != '_' &&
|
||||
c != '\\' && c != '~' && c != '/' && c != ':') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -96,8 +96,6 @@ public class ArchivePlugin extends Plugin implements ApplicationLevelOnlyPlugin,
|
|||
private TaskListener archivingListener;
|
||||
private TaskListener restoringListener;
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* The archive plugin provides menu action from the front end allowing the
|
||||
* user to archive a project or restore an archived project.
|
||||
|
@ -112,36 +110,34 @@ public class ArchivePlugin extends Plugin implements ApplicationLevelOnlyPlugin,
|
|||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
if (archiveDialog != null) {
|
||||
archiveDialog.dispose();
|
||||
}
|
||||
if (restoreDialog != null) {
|
||||
restoreDialog.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @see ghidra.framework.model.ProjectListener#projectClosed(Project)
|
||||
*/
|
||||
@Override
|
||||
public void projectClosed(Project project) {
|
||||
archiveAction.setEnabled(false);
|
||||
restoreAction.setEnabled(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.framework.model.ProjectListener#projectOpened(Project)
|
||||
*/
|
||||
@Override
|
||||
public void projectOpened(Project project) {
|
||||
archiveAction.setEnabled(true);
|
||||
restoreAction.setEnabled(false);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* for JUnits...
|
||||
*/
|
||||
boolean isArchiving() {
|
||||
return isArchiving;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* for JUnits...
|
||||
*/
|
||||
boolean isRestoring() {
|
||||
|
@ -300,12 +296,6 @@ public class ArchivePlugin extends Plugin implements ApplicationLevelOnlyPlugin,
|
|||
new TaskLauncher(task, tool.getToolFrame());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the jar file contains the JAR_FORMAT tag to indicate
|
||||
* the new jar file format.
|
||||
* @param jarFile
|
||||
* @throws IOException
|
||||
*/
|
||||
private boolean isJarFormat(File jarFile) throws IOException {
|
||||
JarInputStream jarIn = new JarInputStream(new FileInputStream(jarFile));
|
||||
JarEntry entry = jarIn.getNextJarEntry();
|
||||
|
|
|
@ -22,8 +22,9 @@ import java.io.File;
|
|||
|
||||
import javax.swing.*;
|
||||
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.ReusableDialogComponentProvider;
|
||||
import docking.widgets.filechooser.GhidraFileChooser;
|
||||
import docking.widgets.filechooser.GhidraFileChooserMode;
|
||||
import docking.widgets.label.GDLabel;
|
||||
import ghidra.framework.GenericRunInfo;
|
||||
import ghidra.framework.model.ProjectLocator;
|
||||
|
@ -35,7 +36,7 @@ import ghidra.util.filechooser.ExtensionFileFilter;
|
|||
* Dialog to prompt the user for the archive file to restore
|
||||
* and where to restore it to.
|
||||
*/
|
||||
public class RestoreDialog extends DialogComponentProvider {
|
||||
public class RestoreDialog extends ReusableDialogComponentProvider {
|
||||
/**
|
||||
* Preference name for directory last selected to choose a jar file
|
||||
* to restore.
|
||||
|
@ -54,14 +55,12 @@ public class RestoreDialog extends DialogComponentProvider {
|
|||
private JButton restoreBrowse;
|
||||
private JLabel projectNameLabel;
|
||||
private JTextField projectNameField;
|
||||
private GhidraFileChooser jarFileChooser;
|
||||
private GhidraFileChooser dirChooser;
|
||||
|
||||
private String archivePathName;
|
||||
private ProjectLocator restoreURL;
|
||||
|
||||
public RestoreDialog(ArchivePlugin plugin) {
|
||||
super("Restore Project Archive", true);
|
||||
super("Restore Project Archive");
|
||||
this.plugin = plugin;
|
||||
initialize();
|
||||
|
||||
|
@ -374,10 +373,9 @@ public class RestoreDialog extends DialogComponentProvider {
|
|||
GhidraFileChooser fileChooser = new GhidraFileChooser(null);
|
||||
// start the browsing in the user's preferred project directory
|
||||
File projectDirectory = new File(GenericRunInfo.getProjectsDirPath());
|
||||
fileChooser.setFileSelectionMode(GhidraFileChooser.DIRECTORIES_ONLY);
|
||||
fileChooser.setFileSelectionMode(GhidraFileChooserMode.DIRECTORIES_ONLY);
|
||||
fileChooser.setCurrentDirectory(projectDirectory);
|
||||
fileChooser.setSelectedFile(projectDirectory);
|
||||
|
||||
return fileChooser;
|
||||
}
|
||||
|
||||
|
@ -386,19 +384,19 @@ public class RestoreDialog extends DialogComponentProvider {
|
|||
* filename that are used for the Project location and name
|
||||
* @param approveButtonText The label for the "Open" button on the file chooser
|
||||
* @param approveToolTip The tool tip for the "Open" button on the file chooser
|
||||
* @return the archive filepath.
|
||||
* @return the archive file path.
|
||||
*/
|
||||
String chooseArchiveFile(String approveButtonText, String approveToolTip) {
|
||||
if (jarFileChooser == null) {
|
||||
jarFileChooser = createFileChooser(ArchivePlugin.ARCHIVE_EXTENSION, "Ghidra Archives",
|
||||
|
||||
GhidraFileChooser jarFileChooser =
|
||||
createFileChooser(ArchivePlugin.ARCHIVE_EXTENSION, "Ghidra Archives",
|
||||
archivePathName);
|
||||
jarFileChooser.setTitle("Restore a Ghidra Project - Archive");
|
||||
String lastDirSelected = Preferences.getProperty(ArchivePlugin.LAST_ARCHIVE_DIR);
|
||||
if (lastDirSelected != null) {
|
||||
File file = new File(lastDirSelected);
|
||||
if (file.exists()) {
|
||||
jarFileChooser.setCurrentDirectory(file);
|
||||
}
|
||||
jarFileChooser.setTitle("Restore a Ghidra Project - Archive");
|
||||
String lastDirSelected = Preferences.getProperty(ArchivePlugin.LAST_ARCHIVE_DIR);
|
||||
if (lastDirSelected != null) {
|
||||
File file = new File(lastDirSelected);
|
||||
if (file.exists()) {
|
||||
jarFileChooser.setCurrentDirectory(file);
|
||||
}
|
||||
}
|
||||
File jarFile = null;
|
||||
|
@ -419,7 +417,7 @@ public class RestoreDialog extends DialogComponentProvider {
|
|||
|
||||
File file = selectedFile;
|
||||
String chosenName = file.getName();
|
||||
if (!NamingUtilities.isValidName(chosenName)) {
|
||||
if (!NamingUtilities.isValidProjectName(chosenName)) {
|
||||
Msg.showError(getClass(), null, "Invalid Archive Name",
|
||||
chosenName + " is not a valid archive name");
|
||||
continue;
|
||||
|
@ -428,6 +426,9 @@ public class RestoreDialog extends DialogComponentProvider {
|
|||
Preferences.setProperty(ArchivePlugin.LAST_ARCHIVE_DIR, file.getParent());
|
||||
pathname = file.getAbsolutePath();
|
||||
}
|
||||
|
||||
jarFileChooser.dispose();
|
||||
|
||||
return pathname;
|
||||
}
|
||||
|
||||
|
@ -436,13 +437,11 @@ public class RestoreDialog extends DialogComponentProvider {
|
|||
* project archive will be restored.
|
||||
* @param approveButtonText The label for the "Open" button on the file chooser
|
||||
* @param approveToolTip The tool tip for the "Open" button on the file chooser
|
||||
* @return the restore directory filepath.
|
||||
* @return the restore directory file path.
|
||||
*/
|
||||
String chooseDirectory(String approveButtonText, String approveToolTip) {
|
||||
if (dirChooser == null) {
|
||||
dirChooser = createDirectoryChooser();
|
||||
dirChooser.setTitle("Restore a Ghidra Project - Directory");
|
||||
}
|
||||
GhidraFileChooser dirChooser = createDirectoryChooser();
|
||||
dirChooser.setTitle("Restore a Ghidra Project - Directory");
|
||||
if (restoreURL != null) {
|
||||
dirChooser.setSelectedFile(new File(restoreURL.getLocation()));
|
||||
}
|
||||
|
@ -450,6 +449,7 @@ public class RestoreDialog extends DialogComponentProvider {
|
|||
dirChooser.setApproveButtonToolTipText(approveToolTip);
|
||||
|
||||
File selectedFile = dirChooser.getSelectedFile(true);
|
||||
dirChooser.dispose();
|
||||
if (selectedFile != null) {
|
||||
return selectedFile.getAbsolutePath();
|
||||
}
|
||||
|
|
|
@ -77,7 +77,6 @@ public class BookmarkPlugin extends ProgramPlugin
|
|||
private BookmarkProvider provider;
|
||||
private DockingAction addAction;
|
||||
private DockingAction deleteAction;
|
||||
private CreateBookmarkDialog createDialog;
|
||||
private GoToService goToService;
|
||||
private MarkerService markerService;
|
||||
private BookmarkManager bookmarkMgr;
|
||||
|
@ -206,10 +205,6 @@ public class BookmarkPlugin extends ProgramPlugin
|
|||
provider.dispose();
|
||||
provider = null;
|
||||
}
|
||||
if (createDialog != null) {
|
||||
createDialog.dispose();
|
||||
createDialog = null;
|
||||
}
|
||||
goToService = null;
|
||||
|
||||
disposeAllBookmarkers();
|
||||
|
@ -444,7 +439,7 @@ public class BookmarkPlugin extends ProgramPlugin
|
|||
return;
|
||||
}
|
||||
boolean hasSelection = currentSelection != null && !currentSelection.isEmpty();
|
||||
createDialog = new CreateBookmarkDialog(this, currCU, hasSelection);
|
||||
CreateBookmarkDialog createDialog = new CreateBookmarkDialog(this, currCU, hasSelection);
|
||||
tool.showDialog(createDialog);
|
||||
}
|
||||
|
||||
|
|
|
@ -46,22 +46,11 @@ public class ClearPlugin extends Plugin {
|
|||
private static final String CLEAR_CODE_BYTES_NAME = "Clear Code Bytes";
|
||||
private static final String CLEAR_FLOW_AND_REPAIR = "Clear Flow and Repair";
|
||||
|
||||
private ClearDialog clearDialog;
|
||||
private ClearFlowDialog clearFlowDialog;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public ClearPlugin(PluginTool tool) {
|
||||
super(tool);
|
||||
createActions();
|
||||
}
|
||||
|
||||
// /////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Clear the flow and repair disassembly at the current location
|
||||
*/
|
||||
void clearFlowAndRepair(ListingActionContext context, boolean clearSymbols, boolean clearData,
|
||||
boolean repair) {
|
||||
ClearFlowAndRepairCmd cmd;
|
||||
|
@ -76,10 +65,6 @@ public class ClearPlugin extends Plugin {
|
|||
tool.executeBackgroundCommand(cmd, context.getProgram());
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the options to determine what must be cleared. Starts a new thread if
|
||||
* necessary to do the work. Called by the actions and by the dialog.
|
||||
*/
|
||||
void clear(ClearOptions options, ListingActionContext context) {
|
||||
if (!options.clearAny()) {
|
||||
return;
|
||||
|
@ -258,13 +243,12 @@ public class ClearPlugin extends Plugin {
|
|||
clear(opts, context);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop up the clear with options dialog.
|
||||
*/
|
||||
private void showClearAllDialog(ListingActionContext programActionContext) {
|
||||
if (clearDialog == null) {
|
||||
clearDialog = new ClearDialog(this);
|
||||
}
|
||||
ClearDialog clearDialog = new ClearDialog(this);
|
||||
clearDialog.setProgramActionContext(programActionContext);
|
||||
tool.showDialog(clearDialog);
|
||||
}
|
||||
|
@ -273,9 +257,7 @@ public class ClearPlugin extends Plugin {
|
|||
* Pop up the clear flows dialog
|
||||
*/
|
||||
private void showClearFlowDialog(ListingActionContext context) {
|
||||
if (clearFlowDialog == null) {
|
||||
clearFlowDialog = new ClearFlowDialog(this);
|
||||
}
|
||||
ClearFlowDialog clearFlowDialog = new ClearFlowDialog(this);
|
||||
clearFlowDialog.setProgramActionContext(context);
|
||||
tool.showDialog(clearFlowDialog);
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ import ghidra.util.HelpLocation;
|
|||
/**
|
||||
* Dialog for setting the comments for a CodeUnit.
|
||||
*/
|
||||
public class CommentsDialog extends DialogComponentProvider implements KeyListener {
|
||||
public class CommentsDialog extends ReusableDialogComponentProvider implements KeyListener {
|
||||
|
||||
private JTextArea eolField;
|
||||
private JTextArea preField;
|
||||
|
|
|
@ -58,7 +58,6 @@ public class CommentsPlugin extends Plugin implements OptionsChangeListener {
|
|||
private DockingAction deleteAction;
|
||||
private DockingAction historyAction;
|
||||
private CommentsDialog dialog;
|
||||
private CommentHistoryDialog historyDialog;
|
||||
|
||||
private DockingAction preCommentEditAction;
|
||||
private DockingAction postCommentEditAction;
|
||||
|
@ -76,6 +75,12 @@ public class CommentsPlugin extends Plugin implements OptionsChangeListener {
|
|||
initializeOptions(tool.getOptions("Comments"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispose() {
|
||||
super.dispose();
|
||||
dialog.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void optionsChanged(ToolOptions options, String optionName, Object oldValue,
|
||||
Object newValue) {
|
||||
|
@ -223,9 +228,7 @@ public class CommentsPlugin extends Plugin implements OptionsChangeListener {
|
|||
private void showCommentHistory(ListingActionContext context) {
|
||||
CodeUnit cu = context.getCodeUnit();
|
||||
ProgramLocation loc = context.getLocation();
|
||||
if (historyDialog == null) {
|
||||
historyDialog = new CommentHistoryDialog();
|
||||
}
|
||||
CommentHistoryDialog historyDialog = new CommentHistoryDialog();
|
||||
historyDialog.showDialog(cu, CommentType.getCommentType(null, loc, CodeUnit.EOL_COMMENT),
|
||||
tool, context);
|
||||
}
|
||||
|
@ -238,14 +241,17 @@ public class CommentsPlugin extends Plugin implements OptionsChangeListener {
|
|||
}
|
||||
|
||||
if (loc instanceof FunctionRepeatableCommentFieldLocation) {
|
||||
action.getPopupMenuData().setMenuPath(
|
||||
new String[] { "Comments", actionString + " Repeatable Comment" + endString });
|
||||
action.getPopupMenuData()
|
||||
.setMenuPath(
|
||||
new String[] { "Comments",
|
||||
actionString + " Repeatable Comment" + endString });
|
||||
return;
|
||||
}
|
||||
|
||||
if (loc instanceof PlateFieldLocation) {
|
||||
action.getPopupMenuData().setMenuPath(
|
||||
new String[] { "Comments", actionString + " Plate Comment" + endString });
|
||||
action.getPopupMenuData()
|
||||
.setMenuPath(
|
||||
new String[] { "Comments", actionString + " Plate Comment" + endString });
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -253,23 +259,29 @@ public class CommentsPlugin extends Plugin implements OptionsChangeListener {
|
|||
int type = cfLoc.getCommentType();
|
||||
switch (type) {
|
||||
case CodeUnit.PRE_COMMENT:
|
||||
action.getPopupMenuData().setMenuPath(
|
||||
new String[] { "Comments", actionString + " Pre-Comment" + endString });
|
||||
action.getPopupMenuData()
|
||||
.setMenuPath(
|
||||
new String[] { "Comments", actionString + " Pre-Comment" + endString });
|
||||
break;
|
||||
|
||||
case CodeUnit.POST_COMMENT:
|
||||
action.getPopupMenuData().setMenuPath(
|
||||
new String[] { "Comments", actionString + " Post-Comment" + endString });
|
||||
action.getPopupMenuData()
|
||||
.setMenuPath(
|
||||
new String[] { "Comments",
|
||||
actionString + " Post-Comment" + endString });
|
||||
break;
|
||||
|
||||
case CodeUnit.EOL_COMMENT:
|
||||
action.getPopupMenuData().setMenuPath(
|
||||
new String[] { "Comments", actionString + " EOL Comment" + endString });
|
||||
action.getPopupMenuData()
|
||||
.setMenuPath(
|
||||
new String[] { "Comments", actionString + " EOL Comment" + endString });
|
||||
break;
|
||||
|
||||
case CodeUnit.REPEATABLE_COMMENT:
|
||||
action.getPopupMenuData().setMenuPath(
|
||||
new String[] { "Comments", actionString + " Repeatable Comment" + endString });
|
||||
action.getPopupMenuData()
|
||||
.setMenuPath(
|
||||
new String[] { "Comments",
|
||||
actionString + " Repeatable Comment" + endString });
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -150,6 +150,7 @@ public abstract class CompositeEditorProvider extends ComponentProviderAdapter
|
|||
editorModel.endFieldEditing();
|
||||
}
|
||||
if (saveChanges(true) != 0) {
|
||||
super.closeComponent();
|
||||
dispose();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ import resources.Icons;
|
|||
*
|
||||
*
|
||||
*/
|
||||
class ParseDialog extends DialogComponentProvider {
|
||||
class ParseDialog extends ReusableDialogComponentProvider {
|
||||
final static String PROFILE_DIR = "parserprofiles";
|
||||
|
||||
private static String FILE_EXTENSION = ".prf";
|
||||
|
@ -89,11 +89,10 @@ class ParseDialog extends DialogComponentProvider {
|
|||
private ArrayList<ComboBoxItem> itemList;
|
||||
private ComboBoxItemComparator comparator;
|
||||
private ResourceFile parentUserFile;
|
||||
private GhidraFileChooser fileChooser;
|
||||
private boolean saveAsInProgress;
|
||||
|
||||
ParseDialog(CParserPlugin plugin) {
|
||||
super("Parse C Source", false);
|
||||
super("Parse C Source", false, true, true, false);
|
||||
|
||||
this.plugin = plugin;
|
||||
itemList = new ArrayList<>();
|
||||
|
@ -157,7 +156,7 @@ class ParseDialog extends DialogComponentProvider {
|
|||
pathPanel.setBorder(BorderFactory.createTitledBorder("Source files to parse"));
|
||||
String importDir = Preferences.getProperty(LAST_IMPORT_C_DIRECTORY);
|
||||
if (importDir == null) {
|
||||
importDir = Preferences.getProperty(Preferences.LAST_IMPORT_DIRECTORY);
|
||||
importDir = Preferences.getProperty(Preferences.LAST_PATH_DIRECTORY);
|
||||
if (importDir != null) {
|
||||
Preferences.setProperty(LAST_IMPORT_C_DIRECTORY, importDir);
|
||||
}
|
||||
|
@ -625,19 +624,15 @@ class ParseDialog extends DialogComponentProvider {
|
|||
}
|
||||
|
||||
private File getSaveFile() {
|
||||
if (fileChooser == null) {
|
||||
fileChooser = new GhidraFileChooser(rootPanel);
|
||||
String dir = Preferences.getProperty(Preferences.LAST_EXPORT_DIRECTORY);
|
||||
if (dir != null) {
|
||||
File file = new File(dir);
|
||||
fileChooser.setCurrentDirectory(file);
|
||||
fileChooser.setTitle("Choose Save Archive File");
|
||||
fileChooser.setApproveButtonText("Choose Save Archive File");
|
||||
fileChooser.setApproveButtonToolTipText("Choose filename for archive");
|
||||
}
|
||||
}
|
||||
fileChooser.rescanCurrentDirectory();
|
||||
|
||||
GhidraFileChooser fileChooser = new GhidraFileChooser(rootPanel);
|
||||
fileChooser.setTitle("Choose Save Archive File");
|
||||
fileChooser.setApproveButtonText("Choose Save Archive File");
|
||||
fileChooser.setApproveButtonToolTipText("Choose filename for archive");
|
||||
fileChooser.setLastDirectoryPreference(Preferences.LAST_EXPORT_DIRECTORY);
|
||||
|
||||
File file = fileChooser.getSelectedFile();
|
||||
fileChooser.dispose();
|
||||
if (file != null) {
|
||||
File parent = file.getParentFile();
|
||||
if (parent != null) {
|
||||
|
|
|
@ -42,14 +42,9 @@ class CreateStructureAction extends ListingContextAction {
|
|||
private DataPlugin plugin;
|
||||
private CreateStructureDialog createStructureDialog;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param name action name
|
||||
* @param owner owner of this action (the plugin name)
|
||||
*/
|
||||
public CreateStructureAction(DataPlugin plugin) {
|
||||
super("Create Structure", plugin.getName());
|
||||
// ACTIONS - auto generated
|
||||
|
||||
setPopupMenuData(new MenuData(CREATE_STRUCTURE_POPUP_MENU, null, "BasicData"));
|
||||
setKeyBindingData(new KeyBindingData(KeyEvent.VK_OPEN_BRACKET, InputEvent.SHIFT_DOWN_MASK));
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ import javax.swing.table.*;
|
|||
import javax.swing.text.BadLocationException;
|
||||
import javax.swing.text.Document;
|
||||
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.ReusableDialogComponentProvider;
|
||||
import docking.widgets.button.GRadioButton;
|
||||
import docking.widgets.table.*;
|
||||
import generic.theme.GThemeDefaults.Colors;
|
||||
|
@ -48,7 +48,7 @@ import ghidra.util.table.GhidraTableFilterPanel;
|
|||
*
|
||||
*
|
||||
*/
|
||||
public class CreateStructureDialog extends DialogComponentProvider {
|
||||
public class CreateStructureDialog extends ReusableDialogComponentProvider {
|
||||
private static final String NEW_STRUCTURE_STATUS_PREFIX = "Creating new structure: ";
|
||||
private static final String EXISITING_STRUCTURE_STATUS_PREFIX = "Using existing structure: ";
|
||||
|
||||
|
|
|
@ -35,26 +35,25 @@ import ghidra.program.util.ProgramLocation;
|
|||
class RenameDataFieldAction extends ListingContextAction {
|
||||
|
||||
private DataPlugin plugin;
|
||||
private RenameDataFieldDialog dialog;
|
||||
|
||||
public RenameDataFieldAction(DataPlugin plugin) {
|
||||
super("Rename Data Field", plugin.getName());
|
||||
dialog = new RenameDataFieldDialog(plugin);
|
||||
public RenameDataFieldAction(DataPlugin plugin) {
|
||||
super("Rename Data Field", plugin.getName());
|
||||
|
||||
setPopupMenuData(
|
||||
new MenuData(
|
||||
new String[] {"Data", "Rename Field"},null,"BasicData" ) );
|
||||
setPopupMenuData(
|
||||
new MenuData(
|
||||
new String[] { "Data", "Rename Field" }, null, "BasicData"));
|
||||
|
||||
setKeyBindingData( new KeyBindingData(
|
||||
KeyEvent.VK_N, 0 ) );
|
||||
setKeyBindingData(new KeyBindingData(
|
||||
KeyEvent.VK_N, 0));
|
||||
|
||||
this.plugin = plugin;
|
||||
setEnabled(true);
|
||||
}
|
||||
this.plugin = plugin;
|
||||
setEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
protected void actionPerformed(ListingActionContext context) {
|
||||
ListingActionContext programActionContext = (ListingActionContext) context.getContextObject();
|
||||
ListingActionContext programActionContext =
|
||||
(ListingActionContext) context.getContextObject();
|
||||
PluginTool tool = plugin.getTool();
|
||||
Program program = programActionContext.getProgram();
|
||||
ProgramLocation loc = programActionContext.getLocation();
|
||||
|
@ -62,19 +61,22 @@ class RenameDataFieldAction extends ListingContextAction {
|
|||
DataType type = data.getDataType();
|
||||
|
||||
if (type instanceof Composite) {
|
||||
Composite comp = (Composite)type;
|
||||
Composite comp = (Composite) type;
|
||||
int[] compPath = loc.getComponentPath();
|
||||
for (int i=0; i<compPath.length-1; i++) {
|
||||
for (int i = 0; i < compPath.length - 1; i++) {
|
||||
DataTypeComponent subComp = comp.getComponent(compPath[i]);
|
||||
type = subComp.getDataType();
|
||||
if (type instanceof Composite)
|
||||
comp = (Composite)type;
|
||||
else
|
||||
if (type instanceof Composite) {
|
||||
comp = (Composite) type;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
tool.showDialog(dialog, tool.getComponentProvider(PluginConstants.CODE_BROWSER));
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ package ghidra.app.plugin.core.datamgr;
|
|||
|
||||
import java.awt.Component;
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
@ -95,7 +94,6 @@ public class DataTypeManagerPlugin extends ProgramPlugin
|
|||
|
||||
private DataTypeManagerHandler dataTypeManagerHandler;
|
||||
private DataTypesProvider provider;
|
||||
private OpenVersionedFileDialog<DataTypeArchive> openDialog;
|
||||
|
||||
private Map<String, DockingAction> recentlyOpenedArchiveMap;
|
||||
private Map<String, DockingAction> installArchiveMap;
|
||||
|
@ -366,19 +364,10 @@ public class DataTypeManagerPlugin extends ProgramPlugin
|
|||
newProvider.setIncludeDataTypeMembersInFilter(provider.includeDataMembersInSearch());
|
||||
newProvider.setFilteringArrays(provider.isFilteringArrays());
|
||||
newProvider.setFilteringPointers(provider.isFilteringPointers());
|
||||
newProvider.setTransient();
|
||||
return newProvider;
|
||||
}
|
||||
|
||||
public void closeProvider(DataTypesProvider providerToClose) {
|
||||
if (providerToClose != provider) {
|
||||
providerToClose.removeFromTool(); // remove any transient providers when closed
|
||||
providerToClose.dispose();
|
||||
}
|
||||
else {
|
||||
provider.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
public Program getProgram() {
|
||||
return currentProgram;
|
||||
}
|
||||
|
@ -574,25 +563,24 @@ public class DataTypeManagerPlugin extends ProgramPlugin
|
|||
}
|
||||
|
||||
public void openProjectDataTypeArchive() {
|
||||
if (openDialog == null) {
|
||||
ActionListener listener = ev -> {
|
||||
DomainFile domainFile = openDialog.getDomainFile();
|
||||
int version = openDialog.getVersion();
|
||||
if (domainFile == null) {
|
||||
openDialog.setStatusText("Please choose a Project Data Type Archive");
|
||||
}
|
||||
else {
|
||||
openDialog.close();
|
||||
openArchive(domainFile, version);
|
||||
}
|
||||
};
|
||||
openDialog =
|
||||
new OpenVersionedFileDialog<>(tool, "Open Project Data Type Archive",
|
||||
DataTypeArchive.class);
|
||||
openDialog.setHelpLocation(new HelpLocation(HelpTopics.PROGRAM, "Open_File_Dialog"));
|
||||
openDialog.addOkActionListener(listener);
|
||||
}
|
||||
tool.showDialog(openDialog);
|
||||
|
||||
OpenVersionedFileDialog<DataTypeArchive> dialog =
|
||||
new OpenVersionedFileDialog<>(tool, "Open Project Data Type Archive",
|
||||
DataTypeArchive.class);
|
||||
dialog.setHelpLocation(new HelpLocation(HelpTopics.PROGRAM, "Open_File_Dialog"));
|
||||
dialog.addOkActionListener(ev -> {
|
||||
DomainFile domainFile = dialog.getDomainFile();
|
||||
int version = dialog.getVersion();
|
||||
if (domainFile == null) {
|
||||
dialog.setStatusText("Please choose a Project Data Type Archive");
|
||||
}
|
||||
else {
|
||||
dialog.close();
|
||||
openArchive(domainFile, version);
|
||||
}
|
||||
});
|
||||
|
||||
tool.showDialog(dialog);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -42,7 +42,6 @@ public class DataTypeSyncDialog extends DialogComponentProvider implements DataT
|
|||
private DataTypeComparePanel comparePanel;
|
||||
private final String operationName;
|
||||
|
||||
private boolean cancelled;
|
||||
private List<DataTypeSyncInfo> selectedInfos = Collections.emptyList();
|
||||
|
||||
public DataTypeSyncDialog(DataTypeManagerPlugin plugin, String clientName, String sourceName,
|
||||
|
@ -118,7 +117,6 @@ public class DataTypeSyncDialog extends DialogComponentProvider implements DataT
|
|||
|
||||
@Override
|
||||
protected void cancelCallback() {
|
||||
cancelled = true;
|
||||
close();
|
||||
}
|
||||
|
||||
|
|
|
@ -114,6 +114,11 @@ public class DataTypesProvider extends ComponentProviderAdapter {
|
|||
createLocalActions();
|
||||
}
|
||||
|
||||
@Override // overridden to open access
|
||||
protected void setTransient() {
|
||||
super.setTransient();
|
||||
}
|
||||
|
||||
/**
|
||||
* This creates all the actions for opening/creating data type archives.
|
||||
* It also creates the action for refreshing the built-in data types
|
||||
|
@ -358,7 +363,10 @@ public class DataTypesProvider extends ComponentProviderAdapter {
|
|||
|
||||
@Override // overridden to handle special logic in plugin
|
||||
public void closeComponent() {
|
||||
plugin.closeProvider(this);
|
||||
super.closeComponent();
|
||||
if (isTransient()) {
|
||||
dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void buildComponent() {
|
||||
|
|
|
@ -51,6 +51,7 @@ public class CreateArchiveAction extends DockingAction {
|
|||
|
||||
Msg.trace(this, "Showing filechooser to get new archive name...");
|
||||
File file = fileChooser.promptUserForFile("New_Archive");
|
||||
fileChooser.dispose();
|
||||
if (file == null) {
|
||||
Msg.trace(this, "No new archive filename chosen by user - not performing action");
|
||||
return;
|
||||
|
|
|
@ -176,6 +176,8 @@ public class ExportToHeaderAction extends DockingAction {
|
|||
new DataTypeWriterTask(gTree, programDataTypeMgr, dataTypeList, handler, file),
|
||||
gTree);
|
||||
}
|
||||
|
||||
fileChooser.dispose();
|
||||
}
|
||||
|
||||
private class DataTypeWriterTask extends Task {
|
||||
|
@ -209,8 +211,9 @@ public class ExportToHeaderAction extends DockingAction {
|
|||
finally {
|
||||
writer.close();
|
||||
}
|
||||
plugin.getTool().setStatusInfo(
|
||||
"Successfully exported data type(s) to " + file.getAbsolutePath());
|
||||
plugin.getTool()
|
||||
.setStatusInfo(
|
||||
"Successfully exported data type(s) to " + file.getAbsolutePath());
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
// user cancelled; ignore
|
||||
|
|
|
@ -67,6 +67,7 @@ public class OpenArchiveAction extends DockingAction {
|
|||
|
||||
DataTypeManagerHandler manager = plugin.getDataTypeManagerHandler();
|
||||
File file = fileChooser.getSelectedFile();
|
||||
fileChooser.dispose();
|
||||
if (file == null) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -119,7 +119,7 @@ public class ArchiveUtils {
|
|||
ArchiveFileChooser fileChooser = new ArchiveFileChooser(component);
|
||||
String archiveName = archive.getName();
|
||||
File file = fileChooser.promptUserForFile(archiveName);
|
||||
|
||||
fileChooser.dispose();
|
||||
if (file == null) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -73,8 +73,6 @@ public class DataTypeManagerHandler {
|
|||
private Set<String> knownOpenFileArchiveNames = new HashSet<>();
|
||||
private Map<UniversalID, InvalidFileArchive> invalidArchives = new HashMap<>();
|
||||
|
||||
private DataTreeDialog dataTreeSaveDialog;
|
||||
private CreateDataTypeArchiveDataTreeDialog dataTreeCreateDialog;
|
||||
private boolean treeDialogCancelled = false;
|
||||
private DomainFileFilter createArchiveFileFilter;
|
||||
|
||||
|
@ -1409,77 +1407,74 @@ public class DataTypeManagerHandler {
|
|||
}
|
||||
|
||||
private DataTreeDialog getSaveDialog() {
|
||||
if (dataTreeSaveDialog == null) {
|
||||
DataTreeDialog dialog =
|
||||
new DataTreeDialog(null, "Save As", DataTreeDialog.SAVE, createArchiveFileFilter);
|
||||
|
||||
ActionListener listener = event -> {
|
||||
DomainFolder folder = dataTreeSaveDialog.getDomainFolder();
|
||||
String newName = dataTreeSaveDialog.getNameText();
|
||||
if (newName.length() == 0) {
|
||||
dataTreeSaveDialog.setStatusText("Please enter a name");
|
||||
return;
|
||||
}
|
||||
else if (folder == null) {
|
||||
dataTreeSaveDialog.setStatusText("Please select a folder");
|
||||
return;
|
||||
}
|
||||
ActionListener listener = event -> {
|
||||
DomainFolder folder = dialog.getDomainFolder();
|
||||
String newName = dialog.getNameText();
|
||||
if (newName.length() == 0) {
|
||||
dialog.setStatusText("Please enter a name");
|
||||
return;
|
||||
}
|
||||
else if (folder == null) {
|
||||
dialog.setStatusText("Please select a folder");
|
||||
return;
|
||||
}
|
||||
|
||||
DomainFile file = folder.getFile(newName);
|
||||
if (file != null && file.isReadOnly()) {
|
||||
dataTreeSaveDialog.setStatusText("Read Only. Choose new name/folder");
|
||||
}
|
||||
else {
|
||||
dataTreeSaveDialog.close();
|
||||
treeDialogCancelled = false;
|
||||
}
|
||||
};
|
||||
dataTreeSaveDialog =
|
||||
new DataTreeDialog(null, "Save As", DataTreeDialog.SAVE, createArchiveFileFilter);
|
||||
DomainFile file = folder.getFile(newName);
|
||||
if (file != null && file.isReadOnly()) {
|
||||
dialog.setStatusText("Read Only. Choose new name/folder");
|
||||
}
|
||||
else {
|
||||
dialog.close();
|
||||
treeDialogCancelled = false;
|
||||
}
|
||||
};
|
||||
|
||||
dataTreeSaveDialog.addOkActionListener(listener);
|
||||
dataTreeSaveDialog
|
||||
.setHelpLocation(new HelpLocation(HelpTopics.PROGRAM, "Save_As_File"));
|
||||
}
|
||||
return dataTreeSaveDialog;
|
||||
dialog.addOkActionListener(listener);
|
||||
dialog.setHelpLocation(new HelpLocation(HelpTopics.PROGRAM, "Save_As_File"));
|
||||
return dialog;
|
||||
}
|
||||
|
||||
private CreateDataTypeArchiveDataTreeDialog getCreateDialog() {
|
||||
if (dataTreeCreateDialog == null) {
|
||||
|
||||
ActionListener listener = event -> {
|
||||
DomainFolder folder = dataTreeCreateDialog.getDomainFolder();
|
||||
String newName = dataTreeCreateDialog.getNameText();
|
||||
if (newName.length() == 0) {
|
||||
dataTreeCreateDialog.setStatusText("Please enter a name");
|
||||
return;
|
||||
}
|
||||
else if (folder == null) {
|
||||
dataTreeCreateDialog.setStatusText("Please select a folder");
|
||||
return;
|
||||
}
|
||||
|
||||
DomainFile file = folder.getFile(newName);
|
||||
if (file != null) {
|
||||
dataTreeCreateDialog.setStatusText("Choose a name that doesn't exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dataTreeCreateDialog.createNewDataTypeArchive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// everything is OK
|
||||
dataTreeCreateDialog.close();
|
||||
treeDialogCancelled = false;
|
||||
};
|
||||
|
||||
dataTreeCreateDialog = new CreateDataTypeArchiveDataTreeDialog(null, "Create",
|
||||
CreateDataTypeArchiveDataTreeDialog dialog =
|
||||
new CreateDataTypeArchiveDataTreeDialog(null, "Create",
|
||||
DataTreeDialog.CREATE, createArchiveFileFilter);
|
||||
|
||||
dataTreeCreateDialog.addOkActionListener(listener);
|
||||
dataTreeCreateDialog.setHelpLocation(
|
||||
new HelpLocation(HelpTopics.DATA_MANAGER, "Create_Data_Type_Archive"));
|
||||
}
|
||||
return dataTreeCreateDialog;
|
||||
ActionListener listener = event -> {
|
||||
DomainFolder folder = dialog.getDomainFolder();
|
||||
String newName = dialog.getNameText();
|
||||
if (newName.length() == 0) {
|
||||
dialog.setStatusText("Please enter a name");
|
||||
return;
|
||||
}
|
||||
else if (folder == null) {
|
||||
dialog.setStatusText("Please select a folder");
|
||||
return;
|
||||
}
|
||||
|
||||
DomainFile file = folder.getFile(newName);
|
||||
if (file != null) {
|
||||
dialog.setStatusText("Choose a name that doesn't exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dialog.createNewDataTypeArchive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// everything is OK
|
||||
dialog.close();
|
||||
treeDialogCancelled = false;
|
||||
};
|
||||
|
||||
dialog.addOkActionListener(listener);
|
||||
dialog.setHelpLocation(
|
||||
new HelpLocation(HelpTopics.DATA_MANAGER, "Create_Data_Type_Archive"));
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public DataTypeManager getDataTypeManager(SourceArchive source) {
|
||||
|
@ -1520,14 +1515,14 @@ public class DataTypeManagerHandler {
|
|||
return true;
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
dataTreeCreateDialog.setStatusText("Duplicate Name: " + e.getMessage());
|
||||
setStatusText("Duplicate Name: " + e.getMessage());
|
||||
}
|
||||
catch (InvalidNameException e) {
|
||||
dataTreeCreateDialog.setStatusText("Invalid Name: " + e.getMessage());
|
||||
setStatusText("Invalid Name: " + e.getMessage());
|
||||
}
|
||||
catch (IOException e) {
|
||||
dataTreeCreateDialog.setStatusText("Unexpected IOException!");
|
||||
Msg.showError(null, dataTreeCreateDialog.getComponent(), "Unexpected Exception",
|
||||
setStatusText("Unexpected IOException!");
|
||||
Msg.showError(null, getComponent(), "Unexpected Exception",
|
||||
e.getMessage(), e);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -219,7 +219,6 @@ public class DataWindowPlugin extends ProgramPlugin implements DomainObjectListe
|
|||
filterAction.addType(type.getDisplayName());
|
||||
}
|
||||
filterAction.selectTypes(selectedList);
|
||||
filterAction.repaint();
|
||||
provider.reload();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,8 +52,6 @@ class FilterAction extends ToggleDockingAction {
|
|||
private boolean viewMode = false;
|
||||
private boolean selectionMode = false;
|
||||
|
||||
private FilterDialog dialog;
|
||||
|
||||
private static class SortMapComparatorASC implements Comparator<String> {
|
||||
|
||||
@Override
|
||||
|
@ -82,10 +80,7 @@ class FilterAction extends ToggleDockingAction {
|
|||
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
if (dialog == null) {
|
||||
dialog = new FilterDialog();
|
||||
}
|
||||
|
||||
FilterDialog dialog = new FilterDialog();
|
||||
dialog.setSelectionEnabled(plugin.getSelection() != null);
|
||||
dialog.updateButtonEnabledState();
|
||||
plugin.getTool().showDialog(dialog);
|
||||
|
@ -93,19 +88,11 @@ class FilterAction extends ToggleDockingAction {
|
|||
|
||||
synchronized void clearTypes() {
|
||||
typeEnabledMap.clear();
|
||||
|
||||
if (dialog != null) {
|
||||
dialog.clearTypes();
|
||||
}
|
||||
}
|
||||
|
||||
synchronized void addType(String type) {
|
||||
Boolean bool = new Boolean(!filterEnabled);
|
||||
Boolean bool = !filterEnabled;
|
||||
typeEnabledMap.put(type, bool);
|
||||
|
||||
if (dialog != null) {
|
||||
dialog.createCheckBox(type, type, bool.booleanValue());
|
||||
}
|
||||
}
|
||||
|
||||
synchronized boolean typeEnabled(String type) {
|
||||
|
@ -137,16 +124,6 @@ class FilterAction extends ToggleDockingAction {
|
|||
for (String element : list) {
|
||||
typeEnabledMap.put(element, Boolean.TRUE);
|
||||
}
|
||||
if (dialog != null) {
|
||||
dialog.selectTypes(list);
|
||||
}
|
||||
}
|
||||
|
||||
void repaint() {
|
||||
if (dialog == null) {
|
||||
return;
|
||||
}
|
||||
dialog.repaint();
|
||||
}
|
||||
|
||||
boolean getViewMode() {
|
||||
|
@ -170,7 +147,6 @@ class FilterAction extends ToggleDockingAction {
|
|||
filterEnabled = false;
|
||||
viewMode = false;
|
||||
selectionMode = false;
|
||||
dialog = null;
|
||||
setEnabled(false);
|
||||
clearTypes();
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ import javax.swing.*;
|
|||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.ReusableDialogComponentProvider;
|
||||
import docking.action.DockingAction;
|
||||
import docking.widgets.checkbox.GCheckBox;
|
||||
import docking.widgets.label.GDLabel;
|
||||
|
@ -39,7 +39,7 @@ import ghidra.util.table.*;
|
|||
import ghidra.util.table.actions.MakeProgramSelectionAction;
|
||||
import ghidra.util.task.Task;
|
||||
|
||||
public class AddressTableDialog extends DialogComponentProvider {
|
||||
public class AddressTableDialog extends ReusableDialogComponentProvider {
|
||||
private static final int DEFAULT_MINIMUM_TABLE_SIZE = 3;
|
||||
private static final String DIALOG_NAME = "Search For Address Tables";
|
||||
|
||||
|
|
|
@ -44,9 +44,9 @@ public class TextEditorComponentProvider extends ComponentProviderAdapter {
|
|||
private static final String TITLE = "Text Editor";
|
||||
private static final String FONT_ID = "font.plugin.service.text.editor";
|
||||
private static final int MAX_UNDO_REDO_SIZE = 50;
|
||||
private static final String LAST_SAVED_TEXT_FILE_DIR = "LastSavedTextFileDirectory";
|
||||
|
||||
private TextEditorManagerPlugin plugin;
|
||||
private GhidraFileChooser chooser;
|
||||
private File textFile;
|
||||
private String textFileName;
|
||||
private DockingAction saveAction;
|
||||
|
@ -146,17 +146,13 @@ public class TextEditorComponentProvider extends ComponentProviderAdapter {
|
|||
}
|
||||
|
||||
private String loadTextFile(InputStream inputStream) throws IOException {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
try {
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
|
||||
return loadTextFile(reader);
|
||||
}
|
||||
finally {
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
|
||||
private String loadTextFile(BufferedReader reader) throws IOException {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
while (true) {
|
||||
String line = reader.readLine();
|
||||
if (line == null) {
|
||||
|
@ -290,21 +286,25 @@ public class TextEditorComponentProvider extends ComponentProviderAdapter {
|
|||
}
|
||||
catch (IOException e) {
|
||||
if (textFile.canWrite()) {
|
||||
Msg.showError(getClass(), getComponent(), "Error saving file", e.getMessage());
|
||||
Msg.showError(getClass(), getComponent(), "Error Saving File",
|
||||
"Unable to save file", e);
|
||||
}
|
||||
else {
|
||||
Msg.showError(getClass(), getComponent(), "Error Saving File",
|
||||
"The file is not writable.");
|
||||
"The file is not writable");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void saveAs() {
|
||||
if (chooser == null) {
|
||||
chooser = new GhidraFileChooser(getComponent());
|
||||
}
|
||||
|
||||
GhidraFileChooser chooser = new GhidraFileChooser(getComponent());
|
||||
|
||||
chooser.setLastDirectoryPreference(LAST_SAVED_TEXT_FILE_DIR);
|
||||
|
||||
File saveAsFile = chooser.getSelectedFile();
|
||||
chooser.dispose();
|
||||
if (saveAsFile == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -344,6 +344,7 @@ public class TextEditorComponentProvider extends ComponentProviderAdapter {
|
|||
public void closeComponent() {
|
||||
if (plugin.removeTextFile(this, textFileName)) {
|
||||
clearUndoRedoStack();
|
||||
super.closeComponent();
|
||||
plugin.getTool().removeComponentProvider(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -269,6 +269,7 @@ public class ExporterDialog extends DialogComponentProvider implements AddressFa
|
|||
setLastExportDirectory(file);
|
||||
filePathTextField.setText(file.getAbsolutePath());
|
||||
}
|
||||
chooser.dispose();
|
||||
}
|
||||
|
||||
private void setLastExportDirectory(File file) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,119 +15,118 @@
|
|||
*/
|
||||
package ghidra.app.plugin.core.function;
|
||||
|
||||
import ghidra.app.util.PluginConstants;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.ReusableDialogComponentProvider;
|
||||
import ghidra.app.util.PluginConstants;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
|
||||
abstract class CommentDialog extends DialogComponentProvider {
|
||||
private JTextArea commentsField;
|
||||
abstract class CommentDialog extends ReusableDialogComponentProvider {
|
||||
private JTextArea commentsField;
|
||||
|
||||
private boolean applyWasDone;
|
||||
private String origComments;
|
||||
private boolean applyWasDone;
|
||||
private String origComments;
|
||||
|
||||
protected FunctionPlugin plugin;
|
||||
protected FunctionPlugin plugin;
|
||||
|
||||
CommentDialog(FunctionPlugin plugin) {
|
||||
// changed name
|
||||
super("Set Comment");
|
||||
addWorkPanel(createPanel());
|
||||
addListeners();
|
||||
CommentDialog(FunctionPlugin plugin) {
|
||||
// changed name
|
||||
super("Set Comment");
|
||||
addWorkPanel(createPanel());
|
||||
addListeners();
|
||||
|
||||
addOKButton();
|
||||
addApplyButton();
|
||||
addCancelButton();
|
||||
this.plugin = plugin;
|
||||
}
|
||||
addOKButton();
|
||||
addApplyButton();
|
||||
addCancelButton();
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
void showDialog(String comment) {
|
||||
applyWasDone = true;
|
||||
origComments = comment;
|
||||
void showDialog(String comment) {
|
||||
applyWasDone = true;
|
||||
origComments = comment;
|
||||
|
||||
commentsField.setText(origComments);
|
||||
if (origComments != null && origComments.length() > 0) {
|
||||
commentsField.selectAll();
|
||||
}
|
||||
PluginTool tool = plugin.getTool();
|
||||
tool.showDialog( this, tool.getComponentProvider(
|
||||
PluginConstants.CODE_BROWSER ));
|
||||
}
|
||||
commentsField.setText(origComments);
|
||||
if (origComments != null && origComments.length() > 0) {
|
||||
commentsField.selectAll();
|
||||
}
|
||||
PluginTool tool = plugin.getTool();
|
||||
tool.showDialog(this, tool.getComponentProvider(
|
||||
PluginConstants.CODE_BROWSER));
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// *** GhidraDialog "callback" methods ***
|
||||
/////////////////////////////////////////////
|
||||
/////////////////////////////////////////////
|
||||
// *** GhidraDialog "callback" methods ***
|
||||
/////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Callback for the cancel button.
|
||||
*/
|
||||
@Override
|
||||
protected void cancelCallback() {
|
||||
close();
|
||||
}
|
||||
/**
|
||||
* Callback for the cancel button.
|
||||
*/
|
||||
@Override
|
||||
protected void cancelCallback() {
|
||||
close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for the OK button.
|
||||
*/
|
||||
@Override
|
||||
protected void okCallback() {
|
||||
applyCallback();
|
||||
close();
|
||||
}
|
||||
/**
|
||||
* Callback for the OK button.
|
||||
*/
|
||||
@Override
|
||||
protected void okCallback() {
|
||||
applyCallback();
|
||||
close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for the Apply button.
|
||||
*/
|
||||
@Override
|
||||
protected void applyCallback() {
|
||||
if (!applyWasDone) {
|
||||
// Apply was hit
|
||||
origComments = commentsField.getText();
|
||||
doApply(origComments);
|
||||
applyWasDone = true;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Callback for the Apply button.
|
||||
*/
|
||||
@Override
|
||||
protected void applyCallback() {
|
||||
if (!applyWasDone) {
|
||||
// Apply was hit
|
||||
origComments = commentsField.getText();
|
||||
doApply(origComments);
|
||||
applyWasDone = true;
|
||||
}
|
||||
}
|
||||
|
||||
abstract protected void doApply(String comment);
|
||||
abstract protected void doApply(String comment);
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// ** private methods **
|
||||
////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// ** private methods **
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Create the panel for the dialog.
|
||||
*/
|
||||
private JPanel createPanel() {
|
||||
/**
|
||||
* Create the panel for the dialog.
|
||||
*/
|
||||
private JPanel createPanel() {
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new BorderLayout());
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new BorderLayout());
|
||||
|
||||
JPanel p = new JPanel();
|
||||
commentsField = new JTextArea(10, 50);
|
||||
commentsField.setLineWrap(true);
|
||||
commentsField.setWrapStyleWord(true);
|
||||
JScrollPane scrollP = new JScrollPane(commentsField);
|
||||
JPanel p = new JPanel();
|
||||
commentsField = new JTextArea(10, 50);
|
||||
commentsField.setLineWrap(true);
|
||||
commentsField.setWrapStyleWord(true);
|
||||
JScrollPane scrollP = new JScrollPane(commentsField);
|
||||
|
||||
p.add(scrollP);
|
||||
panel.add(scrollP, BorderLayout.CENTER);
|
||||
p.add(scrollP);
|
||||
panel.add(scrollP, BorderLayout.CENTER);
|
||||
|
||||
return panel;
|
||||
}
|
||||
return panel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add listeners to the radio buttons.
|
||||
*/
|
||||
private void addListeners() {
|
||||
commentsField.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
applyWasDone = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Add listeners to the radio buttons.
|
||||
*/
|
||||
private void addListeners() {
|
||||
commentsField.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
applyWasDone = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -173,8 +173,7 @@ public class FunctionPlugin extends Plugin implements DataService {
|
|||
* Add the cycle group actions
|
||||
*/
|
||||
private void addCycleGroupActions() {
|
||||
for (int i = 0; i < cgActions.size(); i++) {
|
||||
DockingAction action = cgActions.get(i);
|
||||
for (CycleGroupAction action : cgActions) {
|
||||
tool.removeAction(action);
|
||||
}
|
||||
cgActions.clear();
|
||||
|
|
|
@ -60,16 +60,12 @@ class VariableCommentAction extends ListingContextAction {
|
|||
return;
|
||||
}
|
||||
VariableCommentDialog dialog = funcPlugin.getVariableCommentDialog();
|
||||
if (dialog == null) {
|
||||
dialog = new VariableCommentDialog(funcPlugin);
|
||||
}
|
||||
dialog.showDialog(function.getProgram(), var);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Get a variable using the current location.
|
||||
* @param function
|
||||
* @param function the function
|
||||
* @return null if function is null or if current location is not
|
||||
* a stack variable location.
|
||||
*/
|
||||
|
|
|
@ -15,15 +15,14 @@
|
|||
*/
|
||||
package ghidra.app.plugin.core.help;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.ReusableDialogComponentProvider;
|
||||
import docking.action.DockingAction;
|
||||
import docking.action.MenuData;
|
||||
import docking.dnd.GClipboard;
|
||||
|
@ -70,6 +69,10 @@ public class ProcessorListPlugin extends Plugin implements ApplicationLevelPlugi
|
|||
public void dispose() {
|
||||
tool.removeAction(processorListAction);
|
||||
processorListAction.dispose();
|
||||
|
||||
if (dialogProvider != null) {
|
||||
dialogProvider.dispose();
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
@ -154,7 +157,7 @@ public class ProcessorListPlugin extends Plugin implements ApplicationLevelPlugi
|
|||
return strBuilder.toString();
|
||||
}
|
||||
|
||||
class ProcessorListDialogProvider extends DialogComponentProvider {
|
||||
class ProcessorListDialogProvider extends ReusableDialogComponentProvider {
|
||||
|
||||
ProcessorListDialogProvider() {
|
||||
super("Installed Processor Modules", false, false, true, false);
|
||||
|
|
|
@ -94,6 +94,16 @@ public class InstructionSearchPlugin extends ProgramPlugin {
|
|||
createActions();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispose() {
|
||||
super.dispose();
|
||||
|
||||
if (searchDialog != null) {
|
||||
searchDialog.dispose();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public InstructionSearchDialog getSearchDialog() {
|
||||
return searchDialog;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ import java.util.List;
|
|||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.ReusableDialogComponentProvider;
|
||||
import generic.theme.GThemeDefaults.Colors.Messages;
|
||||
import ghidra.app.plugin.core.instructionsearch.model.*;
|
||||
import ghidra.app.plugin.core.instructionsearch.ui.SelectionModeWidget.InputMode;
|
||||
|
@ -43,7 +43,7 @@ import ghidra.util.SystemUtilities;
|
|||
* will then be disassembled and displayed in the {@link InstructionTable}.
|
||||
*
|
||||
*/
|
||||
public class InsertBytesWidget extends DialogComponentProvider implements KeyListener {
|
||||
public class InsertBytesWidget extends ReusableDialogComponentProvider implements KeyListener {
|
||||
|
||||
// The input text area. This is a generic JTextArea but displays a textual 'hint' to inform
|
||||
// the user of what type of input is required.
|
||||
|
|
|
@ -22,7 +22,7 @@ import java.util.*;
|
|||
import javax.swing.*;
|
||||
|
||||
import docking.ComponentProvider;
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.ReusableDialogComponentProvider;
|
||||
import generic.theme.GColor;
|
||||
import generic.theme.GThemeDefaults.Colors.Messages;
|
||||
import ghidra.app.events.ProgramSelectionPluginEvent;
|
||||
|
@ -61,7 +61,7 @@ import ghidra.util.task.TaskMonitor;
|
|||
* ------------------------------------
|
||||
*/
|
||||
|
||||
public class InstructionSearchDialog extends DialogComponentProvider implements Observer {
|
||||
public class InstructionSearchDialog extends ReusableDialogComponentProvider implements Observer {
|
||||
|
||||
private static final Color BG_COLOR_MARKERS =
|
||||
new GColor("color.bg.plugin.instructionsearch.search.markers");
|
||||
|
|
|
@ -41,12 +41,6 @@ public class InstructionTablePanel extends JPanel {
|
|||
|
||||
private JPanel workPanel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param numColumns
|
||||
* @param plugin
|
||||
* @param dialog
|
||||
*/
|
||||
public InstructionTablePanel(int numColumns, InstructionSearchPlugin plugin,
|
||||
InstructionSearchDialog dialog) {
|
||||
|
||||
|
@ -74,11 +68,6 @@ public class InstructionTablePanel extends JPanel {
|
|||
return workPanel;
|
||||
}
|
||||
|
||||
/*********************************************************************************************
|
||||
* PRIVATE METHODS
|
||||
* @throws InvalidInputException
|
||||
********************************************************************************************/
|
||||
|
||||
private void setup() throws InvalidInputException {
|
||||
|
||||
workPanel = new JPanel();
|
||||
|
|
|
@ -49,9 +49,7 @@ import ghidra.util.Msg;
|
|||
//@formatter:on
|
||||
public class LabelMgrPlugin extends Plugin {
|
||||
|
||||
private OperandLabelDialog operandDialog;
|
||||
private AddEditDialog addEditDialog;
|
||||
private EditFieldNameDialog editFieldDialog;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -62,6 +60,8 @@ public class LabelMgrPlugin extends Plugin {
|
|||
super(tool);
|
||||
// Setup list of actions
|
||||
setupActions();
|
||||
|
||||
addEditDialog = new AddEditDialog("", tool);
|
||||
}
|
||||
|
||||
private void setupActions() {
|
||||
|
@ -88,25 +88,21 @@ public class LabelMgrPlugin extends Plugin {
|
|||
tool.addAction(allHistoryAction);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispose() {
|
||||
addEditDialog.dispose();
|
||||
}
|
||||
|
||||
AddEditDialog getAddEditDialog() {
|
||||
if (addEditDialog == null) {
|
||||
addEditDialog = new AddEditDialog("", tool);
|
||||
}
|
||||
return addEditDialog;
|
||||
}
|
||||
|
||||
EditFieldNameDialog getEditFieldDialog() {
|
||||
if (editFieldDialog == null) {
|
||||
editFieldDialog = new EditFieldNameDialog("", tool);
|
||||
}
|
||||
return editFieldDialog;
|
||||
return new EditFieldNameDialog("", tool);
|
||||
}
|
||||
|
||||
OperandLabelDialog getOperandLabelDialog() {
|
||||
if (operandDialog == null) {
|
||||
operandDialog = new OperandLabelDialog(this);
|
||||
}
|
||||
return operandDialog;
|
||||
return new OperandLabelDialog(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -614,8 +614,11 @@ class MemoryMapProvider extends ComponentProviderAdapter {
|
|||
else {
|
||||
model = new ExpandBlockDownModel(tool, program);
|
||||
}
|
||||
new ExpandBlockDialog(tool, model, block, program.getAddressFactory(), dialogType);
|
||||
|
||||
ExpandBlockDialog dialog =
|
||||
new ExpandBlockDialog(tool, model, block, program.getAddressFactory(), dialogType);
|
||||
model.initialize(block);
|
||||
dialog.dispose();
|
||||
}
|
||||
|
||||
private void showMoveBlockDialog(MemoryBlock block) {
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
package ghidra.app.plugin.core.memory;
|
||||
|
||||
import java.awt.Cursor;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.*;
|
||||
|
@ -54,12 +53,6 @@ class SplitBlockDialog extends DialogComponentProvider {
|
|||
private AddressFactory addrFactory;
|
||||
private MemoryMapPlugin plugin;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param parent
|
||||
* @param block
|
||||
* @param af
|
||||
*/
|
||||
SplitBlockDialog(MemoryMapPlugin plugin, MemoryBlock block, AddressFactory af) {
|
||||
super("Split Block");
|
||||
this.plugin = plugin;
|
||||
|
@ -74,9 +67,6 @@ class SplitBlockDialog extends DialogComponentProvider {
|
|||
addListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.bean.GhidraDialog#okCallback()
|
||||
*/
|
||||
@Override
|
||||
protected void okCallback() {
|
||||
// call plugin to do the work
|
||||
|
@ -195,12 +185,7 @@ class SplitBlockDialog extends DialogComponentProvider {
|
|||
blockOneEnd.addChangeListener(new AddressChangeListener(blockOneEnd));
|
||||
blockTwoStart.addChangeListener(new AddressChangeListener(blockTwoStart));
|
||||
|
||||
ActionListener al = new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
setStatusText("");
|
||||
}
|
||||
};
|
||||
ActionListener al = e -> setStatusText("");
|
||||
blockOneLengthField.addActionListener(al);
|
||||
blockTwoLengthField.addActionListener(al);
|
||||
blockOneEnd.addActionListener(al);
|
||||
|
|
|
@ -366,6 +366,7 @@ public class LocationReferencesProvider extends ComponentProviderAdapter
|
|||
|
||||
@Override
|
||||
public void closeComponent() {
|
||||
super.closeComponent();
|
||||
locationReferencesPlugin.providerDismissed(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,6 @@ public class BundleStatusComponentProvider extends ComponentProviderAdapter {
|
|||
private final BundleStatusTableModel bundleStatusTableModel;
|
||||
private GTableFilterPanel<BundleStatus> filterPanel;
|
||||
|
||||
private GhidraFileChooser fileChooser;
|
||||
private GhidraFileFilter filter;
|
||||
private final BundleHost bundleHost;
|
||||
private transient boolean isDisposed;
|
||||
|
@ -94,7 +93,6 @@ public class BundleStatusComponentProvider extends ComponentProviderAdapter {
|
|||
return GhidraBundle.getType(file) != GhidraBundle.Type.INVALID;
|
||||
}
|
||||
};
|
||||
this.fileChooser = null;
|
||||
|
||||
build();
|
||||
addToTool();
|
||||
|
@ -249,38 +247,29 @@ public class BundleStatusComponentProvider extends ComponentProviderAdapter {
|
|||
}
|
||||
|
||||
private void showAddBundlesFileChooser() {
|
||||
if (fileChooser == null) {
|
||||
fileChooser = new GhidraFileChooser(getComponent());
|
||||
fileChooser.setMultiSelectionEnabled(true);
|
||||
fileChooser.setFileSelectionMode(GhidraFileChooserMode.FILES_AND_DIRECTORIES);
|
||||
fileChooser.setTitle("Select Bundle(s)");
|
||||
// fileChooser.setApproveButtonToolTipText(title);
|
||||
if (filter != null) {
|
||||
fileChooser.addFileFilter(new GhidraFileFilter() {
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return filter.getDescription();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(File f, GhidraFileChooserModel model) {
|
||||
return filter.accept(f, model);
|
||||
}
|
||||
});
|
||||
}
|
||||
String lastSelected = Preferences.getProperty(PREFERENCE_LAST_SELECTED_BUNDLE);
|
||||
if (lastSelected != null) {
|
||||
File lastSelectedFile = new File(lastSelected);
|
||||
fileChooser.setSelectedFile(lastSelectedFile);
|
||||
}
|
||||
GhidraFileChooser fileChooser = new GhidraFileChooser(getComponent());
|
||||
fileChooser.setMultiSelectionEnabled(true);
|
||||
fileChooser.setFileSelectionMode(GhidraFileChooserMode.FILES_AND_DIRECTORIES);
|
||||
fileChooser.setTitle("Select Bundle(s)");
|
||||
// fileChooser.setApproveButtonToolTipText(title);
|
||||
if (filter != null) {
|
||||
fileChooser.addFileFilter(new GhidraFileFilter() {
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return filter.getDescription();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(File f, GhidraFileChooserModel model) {
|
||||
return filter.accept(f, model);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
String lastSelected = Preferences.getProperty(PREFERENCE_LAST_SELECTED_BUNDLE);
|
||||
if (lastSelected != null) {
|
||||
File lastSelectedFile = new File(lastSelected);
|
||||
fileChooser.setSelectedFile(lastSelectedFile);
|
||||
}
|
||||
fileChooser.rescanCurrentDirectory();
|
||||
String lastSelected = Preferences.getProperty(PREFERENCE_LAST_SELECTED_BUNDLE);
|
||||
if (lastSelected != null) {
|
||||
File lastSelectedFile = new File(lastSelected);
|
||||
fileChooser.setSelectedFile(lastSelectedFile);
|
||||
}
|
||||
|
||||
List<File> files = fileChooser.getSelectedFiles();
|
||||
|
@ -304,6 +293,8 @@ public class BundleStatusComponentProvider extends ComponentProviderAdapter {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
fileChooser.dispose();
|
||||
}
|
||||
|
||||
protected List<BundleStatus> getSelectedStatuses() {
|
||||
|
|
|
@ -69,7 +69,6 @@ public class AddressTypeOverviewColorService
|
|||
private Listing listing;
|
||||
private OverviewColorComponent overviewComponent;
|
||||
private PluginTool tool;
|
||||
private DialogComponentProvider legendDialog;
|
||||
private AddressTypeOverviewLegendPanel legendPanel;
|
||||
|
||||
@Override
|
||||
|
@ -336,12 +335,12 @@ public class AddressTypeOverviewColorService
|
|||
}
|
||||
|
||||
private DialogComponentProvider getLegendDialog() {
|
||||
if (legendDialog == null) {
|
||||
if (legendPanel == null) {
|
||||
legendPanel = new AddressTypeOverviewLegendPanel(this);
|
||||
|
||||
legendDialog =
|
||||
new OverviewColorLegendDialog("Overview Legend", legendPanel, getHelpLocation());
|
||||
}
|
||||
|
||||
OverviewColorLegendDialog legendDialog =
|
||||
new OverviewColorLegendDialog("Overview Legend", legendPanel, getHelpLocation());
|
||||
return legendDialog;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,6 @@ public class EntropyOverviewColorService implements OverviewColorService {
|
|||
private OverviewPalette palette;
|
||||
private EntropyOverviewOptionsManager entropyOptionsManager;
|
||||
private OverviewColorComponent overviewComponent;
|
||||
private OverviewColorLegendDialog legendDialog;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
|
@ -193,9 +192,6 @@ public class EntropyOverviewColorService implements OverviewColorService {
|
|||
if (overviewComponent != null) {
|
||||
overviewComponent.refreshAll();
|
||||
}
|
||||
if (legendDialog != null) {
|
||||
legendDialog.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -219,12 +215,11 @@ public class EntropyOverviewColorService implements OverviewColorService {
|
|||
}
|
||||
|
||||
private DialogComponentProvider getLegendDialog() {
|
||||
if (legendDialog == null) {
|
||||
LegendPanel legendPanel = new LegendPanel();
|
||||
legendPanel.setPalette(palette);
|
||||
legendDialog =
|
||||
new OverviewColorLegendDialog("Entropy Legend", legendPanel, getHelpLocation());
|
||||
}
|
||||
|
||||
LegendPanel legendPanel = new LegendPanel();
|
||||
legendPanel.setPalette(palette);
|
||||
OverviewColorLegendDialog legendDialog =
|
||||
new OverviewColorLegendDialog("Entropy Legend", legendPanel, getHelpLocation());
|
||||
return legendDialog;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,13 +20,13 @@ import java.awt.event.*;
|
|||
|
||||
import javax.swing.*;
|
||||
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.ReusableDialogComponentProvider;
|
||||
import docking.widgets.button.GRadioButton;
|
||||
import docking.widgets.checkbox.GCheckBox;
|
||||
import generic.theme.Gui;
|
||||
import ghidra.util.HelpLocation;
|
||||
|
||||
public class PrintOptionsDialog extends DialogComponentProvider {
|
||||
public class PrintOptionsDialog extends ReusableDialogComponentProvider {
|
||||
|
||||
private static final String FONT_ID = "font.print";
|
||||
private boolean selectionEnabled;
|
||||
|
|
|
@ -76,6 +76,15 @@ public class PrintingPlugin extends ProgramPlugin {
|
|||
cvService = tool.getService(CodeViewerService.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispose() {
|
||||
super.dispose();
|
||||
|
||||
if (pod != null) {
|
||||
pod.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void programActivated(Program program) {
|
||||
printAction.setEnabled(true);
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
package ghidra.app.plugin.core.progmgr;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.beans.PropertyEditor;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
@ -83,12 +82,13 @@ public class ProgramManagerPlugin extends Plugin implements ProgramManager {
|
|||
private MultiProgramManager programMgr;
|
||||
private ProgramSaveManager programSaveMgr;
|
||||
private int transactionID = -1;
|
||||
private OpenVersionedFileDialog<Program> openDialog;
|
||||
private boolean locked = false;
|
||||
private UndoAction undoAction;
|
||||
private RedoAction redoAction;
|
||||
private ProgramLocation currentLocation;
|
||||
|
||||
private OpenVersionedFileDialog<Program> openDialog;
|
||||
|
||||
public ProgramManagerPlugin(PluginTool tool) {
|
||||
super(tool);
|
||||
|
||||
|
@ -297,6 +297,9 @@ public class ProgramManagerPlugin extends Plugin implements ProgramManager {
|
|||
public void dispose() {
|
||||
programMgr.dispose();
|
||||
tool.clearLastEvents();
|
||||
if (openDialog != null) {
|
||||
openDialog.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -567,6 +570,7 @@ public class ProgramManagerPlugin extends Plugin implements ProgramManager {
|
|||
});
|
||||
dialog.setHelpLocation(new HelpLocation(HelpTopics.PROGRAM, "Program_Options"));
|
||||
tool.showDialog(dialog);
|
||||
dialog.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -605,8 +609,12 @@ public class ProgramManagerPlugin extends Plugin implements ProgramManager {
|
|||
}
|
||||
|
||||
private void open() {
|
||||
|
||||
if (openDialog == null) {
|
||||
ActionListener listener = e -> {
|
||||
openDialog = new OpenVersionedFileDialog<>(tool, "Open Program", Program.class);
|
||||
openDialog.setHelpLocation(new HelpLocation(HelpTopics.PROGRAM, "Open_File_Dialog"));
|
||||
|
||||
openDialog.addOkActionListener(e -> {
|
||||
DomainFile domainFile = openDialog.getDomainFile();
|
||||
int version = openDialog.getVersion();
|
||||
if (domainFile == null) {
|
||||
|
@ -616,11 +624,9 @@ public class ProgramManagerPlugin extends Plugin implements ProgramManager {
|
|||
openDialog.close();
|
||||
doOpenProgram(domainFile, version, OPEN_CURRENT);
|
||||
}
|
||||
};
|
||||
openDialog = new OpenVersionedFileDialog<>(tool, "Open Program", Program.class);
|
||||
openDialog.setHelpLocation(new HelpLocation(HelpTopics.PROGRAM, "Open_File_Dialog"));
|
||||
openDialog.addOkActionListener(listener);
|
||||
});
|
||||
}
|
||||
|
||||
tool.showDialog(openDialog);
|
||||
contextChanged();
|
||||
}
|
||||
|
|
|
@ -38,7 +38,6 @@ import ghidra.util.task.*;
|
|||
class ProgramSaveManager {
|
||||
private ProgramManager programMgr;
|
||||
private PluginTool tool;
|
||||
private DataTreeDialog dataTreeSaveDialog;
|
||||
private boolean treeDialogCancelled;
|
||||
private DomainFileFilter domainFileFilter;
|
||||
|
||||
|
@ -450,37 +449,35 @@ class ProgramSaveManager {
|
|||
}
|
||||
|
||||
private DataTreeDialog getSaveDialog() {
|
||||
if (dataTreeSaveDialog == null) {
|
||||
DataTreeDialog dialog =
|
||||
new DataTreeDialog(null, "Save As", DataTreeDialog.SAVE, domainFileFilter);
|
||||
|
||||
ActionListener listener = event -> {
|
||||
DomainFolder folder = dataTreeSaveDialog.getDomainFolder();
|
||||
String newName = dataTreeSaveDialog.getNameText();
|
||||
if (newName.length() == 0) {
|
||||
dataTreeSaveDialog.setStatusText("Please enter a name");
|
||||
return;
|
||||
}
|
||||
else if (folder == null) {
|
||||
dataTreeSaveDialog.setStatusText("Please select a folder");
|
||||
return;
|
||||
}
|
||||
ActionListener listener = event -> {
|
||||
DomainFolder folder = dialog.getDomainFolder();
|
||||
String newName = dialog.getNameText();
|
||||
if (newName.length() == 0) {
|
||||
dialog.setStatusText("Please enter a name");
|
||||
return;
|
||||
}
|
||||
else if (folder == null) {
|
||||
dialog.setStatusText("Please select a folder");
|
||||
return;
|
||||
}
|
||||
|
||||
DomainFile file = folder.getFile(newName);
|
||||
if (file != null && file.isReadOnly()) {
|
||||
dataTreeSaveDialog.setStatusText("Read Only. Choose new name/folder");
|
||||
}
|
||||
else {
|
||||
dataTreeSaveDialog.close();
|
||||
treeDialogCancelled = false;
|
||||
}
|
||||
};
|
||||
dataTreeSaveDialog =
|
||||
new DataTreeDialog(null, "Save As", DataTreeDialog.SAVE, domainFileFilter);
|
||||
DomainFile file = folder.getFile(newName);
|
||||
if (file != null && file.isReadOnly()) {
|
||||
dialog.setStatusText("Read Only. Choose new name/folder");
|
||||
}
|
||||
else {
|
||||
dialog.close();
|
||||
treeDialogCancelled = false;
|
||||
}
|
||||
};
|
||||
|
||||
dataTreeSaveDialog.addOkActionListener(listener);
|
||||
dataTreeSaveDialog.setHelpLocation(
|
||||
new HelpLocation(HelpTopics.PROGRAM, "Save_As_File"));
|
||||
}
|
||||
return dataTreeSaveDialog;
|
||||
dialog.addOkActionListener(listener);
|
||||
dialog.setHelpLocation(new HelpLocation(HelpTopics.PROGRAM, "Save_As_File"));
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
||||
class SaveFileTask extends Task {
|
||||
|
|
|
@ -19,12 +19,11 @@ import java.awt.*;
|
|||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import org.jdom.Element;
|
||||
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.ReusableDialogComponentProvider;
|
||||
import docking.widgets.button.GRadioButton;
|
||||
import ghidra.framework.options.SaveState;
|
||||
import ghidra.program.model.address.Address;
|
||||
|
@ -35,7 +34,7 @@ import ghidra.program.model.symbol.Reference;
|
|||
import ghidra.util.HelpLocation;
|
||||
import ghidra.util.exception.AssertException;
|
||||
|
||||
public class EditReferenceDialog extends DialogComponentProvider {
|
||||
public class EditReferenceDialog extends ReusableDialogComponentProvider {
|
||||
|
||||
static final int PREFERRED_PANEL_HEIGHT = 190;
|
||||
static final int PREFERRED_PANEL_WIDTH = 450;
|
||||
|
@ -63,7 +62,7 @@ public class EditReferenceDialog extends DialogComponentProvider {
|
|||
private boolean initializing;
|
||||
|
||||
public EditReferenceDialog(ReferencesPlugin plugin) {
|
||||
super("Edit Reference", true);
|
||||
super("Edit Reference");
|
||||
this.plugin = plugin;
|
||||
addWorkPanel(buildMainPanel());
|
||||
addApplyButton();
|
||||
|
@ -72,17 +71,12 @@ public class EditReferenceDialog extends DialogComponentProvider {
|
|||
setDefaultButton(applyButton);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispose of this dialog.
|
||||
*/
|
||||
@Override
|
||||
public void dispose() {
|
||||
close();
|
||||
cleanup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current code unit displayed.
|
||||
*/
|
||||
CodeUnit getCurrentCodeUnit() {
|
||||
return instrPanel.getCurrentCodeUnit();
|
||||
}
|
||||
|
@ -120,15 +114,12 @@ public class EditReferenceDialog extends DialogComponentProvider {
|
|||
|
||||
JPanel refTypePanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 5));
|
||||
refTypePanel.setBorder(new TitledBorder(new EtchedBorder(), "Type of Reference"));
|
||||
ChangeListener refChoiceListener = new ChangeListener() {
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
Object src = e.getSource();
|
||||
if (src instanceof JRadioButton) {
|
||||
JRadioButton refChoiceButton = (JRadioButton) src;
|
||||
if (refChoiceButton.isSelected()) {
|
||||
refChoiceActivated(refChoiceButton);
|
||||
}
|
||||
ChangeListener refChoiceListener = e -> {
|
||||
Object src = e.getSource();
|
||||
if (src instanceof JRadioButton) {
|
||||
JRadioButton refChoiceButton = (JRadioButton) src;
|
||||
if (refChoiceButton.isSelected()) {
|
||||
refChoiceActivated(refChoiceButton);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -101,6 +101,7 @@ public class ResourceActionsPlugin extends Plugin {
|
|||
chooser.setApproveButtonText("Save Image As");
|
||||
chooser.addFileFilter(GRAPHIC_FORMATS_FILTER);
|
||||
File f = chooser.getSelectedFile();
|
||||
chooser.dispose();
|
||||
if (f != null) {
|
||||
if (f.exists() && OptionDialog.showYesNoDialog(tool.getActiveWindow(),
|
||||
"Overwrite Existing File?",
|
||||
|
@ -146,6 +147,7 @@ public class ResourceActionsPlugin extends Plugin {
|
|||
chooser.setApproveButtonText("Save Image As");
|
||||
chooser.addFileFilter(GRAPHIC_FORMATS_FILTER);
|
||||
File f = chooser.getSelectedFile();
|
||||
chooser.dispose();
|
||||
if (f != null) {
|
||||
if (f.exists() && OptionDialog.showYesNoDialog(tool.getActiveWindow(),
|
||||
"Overwrite Existing File?",
|
||||
|
|
|
@ -628,11 +628,15 @@ public class GhidraScriptEditorComponentProvider extends ComponentProvider {
|
|||
}
|
||||
|
||||
private void closeComponentSavingAsNecessary() {
|
||||
provider.removeScriptEditor(scriptSourceFile, true);
|
||||
if (provider.removeScriptEditor(scriptSourceFile, true)) {
|
||||
super.closeComponent();
|
||||
}
|
||||
}
|
||||
|
||||
private void closeComponentWithoutSaving() {
|
||||
provider.removeScriptEditor(scriptSourceFile, false);
|
||||
if (provider.removeScriptEditor(scriptSourceFile, false)) {
|
||||
super.closeComponent();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -50,7 +50,7 @@ import ghidra.util.task.Task;
|
|||
* backward searching, proper endianness and whether to find just
|
||||
* the next occurrence or all of them in the program.
|
||||
*/
|
||||
class MemSearchDialog extends DialogComponentProvider {
|
||||
class MemSearchDialog extends ReusableDialogComponentProvider {
|
||||
|
||||
static final String ADVANCED_BUTTON_NAME = "mem.search.advanced";
|
||||
private static final String CODE_UNIT_SCOPE_NAME = "Code Unit Scope";
|
||||
|
|
|
@ -39,7 +39,7 @@ import ghidra.util.task.TaskMonitorComponent;
|
|||
/**
|
||||
* Dialog for showing options to search text in a Program.
|
||||
*/
|
||||
class SearchTextDialog extends DialogComponentProvider {
|
||||
class SearchTextDialog extends ReusableDialogComponentProvider {
|
||||
|
||||
private static final int DEFAULT_MAX_ENTRIES = 10;
|
||||
|
||||
|
|
|
@ -179,14 +179,17 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
|
|||
|
||||
navigatable = null;
|
||||
|
||||
if (searchDialog != null && searchDialog.isVisible()) {
|
||||
TaskMonitor taskMonitor = searchDialog.getTaskMonitorComponent();
|
||||
taskMonitor.cancel();
|
||||
searchDialog.dispose();
|
||||
if (searchDialog != null) {
|
||||
|
||||
if (searchAllTaskMonitor != null) {
|
||||
searchAllTaskMonitor.cancel();
|
||||
if (searchDialog.isVisible()) {
|
||||
TaskMonitor taskMonitor = searchDialog.getTaskMonitorComponent();
|
||||
taskMonitor.cancel();
|
||||
if (searchAllTaskMonitor != null) {
|
||||
searchAllTaskMonitor.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
searchDialog.dispose();
|
||||
}
|
||||
|
||||
if (currentTask != null) {
|
||||
|
|
|
@ -16,14 +16,12 @@
|
|||
package ghidra.app.plugin.core.select;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import docking.ComponentProvider;
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.ReusableDialogComponentProvider;
|
||||
import docking.widgets.button.GRadioButton;
|
||||
import docking.widgets.label.GLabel;
|
||||
import docking.widgets.textfield.IntegerTextField;
|
||||
|
@ -39,7 +37,7 @@ import ghidra.util.layout.PairLayout;
|
|||
* Class to set up dialog box that will enable the user
|
||||
* to set the available options for block selection
|
||||
*/
|
||||
class SelectBlockDialog extends DialogComponentProvider {
|
||||
class SelectBlockDialog extends ReusableDialogComponentProvider {
|
||||
private static final String OVERFLOW_SELECTION_WARNING =
|
||||
"Selection is larger than available " + "bytes, using the end of the address space";
|
||||
|
||||
|
@ -53,7 +51,7 @@ class SelectBlockDialog extends DialogComponentProvider {
|
|||
private PluginTool tool;
|
||||
|
||||
SelectBlockDialog(PluginTool tool, Navigatable navigatable) {
|
||||
super("Select Bytes", false);
|
||||
super("Select Bytes", false, true, true, false);
|
||||
this.tool = tool;
|
||||
this.navigatable = navigatable;
|
||||
// navigatable.addNavigatableListener(this);
|
||||
|
@ -113,46 +111,34 @@ class SelectBlockDialog extends DialogComponentProvider {
|
|||
|
||||
forwardButton = new GRadioButton("Select Forward", true);
|
||||
forwardButton.setName("forwardButton");
|
||||
forwardButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent ae) {
|
||||
setStatusText("Enter number of bytes to select");
|
||||
setAddressFieldEnabled(false);
|
||||
setLengthInputEnabled(true);
|
||||
}
|
||||
forwardButton.addActionListener(ae -> {
|
||||
setStatusText("Enter number of bytes to select");
|
||||
setAddressFieldEnabled(false);
|
||||
setLengthInputEnabled(true);
|
||||
});
|
||||
buttonGroup.add(forwardButton);
|
||||
backwardButton = new GRadioButton("Select Backward");
|
||||
backwardButton.setName("backwardButton");
|
||||
backwardButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent ae) {
|
||||
setStatusText("Enter number of bytes to select");
|
||||
setAddressFieldEnabled(false);
|
||||
setLengthInputEnabled(true);
|
||||
}
|
||||
backwardButton.addActionListener(ae -> {
|
||||
setStatusText("Enter number of bytes to select");
|
||||
setAddressFieldEnabled(false);
|
||||
setLengthInputEnabled(true);
|
||||
});
|
||||
buttonGroup.add(backwardButton);
|
||||
allButton = new GRadioButton("Select All");
|
||||
allButton.setName("allButton");
|
||||
allButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent ae) {
|
||||
setItemsEnabled(false);
|
||||
clearStatusText();
|
||||
}
|
||||
allButton.addActionListener(ae -> {
|
||||
setItemsEnabled(false);
|
||||
clearStatusText();
|
||||
});
|
||||
|
||||
buttonGroup.add(allButton);
|
||||
toButton = new GRadioButton("To Address");
|
||||
toButton.setName("toButton");
|
||||
toButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent ae) {
|
||||
setStatusText("Enter an Address to go to");
|
||||
setAddressFieldEnabled(true);
|
||||
setLengthInputEnabled(false);
|
||||
}
|
||||
toButton.addActionListener(ae -> {
|
||||
setStatusText("Enter an Address to go to");
|
||||
setAddressFieldEnabled(true);
|
||||
setLengthInputEnabled(false);
|
||||
});
|
||||
buttonGroup.add(toButton);
|
||||
gbc.gridx = 0;
|
||||
|
@ -298,7 +284,6 @@ class SelectBlockDialog extends DialogComponentProvider {
|
|||
Address currentAddress = navigatable.getLocation().getAddress();
|
||||
length *= currentAddress.getAddressSpace().getAddressableUnitSize();
|
||||
|
||||
AddressFactory addressFactory = navigatable.getProgram().getAddressFactory();
|
||||
AddressSet addressSet = new AddressSet(navigatable.getSelection());
|
||||
if (addressSet.isEmpty()) {
|
||||
addressSet.addRange(currentAddress, currentAddress);
|
||||
|
@ -361,12 +346,7 @@ class SelectBlockDialog extends DialogComponentProvider {
|
|||
}
|
||||
|
||||
private void showWarningDialog(final String text) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
JOptionPane.showMessageDialog(getComponent(), text);
|
||||
}
|
||||
});
|
||||
SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(getComponent(), text));
|
||||
}
|
||||
|
||||
public void setNavigatable(Navigatable navigatable) {
|
||||
|
|
|
@ -57,6 +57,15 @@ public class SelectBlockPlugin extends Plugin {
|
|||
createActions();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispose() {
|
||||
super.dispose();
|
||||
|
||||
if (dialog != null) {
|
||||
dialog.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void createActions() {
|
||||
|
||||
toolBarAction = new NavigatableContextAction("SelectBlock", getName()) {
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
package ghidra.app.plugin.core.string;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -231,23 +229,21 @@ public class SearchStringDialog extends DialogComponentProvider {
|
|||
|
||||
// Set up a file chooser that allows the user to select a new *.sng file.
|
||||
JButton browseButton = new BrowseButton();
|
||||
browseButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
GhidraFileChooser chooser = new GhidraFileChooser(panel);
|
||||
chooser.setTitle("Select Word Model File");
|
||||
chooser.setMultiSelectionEnabled(false);
|
||||
chooser.setFileFilter(new ExtensionFileFilter("sng", "Word File"));
|
||||
browseButton.addActionListener(e -> {
|
||||
GhidraFileChooser chooser = new GhidraFileChooser(panel);
|
||||
chooser.setTitle("Select Word Model File");
|
||||
chooser.setMultiSelectionEnabled(false);
|
||||
chooser.setFileFilter(new ExtensionFileFilter("sng", "Word File"));
|
||||
|
||||
File selectedFile = chooser.getSelectedFile();
|
||||
if (selectedFile == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Important to only save off the name of the file. The NGramUtils call that
|
||||
// loads the file will search for the file given this name.
|
||||
wordModelField.setText(selectedFile.getName());
|
||||
File selectedFile = chooser.getSelectedFile();
|
||||
chooser.dispose();
|
||||
if (selectedFile == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Important to only save off the name of the file. The NGramUtils call that
|
||||
// loads the file will search for the file given this name.
|
||||
wordModelField.setText(selectedFile.getName());
|
||||
});
|
||||
|
||||
modelFieldPanel.add(browseButton);
|
||||
|
|
|
@ -25,7 +25,7 @@ import javax.swing.*;
|
|||
import org.jdom.Element;
|
||||
|
||||
import docking.ComponentProvider;
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.ReusableDialogComponentProvider;
|
||||
import docking.widgets.checkbox.GCheckBox;
|
||||
import docking.widgets.label.GHtmlLabel;
|
||||
import docking.widgets.label.GIconLabel;
|
||||
|
@ -35,7 +35,7 @@ import ghidra.util.*;
|
|||
import ghidra.util.layout.*;
|
||||
import resources.Icons;
|
||||
|
||||
public class FilterDialog extends DialogComponentProvider {
|
||||
public class FilterDialog extends ReusableDialogComponentProvider {
|
||||
private NewSymbolFilter filter;
|
||||
private JPanel advancedPanel;
|
||||
private JPanel advancedFilterPanel;
|
||||
|
@ -48,7 +48,7 @@ public class FilterDialog extends DialogComponentProvider {
|
|||
private PluginTool tool;
|
||||
|
||||
public FilterDialog(PluginTool tool) {
|
||||
super("Symbol Table Filter", false);
|
||||
super("Symbol Table Filter", false, true, true, false);
|
||||
this.tool = tool;
|
||||
filter = new NewSymbolFilter();
|
||||
addWorkPanel(buildWorkPanel());
|
||||
|
|
|
@ -133,9 +133,7 @@ class SymbolPanel extends JPanel {
|
|||
symTable.dispose();
|
||||
threadedTablePanel.dispose();
|
||||
tableFilterPanel.dispose();
|
||||
symProvider = null;
|
||||
filterDialog.close();
|
||||
filterDialog = null;
|
||||
filterDialog.dispose();
|
||||
}
|
||||
|
||||
void setFilter() {
|
||||
|
|
|
@ -287,7 +287,7 @@ public class TableComponentProvider<T> extends ComponentProviderAdapter
|
|||
navigatable.removeNavigatableListener(this);
|
||||
}
|
||||
|
||||
tool.removeComponentProvider(this);
|
||||
super.closeComponent();
|
||||
tableServicePlugin.remove(this);
|
||||
|
||||
if (markerSet != null) {
|
||||
|
|
|
@ -22,8 +22,8 @@ import java.util.List;
|
|||
import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.DockingWindowManager;
|
||||
import docking.ReusableDialogComponentProvider;
|
||||
import docking.widgets.checkbox.GCheckBox;
|
||||
import docking.widgets.label.GLabel;
|
||||
import generic.theme.GIcon;
|
||||
|
@ -31,7 +31,7 @@ import generic.theme.GThemeDefaults.Colors;
|
|||
import generic.theme.GThemeDefaults.Colors.Java;
|
||||
import generic.theme.Gui;
|
||||
|
||||
class TipOfTheDayDialog extends DialogComponentProvider {
|
||||
class TipOfTheDayDialog extends ReusableDialogComponentProvider {
|
||||
private static final String FONT_ID = "font.plugin.tips";
|
||||
private static final String FONT_LABEL_ID = "font.plugin.tips.label";
|
||||
private static final int _24_HOURS = 86400000;
|
||||
|
|
|
@ -134,7 +134,6 @@ public class GenerateOldLanguagePlugin extends Plugin implements ApplicationLeve
|
|||
|
||||
private JPanel panel;
|
||||
private SelectLanguagePanel selectLangPanel;
|
||||
private GhidraFileChooser chooser;
|
||||
|
||||
GenerateOldLanguageDialog(final boolean skipOldLangGeneration) {
|
||||
super("Select Old Language", true, true, true, false);
|
||||
|
@ -169,17 +168,17 @@ public class GenerateOldLanguagePlugin extends Plugin implements ApplicationLeve
|
|||
return;
|
||||
}
|
||||
|
||||
if (chooser == null) {
|
||||
chooser = new GhidraFileChooser(panel);
|
||||
chooser.setTitle("Specify Old Language Output File");
|
||||
chooser.setFileFilter(OLD_LANG_FILTER);
|
||||
chooser.setApproveButtonText("Create");
|
||||
// there's no single directory; you need to pick it yourself now
|
||||
GhidraFileChooser chooser = new GhidraFileChooser(panel);
|
||||
chooser.setTitle("Specify Old Language Output File");
|
||||
chooser.setFileFilter(OLD_LANG_FILTER);
|
||||
chooser.setApproveButtonText("Create");
|
||||
// there's no single directory; you need to pick it yourself now
|
||||
// chooser.setCurrentDirectory(LANGUAGE_DIR);
|
||||
chooser.setCurrentDirectory(
|
||||
Application.getApplicationRootDirectory().getFile(false));
|
||||
}
|
||||
chooser.setCurrentDirectory(
|
||||
Application.getApplicationRootDirectory().getFile(false));
|
||||
|
||||
File file = chooser.getSelectedFile(true);
|
||||
chooser.dispose();
|
||||
if (file == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -234,7 +233,6 @@ public class GenerateOldLanguagePlugin extends Plugin implements ApplicationLeve
|
|||
|
||||
private JPanel panel;
|
||||
private SelectLanguagePanel selectLangPanel;
|
||||
private GhidraFileChooser chooser;
|
||||
|
||||
private Language oldLang;
|
||||
private File oldLangFile;
|
||||
|
@ -269,17 +267,18 @@ public class GenerateOldLanguagePlugin extends Plugin implements ApplicationLeve
|
|||
|
||||
File transFile;
|
||||
if (GenerateTranslatorDialog.this.oldLangFile == null) {
|
||||
if (chooser == null) {
|
||||
chooser = new GhidraFileChooser(panel);
|
||||
chooser.setTitle("Specify Old Language Output File");
|
||||
chooser.setFileFilter(TRANSLATOR_FILTER);
|
||||
chooser.setApproveButtonText("Create");
|
||||
// there's no single directory; you need to pick it yourself now
|
||||
|
||||
GhidraFileChooser chooser = new GhidraFileChooser(panel);
|
||||
chooser.setTitle("Specify Old Language Output File");
|
||||
chooser.setFileFilter(TRANSLATOR_FILTER);
|
||||
chooser.setApproveButtonText("Create");
|
||||
// there's no single directory; you need to pick it yourself now
|
||||
// chooser.setCurrentDirectory(LANGUAGE_DIR);
|
||||
chooser.setCurrentDirectory(
|
||||
Application.getApplicationRootDirectory().getFile(false));
|
||||
}
|
||||
chooser.setCurrentDirectory(
|
||||
Application.getApplicationRootDirectory().getFile(false));
|
||||
|
||||
transFile = chooser.getSelectedFile(true);
|
||||
chooser.dispose();
|
||||
if (transFile == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -533,7 +532,7 @@ public class GenerateOldLanguagePlugin extends Plugin implements ApplicationLeve
|
|||
public List<LanguageDescription> getLanguageDescriptions(
|
||||
boolean includeDeprecatedLanguages) {
|
||||
// Include deprecated languages
|
||||
List<LanguageDescription> list = new ArrayList<LanguageDescription>();
|
||||
List<LanguageDescription> list = new ArrayList<>();
|
||||
list.addAll(langService.getLanguageDescriptions(true));
|
||||
if (includeOldLanguages) {
|
||||
list.addAll(Arrays.asList(oldLangFactory.getLatestOldLanaguageDescriptions()));
|
||||
|
|
|
@ -2044,7 +2044,7 @@ public abstract class GhidraScript extends FlatProgramAPI {
|
|||
chooser.setApproveButtonText(approveButtonText);
|
||||
chooser.setFileSelectionMode(GhidraFileChooserMode.FILES_ONLY);
|
||||
File file = chooser.getSelectedFile();
|
||||
|
||||
chooser.dispose();
|
||||
if (chooser.wasCancelled()) {
|
||||
throw new CancelledException();
|
||||
}
|
||||
|
@ -2121,7 +2121,7 @@ public abstract class GhidraScript extends FlatProgramAPI {
|
|||
chooser.setApproveButtonText(approveButtonText);
|
||||
chooser.setFileSelectionMode(GhidraFileChooserMode.DIRECTORIES_ONLY);
|
||||
File file = chooser.getSelectedFile();
|
||||
|
||||
chooser.dispose();
|
||||
if (chooser.wasCancelled()) {
|
||||
throw new CancelledException();
|
||||
}
|
||||
|
|
|
@ -15,13 +15,6 @@
|
|||
*/
|
||||
package ghidra.app.util;
|
||||
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.DataTypeComponent;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.util.HelpLocation;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
import javax.swing.*;
|
||||
|
@ -30,6 +23,12 @@ import javax.swing.border.TitledBorder;
|
|||
|
||||
import docking.ComponentProvider;
|
||||
import docking.DialogComponentProvider;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.DataTypeComponent;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.util.HelpLocation;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
public class EditFieldNameDialog extends DialogComponentProvider {
|
||||
|
||||
|
@ -40,7 +39,7 @@ public class EditFieldNameDialog extends DialogComponentProvider {
|
|||
private Program program;
|
||||
private DataTypeComponent dtComp;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Construct a new dialog.
|
||||
*
|
||||
* @param title title for the dialog, null value is acceptable if no title
|
||||
|
@ -63,8 +62,6 @@ public class EditFieldNameDialog extends DialogComponentProvider {
|
|||
setMinimumSize(new Dimension(300, 50));
|
||||
}
|
||||
|
||||
|
||||
|
||||
private String getCurrentFieldName() {
|
||||
String name = dtComp.getFieldName();
|
||||
if (name == null) {
|
||||
|
@ -77,29 +74,31 @@ public class EditFieldNameDialog extends DialogComponentProvider {
|
|||
* This method gets called when the user clicks on the OK Button. The base
|
||||
* class calls this method.
|
||||
*/
|
||||
@Override
|
||||
protected void okCallback() {
|
||||
@Override
|
||||
protected void okCallback() {
|
||||
|
||||
String newName = fieldName.getText().trim();
|
||||
String newName = fieldName.getText().trim();
|
||||
|
||||
if (newName.equals(getCurrentFieldName())) {
|
||||
close();
|
||||
return;
|
||||
}
|
||||
if (newName.equals(getCurrentFieldName())) {
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
boolean success = false;
|
||||
int txId = program.startTransaction("Edit Field Name");
|
||||
try {
|
||||
boolean success = false;
|
||||
int txId = program.startTransaction("Edit Field Name");
|
||||
try {
|
||||
dtComp.setFieldName(newName);
|
||||
DataType parent = dtComp.getParent();
|
||||
if (parent != null) {
|
||||
long timeNow = System.currentTimeMillis();
|
||||
parent.setLastChangeTime(timeNow);
|
||||
parent.setLastChangeTime(timeNow);
|
||||
}
|
||||
success = true;
|
||||
} catch (DuplicateNameException e) {
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
setStatusText(e.getMessage());
|
||||
} finally {
|
||||
}
|
||||
finally {
|
||||
program.endTransaction(txId, true);
|
||||
}
|
||||
|
||||
|
@ -108,22 +107,24 @@ public class EditFieldNameDialog extends DialogComponentProvider {
|
|||
program = null;
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public void editField(DataTypeComponent dataTypeComponent, Program p) {
|
||||
ComponentProvider componentProvider = tool.getComponentProvider(PluginConstants.CODE_BROWSER);
|
||||
JComponent component = componentProvider.getComponent();
|
||||
editField( dataTypeComponent, p, component );
|
||||
}
|
||||
|
||||
public void editField(DataTypeComponent dataTypeComponent, Program p, Component centeredOverComponent ) {
|
||||
this.dtComp = dataTypeComponent;
|
||||
this.program = p;
|
||||
String name = getCurrentFieldName();
|
||||
setTitle("Edit Field Name: "+ dataTypeComponent.getParent().getName() + "." + name);
|
||||
fieldName.setText(name);
|
||||
clearStatusText();
|
||||
tool.showDialog(this, centeredOverComponent);
|
||||
public void editField(DataTypeComponent dataTypeComponent, Program p) {
|
||||
ComponentProvider componentProvider =
|
||||
tool.getComponentProvider(PluginConstants.CODE_BROWSER);
|
||||
JComponent component = componentProvider.getComponent();
|
||||
editField(dataTypeComponent, p, component);
|
||||
}
|
||||
|
||||
public void editField(DataTypeComponent dataTypeComponent, Program p,
|
||||
Component centeredOverComponent) {
|
||||
this.dtComp = dataTypeComponent;
|
||||
this.program = p;
|
||||
String name = getCurrentFieldName();
|
||||
setTitle("Edit Field Name: " + dataTypeComponent.getParent().getName() + "." + name);
|
||||
fieldName.setText(name);
|
||||
clearStatusText();
|
||||
tool.showDialog(this, centeredOverComponent);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -139,7 +140,7 @@ public class EditFieldNameDialog extends DialogComponentProvider {
|
|||
|
||||
mainPanel.add(fieldName, BorderLayout.CENTER);
|
||||
|
||||
mainPanel.setBorder(new EmptyBorder(5,5,5,5));
|
||||
mainPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
|
||||
|
||||
return mainPanel;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ public class OptionsDialog extends DialogComponentProvider implements OptionList
|
|||
private OptionValidator validator;
|
||||
|
||||
/**
|
||||
* Contructs a new OptionsDialog for editing the options associated with a specific import format
|
||||
* Constructs a new OptionsDialog for editing the options associated with a specific import format
|
||||
* such as PE, ELF, XML, etc.
|
||||
*
|
||||
* @param originalOptions the list of options generated from the specific import format selected.
|
||||
|
|
|
@ -15,12 +15,11 @@
|
|||
*/
|
||||
package ghidra.app.util.bin.format.dwarf4.external;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import docking.action.builder.ActionBuilder;
|
||||
import docking.tool.ToolConstants;
|
||||
import docking.widgets.filechooser.GhidraFileChooser;
|
||||
|
@ -70,6 +69,7 @@ public class DWARFExternalDebugFilesPlugin extends Plugin {
|
|||
chooser.setFileSelectionMode(GhidraFileChooserMode.DIRECTORIES_ONLY);
|
||||
chooser.setTitle("Select External Debug Files Directory");
|
||||
File selectedDir = chooser.getSelectedFile();
|
||||
chooser.dispose();
|
||||
if (selectedDir == null) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -62,8 +62,6 @@ import ghidra.util.task.TaskBuilder;
|
|||
*/
|
||||
public class ImporterDialog extends DialogComponentProvider {
|
||||
|
||||
public static final String LAST_IMPORTFILE_PREFERENCE_KEY = "Importer.LastFile";
|
||||
|
||||
protected PluginTool tool;
|
||||
private ProgramManager programManager;
|
||||
protected FSRL fsrl;
|
||||
|
@ -118,7 +116,7 @@ public class ImporterDialog extends DialogComponentProvider {
|
|||
// only save the imported file's path if its a local filesystem path that
|
||||
// will be valid when used later. FSRL paths that drill into container files
|
||||
// aren't widely supported yet.
|
||||
Preferences.setProperty(LAST_IMPORTFILE_PREFERENCE_KEY, fsrl.getPath());
|
||||
Preferences.setProperty(Preferences.LAST_IMPORT_FILE, fsrl.getPath());
|
||||
}
|
||||
|
||||
addWorkPanel(buildWorkPanel());
|
||||
|
|
|
@ -15,12 +15,11 @@
|
|||
*/
|
||||
package ghidra.plugin.importer;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.action.*;
|
||||
|
@ -139,7 +138,10 @@ public class ImporterPlugin extends Plugin
|
|||
frontEndService.removeProjectListener(this);
|
||||
frontEndService = null;
|
||||
}
|
||||
chooser = null;
|
||||
|
||||
if (chooser != null) {
|
||||
chooser.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -327,7 +329,7 @@ public class ImporterPlugin extends Plugin
|
|||
chooser.setTitle(title);
|
||||
chooser.setApproveButtonText(buttonText);
|
||||
|
||||
String lastFile = Preferences.getProperty(ImporterDialog.LAST_IMPORTFILE_PREFERENCE_KEY);
|
||||
String lastFile = Preferences.getProperty(Preferences.LAST_IMPORT_FILE);
|
||||
if (lastFile != null) {
|
||||
chooser.setSelectedFile(new File(lastFile));
|
||||
}
|
||||
|
|
|
@ -144,6 +144,15 @@ class FSBActionManager {
|
|||
}
|
||||
|
||||
public void dispose() {
|
||||
|
||||
if (chooserExport != null) {
|
||||
chooserExport.dispose();
|
||||
}
|
||||
|
||||
if (chooserExportAll != null) {
|
||||
chooserExportAll.dispose();
|
||||
}
|
||||
|
||||
removeActions();
|
||||
}
|
||||
|
||||
|
|
|
@ -15,13 +15,12 @@
|
|||
*/
|
||||
package ghidra.plugins.fsbrowser;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.KeyStroke;
|
||||
|
||||
|
@ -37,8 +36,8 @@ import ghidra.app.plugin.PluginCategoryNames;
|
|||
import ghidra.app.services.*;
|
||||
import ghidra.app.util.opinion.LoaderService;
|
||||
import ghidra.formats.gfilesystem.*;
|
||||
import ghidra.framework.main.FrontEndService;
|
||||
import ghidra.framework.main.ApplicationLevelPlugin;
|
||||
import ghidra.framework.main.FrontEndService;
|
||||
import ghidra.framework.model.Project;
|
||||
import ghidra.framework.model.ProjectListener;
|
||||
import ghidra.framework.plugintool.*;
|
||||
|
@ -70,7 +69,8 @@ import utilities.util.FileUtilities;
|
|||
eventsConsumed = { ProgramActivatedPluginEvent.class }
|
||||
)
|
||||
//@formatter:on
|
||||
public class FileSystemBrowserPlugin extends Plugin implements ApplicationLevelPlugin, ProjectListener,
|
||||
public class FileSystemBrowserPlugin extends Plugin
|
||||
implements ApplicationLevelPlugin, ProjectListener,
|
||||
FileSystemBrowserService {
|
||||
|
||||
/* package */ DockingAction openFilesystemAction;
|
||||
|
@ -128,7 +128,10 @@ public class FileSystemBrowserPlugin extends Plugin implements ApplicationLevelP
|
|||
frontEndService.removeProjectListener(this);
|
||||
frontEndService = null;
|
||||
}
|
||||
chooserOpen = null;
|
||||
|
||||
if (chooserOpen != null) {
|
||||
chooserOpen.dispose();
|
||||
}
|
||||
|
||||
for (FileSystemBrowserComponentProvider provider : currentBrowsers.values()) {
|
||||
provider.dispose();
|
||||
|
|
|
@ -53,6 +53,8 @@ import ghidra.util.task.TaskLauncher;
|
|||
|
||||
public class BatchImportDialog extends DialogComponentProvider {
|
||||
|
||||
private static final String LAST_IMPORT_DIR = "LastBatchImportDir";
|
||||
|
||||
/**
|
||||
* Shows the batch import dialog (via runSwingLater) and prompts the user to select
|
||||
* a file if the supplied {@code batchInfo} is empty.
|
||||
|
@ -96,7 +98,6 @@ public class BatchImportDialog extends DialogComponentProvider {
|
|||
private JButton rescanButton;
|
||||
private JSpinner maxDepthSpinner;
|
||||
|
||||
private GhidraFileChooser fileChooser;
|
||||
private SourcesListModel sourceListModel;
|
||||
|
||||
private BatchImportDialog(BatchInfo batchInfo, DomainFolder defaultFolder) {
|
||||
|
@ -387,20 +388,21 @@ public class BatchImportDialog extends DialogComponentProvider {
|
|||
}
|
||||
|
||||
private boolean addSources() {
|
||||
if (fileChooser == null) {
|
||||
fileChooser = new GhidraFileChooser(getComponent());
|
||||
fileChooser.setMultiSelectionEnabled(true);
|
||||
fileChooser.setTitle("Choose File to Batch Import");
|
||||
fileChooser.setApproveButtonText("Select files");
|
||||
fileChooser.setFileSelectionMode(GhidraFileChooserMode.FILES_AND_DIRECTORIES);
|
||||
fileChooser.addFileFilter(ImporterUtilities.LOADABLE_FILES_FILTER);
|
||||
fileChooser.addFileFilter(ImporterUtilities.CONTAINER_FILES_FILTER);
|
||||
fileChooser.setSelectedFileFilter(GhidraFileFilter.ALL);
|
||||
}
|
||||
|
||||
List<File> selectedFiles = fileChooser.getSelectedFiles();
|
||||
GhidraFileChooser chooser = new GhidraFileChooser(getComponent());
|
||||
chooser.setMultiSelectionEnabled(true);
|
||||
chooser.setTitle("Choose File to Batch Import");
|
||||
chooser.setApproveButtonText("Select files");
|
||||
chooser.setFileSelectionMode(GhidraFileChooserMode.FILES_AND_DIRECTORIES);
|
||||
chooser.addFileFilter(ImporterUtilities.LOADABLE_FILES_FILTER);
|
||||
chooser.addFileFilter(ImporterUtilities.CONTAINER_FILES_FILTER);
|
||||
chooser.setSelectedFileFilter(GhidraFileFilter.ALL);
|
||||
|
||||
chooser.setLastDirectoryPreference(LAST_IMPORT_DIR);
|
||||
|
||||
List<File> selectedFiles = chooser.getSelectedFiles();
|
||||
if (selectedFiles.isEmpty()) {
|
||||
return !fileChooser.wasCancelled();
|
||||
return !chooser.wasCancelled();
|
||||
}
|
||||
|
||||
List<FSRL> filesToAdd = new ArrayList<>();
|
||||
|
@ -408,6 +410,8 @@ public class BatchImportDialog extends DialogComponentProvider {
|
|||
filesToAdd.add(FileSystemService.getInstance().getLocalFSRL(selectedFile));
|
||||
}
|
||||
|
||||
chooser.dispose();
|
||||
|
||||
return addSources(filesToAdd);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@ class BatchProjectDestinationPanel extends JPanel {
|
|||
|
||||
private JComponent parent;
|
||||
private JTextField folderNameTextField;
|
||||
private DataTreeDialog dataTreeDialog;
|
||||
private DomainFolder selectedDomainFolder;
|
||||
|
||||
public BatchProjectDestinationPanel(JComponent parent, DomainFolder defaultFolder) {
|
||||
|
@ -96,7 +95,7 @@ class BatchProjectDestinationPanel extends JPanel {
|
|||
}
|
||||
|
||||
private void browseFolders() {
|
||||
dataTreeDialog =
|
||||
DataTreeDialog dataTreeDialog =
|
||||
new DataTreeDialog(parent, "Choose a project folder", DataTreeDialog.CHOOSE_FOLDER);
|
||||
dataTreeDialog.addOkActionListener(e -> {
|
||||
dataTreeDialog.close();
|
||||
|
@ -107,9 +106,6 @@ class BatchProjectDestinationPanel extends JPanel {
|
|||
}
|
||||
|
||||
public void setFolder(DomainFolder folder) {
|
||||
if (dataTreeDialog != null) {
|
||||
dataTreeDialog.setSelectedFolder(folder);
|
||||
}
|
||||
folderNameTextField.setText(folder != null ? folder.toString() : "< Choose a folder >");
|
||||
this.selectedDomainFolder = folder;
|
||||
onProjectDestinationChange(selectedDomainFolder);
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
package ghidra.app.plugin.core.label;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
|
@ -37,8 +37,6 @@ public class OperandLabelDialogTest extends AbstractGhidraHeadedIntegrationTest
|
|||
private LabelMgrPlugin plugin;
|
||||
private CodeBrowserPlugin cb;
|
||||
private Program program;
|
||||
private OperandLabelDialog dialog;
|
||||
private GhidraComboBox<?> combo;
|
||||
private SetOperandLabelAction setLabelAction;
|
||||
|
||||
@Before
|
||||
|
@ -51,10 +49,6 @@ public class OperandLabelDialogTest extends AbstractGhidraHeadedIntegrationTest
|
|||
plugin = getPlugin(tool, LabelMgrPlugin.class);
|
||||
cb = getPlugin(tool, CodeBrowserPlugin.class);
|
||||
|
||||
dialog = runSwing(() -> plugin.getOperandLabelDialog());
|
||||
|
||||
combo = (GhidraComboBox<?>) findComponentByName(dialog, "MYCHOICE");
|
||||
|
||||
setLabelAction = (SetOperandLabelAction) getAction(plugin, "Set Operand Label");
|
||||
}
|
||||
|
||||
|
@ -80,7 +74,10 @@ public class OperandLabelDialogTest extends AbstractGhidraHeadedIntegrationTest
|
|||
performAction(setLabelAction, context, false);
|
||||
waitForSwing();
|
||||
|
||||
runSwing(() -> combo.setSelectedItem("bob"));
|
||||
OperandLabelDialog dialog = waitForDialogComponent(OperandLabelDialog.class);
|
||||
GhidraComboBox<?> combo = (GhidraComboBox<?>) findComponentByName(dialog, "MYCHOICE");
|
||||
|
||||
setSelectedItem(combo, "bob");
|
||||
|
||||
pressButtonByText(dialog, "OK");
|
||||
waitForSwing();
|
||||
|
@ -94,7 +91,10 @@ public class OperandLabelDialogTest extends AbstractGhidraHeadedIntegrationTest
|
|||
performAction(setLabelAction, context, false);
|
||||
waitForSwing();
|
||||
|
||||
runSwing(() -> combo.setSelectedItem("b"));
|
||||
dialog = waitForDialogComponent(OperandLabelDialog.class);
|
||||
combo = (GhidraComboBox<?>) findComponentByName(dialog, "MYCHOICE");
|
||||
|
||||
setSelectedItem(combo, "b");
|
||||
pressButtonByText(dialog, "OK");
|
||||
|
||||
program.flushEvents();
|
||||
|
@ -108,4 +108,7 @@ public class OperandLabelDialogTest extends AbstractGhidraHeadedIntegrationTest
|
|||
assertEquals("dword ptr [b]", cb.getCurrentFieldText());
|
||||
}
|
||||
|
||||
private void setSelectedItem(GhidraComboBox<?> combo, String s) {
|
||||
runSwing(() -> combo.setSelectedItem(s));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.List;
|
|||
import java.util.Objects;
|
||||
|
||||
import docking.widgets.filechooser.GhidraFileChooser;
|
||||
import docking.widgets.filechooser.GhidraFileChooserMode;
|
||||
import ghidra.bitpatterns.info.ContextRegisterFilter;
|
||||
import ghidra.bitpatterns.info.PatternType;
|
||||
import ghidra.framework.preferences.Preferences;
|
||||
|
@ -88,7 +89,7 @@ public class ExportPatternFileActionListener implements ActionListener {
|
|||
return;
|
||||
}
|
||||
GhidraFileChooser gFileChooser = new GhidraFileChooser(component);
|
||||
gFileChooser.setFileSelectionMode(GhidraFileChooser.FILES_ONLY);
|
||||
gFileChooser.setFileSelectionMode(GhidraFileChooserMode.FILES_ONLY);
|
||||
ExtensionFileFilter xmlFilter = new ExtensionFileFilter("xml", "XML Files");
|
||||
gFileChooser.setFileFilter(xmlFilter);
|
||||
String baseDir = Preferences.getProperty(XML_EXPORT_DIR_PROPERTY);
|
||||
|
@ -97,11 +98,13 @@ public class ExportPatternFileActionListener implements ActionListener {
|
|||
}
|
||||
gFileChooser.setTitle("Select Export File");
|
||||
File outFile = gFileChooser.getSelectedFile();
|
||||
String lastDirPath = gFileChooser.getCurrentDirectory().getAbsolutePath();
|
||||
gFileChooser.dispose();
|
||||
if (gFileChooser.wasCancelled() || outFile == null) {
|
||||
return;
|
||||
}
|
||||
Preferences.setProperty(XML_EXPORT_DIR_PROPERTY,
|
||||
gFileChooser.getCurrentDirectory().getAbsolutePath());
|
||||
|
||||
Preferences.setProperty(XML_EXPORT_DIR_PROPERTY, lastDirPath);
|
||||
Preferences.store();
|
||||
BitsInputDialogComponentProvider bitsProvider =
|
||||
new BitsInputDialogComponentProvider(BITS_PROVIDER_MESSAGE);
|
||||
|
@ -115,7 +118,6 @@ public class ExportPatternFileActionListener implements ActionListener {
|
|||
}
|
||||
catch (IOException e1) {
|
||||
Msg.showError(this, component, "IO Error", "IO error exporting pattern xml file", e1);
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ import docking.action.DockingAction;
|
|||
import docking.action.MenuData;
|
||||
import docking.tool.ToolConstants;
|
||||
import docking.widgets.filechooser.GhidraFileChooser;
|
||||
import docking.widgets.filechooser.GhidraFileChooserMode;
|
||||
import docking.widgets.label.GLabel;
|
||||
import ghidra.bitpatterns.info.*;
|
||||
import ghidra.framework.options.OptionsChangeListener;
|
||||
|
@ -227,13 +228,14 @@ public class FunctionBitPatternsMainProvider extends ComponentProviderAdapter
|
|||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
GhidraFileChooser fileChooser = new GhidraFileChooser(component);
|
||||
fileChooser.setFileSelectionMode(GhidraFileChooser.DIRECTORIES_ONLY);
|
||||
fileChooser.setFileSelectionMode(GhidraFileChooserMode.DIRECTORIES_ONLY);
|
||||
fileChooser.setTitle("Select Directory Containing XML Files");
|
||||
String baseDir = Preferences.getProperty(PATTERN_INFO_DIR);
|
||||
if (baseDir != null) {
|
||||
fileChooser.setCurrentDirectory(new File(baseDir));
|
||||
}
|
||||
File xmlDir = fileChooser.getSelectedFile();
|
||||
fileChooser.dispose();
|
||||
if (xmlDir == null) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.math.BigInteger;
|
|||
import org.xml.sax.SAXException;
|
||||
|
||||
import docking.widgets.filechooser.GhidraFileChooser;
|
||||
import docking.widgets.filechooser.GhidraFileChooserMode;
|
||||
import generic.jar.ResourceFile;
|
||||
import ghidra.app.analyzers.FunctionStartAnalyzer.ContextAction;
|
||||
import ghidra.bitpatterns.info.ContextRegisterFilter;
|
||||
|
@ -59,7 +60,7 @@ public class ImportPatternFileActionListener implements ActionListener {
|
|||
public void actionPerformed(ActionEvent e) {
|
||||
GhidraFileChooser fileChooser = new GhidraFileChooser(component);
|
||||
|
||||
fileChooser.setFileSelectionMode(GhidraFileChooser.FILES_ONLY);
|
||||
fileChooser.setFileSelectionMode(GhidraFileChooserMode.FILES_ONLY);
|
||||
fileChooser.setTitle("Select Pattern File");
|
||||
String baseDir = Preferences.getProperty(XML_IMPORT_DIR_PROPERTY);
|
||||
if (baseDir != null) {
|
||||
|
@ -68,11 +69,13 @@ public class ImportPatternFileActionListener implements ActionListener {
|
|||
ExtensionFileFilter xmlFilter = new ExtensionFileFilter("xml", "XML Files");
|
||||
fileChooser.setFileFilter(xmlFilter);
|
||||
File patternFile = fileChooser.getSelectedFile();
|
||||
String lastDirPath = fileChooser.getCurrentDirectory().getAbsolutePath();
|
||||
fileChooser.dispose();
|
||||
if (fileChooser.wasCancelled() || patternFile == null) {
|
||||
return;
|
||||
}
|
||||
Preferences.setProperty(XML_IMPORT_DIR_PROPERTY,
|
||||
fileChooser.getCurrentDirectory().getAbsolutePath());
|
||||
|
||||
Preferences.setProperty(XML_IMPORT_DIR_PROPERTY, lastDirPath);
|
||||
Preferences.store();
|
||||
//only clear the patterns if new patterns are loaded from a file
|
||||
ResourceFile resource = new ResourceFile(patternFile);
|
||||
|
|
|
@ -146,6 +146,7 @@ public class ProgramByteViewerComponentProvider extends ByteViewerComponentProvi
|
|||
@Override
|
||||
public void closeComponent() {
|
||||
// overridden to handle snapshots
|
||||
super.closeComponent();
|
||||
plugin.closeProvider(this);
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue