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