files = CollectionUtils.asList((List>) obj, File.class);
-
- FileImporterService im = tool.getService(FileImporterService.class);
- if (im == null) {
- tool.setStatusInfo("ERROR: Could not get importer service.");
- return;
- }
-
- DomainFolder rootFolder = tool.getProject().getProjectData().getRootFolder();
-
- if (files.size() == 1 && files.get(0).isFile()) {
- im.importFile(rootFolder, files.get(0));
- }
- else {
- im.importFiles(rootFolder, files);
- }
- }
-}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/Option.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/Option.java
index afe63dcd5f..e5262f5181 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/Option.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/Option.java
@@ -96,6 +96,15 @@ public class Option {
this.listener = listener;
}
+ /**
+ * Override if you want to provide a custom widget for selecting your
+ * options.
+ *
+ * Important! If you override this you MUST also override the {@link #copy()}
+ * method so it returns a new instance of your custom editor.
+ *
+ * @return the custom editor
+ */
public Component getCustomEditorComponent() {
return null;
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/exporter/Compare.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/exporter/Compare.java
index 58ba286399..4b2fb28cb5 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/exporter/Compare.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/exporter/Compare.java
@@ -25,17 +25,17 @@ import ghidra.util.Msg;
public class Compare {
public static void compare(ArrayList expectedList, File actualFile) throws Exception {
int index = 0;
- BufferedReader reader = new BufferedReader(new FileReader(actualFile));
-
+
boolean hasFailure = false;
- try {
+ try (BufferedReader reader = new BufferedReader(new FileReader(actualFile))) {
int excess = 0;
while (true) {
String actualLine = reader.readLine();
if (actualLine == null) {
break;
}
+
if (index >= expectedList.size()) {
++excess;
continue;
@@ -73,8 +73,5 @@ public class Compare {
Assert.fail("One or more failures--see output for data");
}
}
- finally {
- reader.close();
- }
}
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/exporter/IntelHexExporter.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/exporter/IntelHexExporter.java
index 29242fff3b..47ba38d9ef 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/exporter/IntelHexExporter.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/exporter/IntelHexExporter.java
@@ -15,10 +15,15 @@
*/
package ghidra.app.util.exporter;
+import java.awt.BorderLayout;
+import java.awt.Component;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
+import javax.swing.*;
+
+import docking.widgets.textfield.HintTextField;
import ghidra.app.util.*;
import ghidra.app.util.opinion.IntelHexRecord;
import ghidra.app.util.opinion.IntelHexRecordWriter;
@@ -29,18 +34,55 @@ import ghidra.program.model.mem.*;
import ghidra.util.HelpLocation;
import ghidra.util.task.TaskMonitor;
+/**
+ * Exports the current program (or program selection) as bytes in Intel Hex format.
+ *
+ * The output defaults to lines of 16-bytes but this is configurable using the
+ * {@link #recordSizeOption} attribute. This allows users to select any record size
+ * up to the max of 0xFF. Users may also choose to Drop Extra Bytes, which will
+ * cause only lines that match the max record size to be printed; any other
+ * bytes will be dropped. If this option is not set, every byte will be represented in the output.
+ */
public class IntelHexExporter extends Exporter {
- protected final static int MAX_BYTES_PER_LINE = 0x00000010;
-
- protected Option option;
+ /** Option allowing the user to select the address space */
+ protected Option addressSpaceOption;
+
+ /** Option allowing the user to select the number of bytes in each line of output */
+ protected RecordSizeOption recordSizeOption;
+
+ private static final int DEFAULT_RECORD_SIZE = 0x10;
+
/**
- * Constructs a new Intel Hex exporter.
+ * Constructs a new Intel Hex exporter. This will use a record size of 16 (the default)
+ * and will export ALL bytes in the program or selection (even if the total length
+ * is not a multiple of 16.
*/
public IntelHexExporter() {
this("Intel Hex", "hex", new HelpLocation("ExporterPlugin", "intel_hex"));
}
-
+
+ /**
+ * Constructs a new Intel Hex exporter with a custom record size.
+ *
+ * @param recordSize the record size to use when writing to the output file
+ * @param dropBytes if true, bytes at the end of the file that don't match the specified
+ * record size will be dropped
+ */
+ public IntelHexExporter(int recordSize, boolean dropBytes) {
+ this("Intel Hex", "hex", new HelpLocation("ExporterPlugin", "intel_hex"));
+ recordSizeOption = new RecordSizeOption("Record Size", Integer.class);
+ recordSizeOption.setRecordSize(recordSize);
+ recordSizeOption.setDropBytes(dropBytes);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param name the name of the exporter
+ * @param extension the extension to use for the output file
+ * @param help location of Ghidra help
+ */
protected IntelHexExporter(String name, String extension, HelpLocation help) {
super(name, extension, help);
}
@@ -55,16 +97,49 @@ public class IntelHexExporter extends Exporter {
}
Program program = (Program) domainObject;
- option = new Option("Address Space", program.getAddressFactory().getDefaultAddressSpace());
+ addressSpaceOption =
+ new Option("Address Space", program.getAddressFactory().getDefaultAddressSpace());
+
+ if (recordSizeOption == null) {
+ recordSizeOption = new RecordSizeOption("Record Size", Integer.class);
+ }
+
+ optionsList.add(addressSpaceOption);
+ optionsList.add(recordSizeOption);
- optionsList.add(option);
return optionsList;
}
@Override
public void setOptions(List options) throws OptionException {
if (!options.isEmpty()) {
- option = options.get(0);
+ addressSpaceOption = options.get(0);
+ recordSizeOption = (RecordSizeOption) options.get(1);
+ }
+ }
+
+ /**
+ * Verifier for a {@link HintTextField} that ensures input is a numeric value between
+ * 0 and 0xFF.
+ *
+ * Input may be specified in either decimal or hex.
+ */
+ private class BoundedIntegerVerifier extends InputVerifier {
+
+ @Override
+ public boolean verify(JComponent input) {
+ HintTextField field = (HintTextField) input;
+ String text = field.getText();
+
+ int val;
+ try {
+ val = Integer.decode(text);
+ }
+ catch (NumberFormatException e) {
+ return false;
+ }
+
+ return val <= 0xFF && val >= 0;
}
}
@@ -84,33 +159,31 @@ public class IntelHexExporter extends Exporter {
return false;
}
- if (option == null) {
+ if (addressSpaceOption == null || recordSizeOption == null) {
getOptions(() -> program);
}
- PrintWriter writer = new PrintWriter(new FileOutputStream(file));
+ try (PrintWriter writer = new PrintWriter(new FileOutputStream(file))) {
- Memory memory = program.getMemory();
+ Memory memory = program.getMemory();
- if (addrSet == null) {
- addrSet = memory;
- }
-
- try {
- List records = dumpMemory(program, memory, addrSet, monitor);
- for (IntelHexRecord record : records) {
- writer.println(record.format());
+ if (addrSet == null) {
+ addrSet = memory;
}
- }
- catch (MemoryAccessException e) {
- throw new ExporterException(e);
- }
- finally {
- // Close the PrintWriter
- //
- writer.close();
- option = null;
+ try {
+ List records = dumpMemory(program, memory, addrSet, monitor);
+ for (IntelHexRecord record : records) {
+ writer.println(record.format());
+ }
+ }
+ catch (MemoryAccessException e) {
+ throw new ExporterException(e);
+ }
+ finally {
+ addressSpaceOption = null;
+ recordSizeOption = null;
+ }
}
return true;
@@ -118,15 +191,19 @@ public class IntelHexExporter extends Exporter {
protected List dumpMemory(Program program, Memory memory,
AddressSetView addrSetView, TaskMonitor monitor) throws MemoryAccessException {
- IntelHexRecordWriter writer = new IntelHexRecordWriter(MAX_BYTES_PER_LINE);
+
+ int size = (int) recordSizeOption.getValue();
+ boolean dropBytes = recordSizeOption.dropExtraBytes();
+
+ IntelHexRecordWriter writer = new IntelHexRecordWriter(size, dropBytes);
AddressSet set = new AddressSet(addrSetView);
MemoryBlock[] blocks = memory.getBlocks();
- for (int i = 0; i < blocks.length; ++i) {
- if (!blocks[i].isInitialized() ||
- blocks[i].getStart().getAddressSpace() != option.getValue()) {
- set.delete(new AddressRangeImpl(blocks[i].getStart(), blocks[i].getEnd()));
+ for (MemoryBlock block : blocks) {
+ if (!block.isInitialized() ||
+ block.getStart().getAddressSpace() != addressSpaceOption.getValue()) {
+ set.delete(new AddressRangeImpl(block.getStart(), block.getEnd()));
}
}
@@ -148,4 +225,113 @@ public class IntelHexExporter extends Exporter {
}
return writer.finish(entryPoint);
}
+
+ /**
+ * Option for exporting Intel Hex records that allows users to specify a record size for the
+ * output. Users may also optionally select the Drop Extra Bytes option that
+ * will cause only those records that match the maximum size to be output to the file.
+ *
+ * @see RecordSizeComponent
+ */
+ private class RecordSizeOption extends Option {
+
+ private final RecordSizeComponent comp = new RecordSizeComponent(DEFAULT_RECORD_SIZE);
+
+ public RecordSizeOption(String name, Class> valueClass) {
+ super(name, valueClass);
+ }
+
+ public RecordSizeOption(String name, Class> valueClass, Object value, String arg,
+ String group) {
+ super(name, valueClass, value, arg, group);
+ }
+
+ @Override
+ public Component getCustomEditorComponent() {
+ return comp;
+ }
+
+ @Override
+ public Option copy() {
+ return new RecordSizeOption(getName(), getValueClass(), getValue(), getArg(),
+ getGroup());
+ }
+
+ @Override
+ public Object getValue() {
+ return comp.getValue();
+ }
+
+ @Override
+ public Class> getValueClass() {
+ return Integer.class;
+ }
+
+ public boolean dropExtraBytes() {
+ return comp.dropExtraBytes();
+ }
+
+ public void setRecordSize(int recordSize) {
+ comp.setRecordSize(recordSize);
+ }
+
+ public void setDropBytes(boolean dropBytes) {
+ comp.setDropBytes(dropBytes);
+ }
+ }
+
+ /**
+ * Component that displays two widgets for setting export options:
+ *
+ *
+ * input: a {@link HintTextField} for entering numeric digits; these
+ * represent the record size for each line of output
+ * dropCb: a {@link JCheckBox} for specifying a setting that enforces that every line in
+ * the output matches the specified record size
+ *
+ *
+ * Note: If the Drop Extra Bytes option is set, any bytes that are left over
+ * after outputting all lines that match the record size will be omitted from the output.
+ */
+ private class RecordSizeComponent extends JPanel {
+
+ private HintTextField input;
+ private JCheckBox dropCb;
+
+ public RecordSizeComponent(int recordSize) {
+ setLayout(new BorderLayout());
+
+ input = new HintTextField(Integer.toString(recordSize), false, new BoundedIntegerVerifier());
+ dropCb = new JCheckBox("Align To Record Size");
+
+ input.setText(Integer.toString(recordSize));
+
+ add(input, BorderLayout.CENTER);
+ add(dropCb, BorderLayout.EAST);
+ }
+
+ public int getValue() {
+ String val = input.getText();
+ if (!input.isFieldValid()) {
+
+ // If the user clears the input field, revert to the default
+ // record size (16).
+ return DEFAULT_RECORD_SIZE;
+ }
+
+ return Integer.valueOf(val);
+ }
+
+ public boolean dropExtraBytes() {
+ return dropCb.isSelected();
+ }
+
+ public void setRecordSize(int recordSize) {
+ input.setText(Integer.toString(recordSize));
+ }
+
+ public void setDropBytes(boolean dropBytes) {
+ dropCb.setSelected(dropBytes);
+ }
+ }
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/IntelHexRecordWriter.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/IntelHexRecordWriter.java
index 623417a12a..16d21698c1 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/IntelHexRecordWriter.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/IntelHexRecordWriter.java
@@ -20,21 +20,31 @@ import java.util.*;
import ghidra.program.model.address.*;
public class IntelHexRecordWriter {
+
private final int maxBytesPerLine;
+ private final boolean dropExtraBytes;
private Address startAddress = null;
private Long oldSegment = null;
- private ArrayList bytes = new ArrayList();
+ private ArrayList bytes = new ArrayList<>();
private Boolean isSegmented = null;
- private ArrayList results = new ArrayList();
+ private ArrayList results = new ArrayList<>();
private boolean done = false;
- public IntelHexRecordWriter(int maxBytesPerLine) {
+ /**
+ * Constructor
+ *
+ * @param maxBytesPerLine the maximum number of bytes to write per line in the hex output
+ * @param dropExtraBytes if true, only lines matching {@link #maxBytesPerLine} will be output;
+ * remaining bytes will be left out
+ */
+ public IntelHexRecordWriter(int maxBytesPerLine, boolean dropExtraBytes) {
if (maxBytesPerLine > IntelHexRecord.MAX_RECORD_LENGTH) {
throw new IllegalArgumentException("maxBytesPerLine > IntelHexRecord.MAX_RECORD_LENGTH");
}
this.maxBytesPerLine = maxBytesPerLine;
+ this.dropExtraBytes = dropExtraBytes;
}
public void addByte(Address address, byte b) {
@@ -117,6 +127,14 @@ public class IntelHexRecordWriter {
}
public List finish(Address entryPoint) {
+
+ // Before finalizing things, write out any remaining bytes that haven't yet been written, if
+ // the user has specified to do so via the drop extra bytes option (false =
+ // write out everything).
+ if (bytes.size() > 0 && !dropExtraBytes) {
+ emitData();
+ }
+
if (entryPoint != null && isSegmented != null) {
final long offset = entryPoint.getOffset();
byte[] data = new byte[4];
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/FieldHighlightFactory.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/FieldHighlightFactory.java
index c46721d71e..7f340dc38f 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/FieldHighlightFactory.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/FieldHighlightFactory.java
@@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
- * REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +15,7 @@
*/
package ghidra.app.util.viewer.field;
+import docking.widgets.fieldpanel.field.Field;
import docking.widgets.fieldpanel.support.Highlight;
import docking.widgets.fieldpanel.support.HighlightFactory;
import ghidra.app.util.HighlightProvider;
@@ -30,26 +30,22 @@ public class FieldHighlightFactory implements HighlightFactory {
private HighlightProvider provider;
private Class extends FieldFactory> fieldFactoryClass;
private Object obj;
-
+
/**
* Constructs a new FieldHighlightFactory.
* @param provider the HighlightProvider that will actually compute the highlights.
* @param fieldFactoryClass the class of the field factory that generated the field to be rendered.
* @param obj the object that holds the information that will be rendered (usually a code unit)
*/
- public FieldHighlightFactory(HighlightProvider provider, Class extends FieldFactory> fieldFactoryClass, Object obj) {
+ public FieldHighlightFactory(HighlightProvider provider,
+ Class extends FieldFactory> fieldFactoryClass, Object obj) {
this.provider = provider;
this.fieldFactoryClass = fieldFactoryClass;
this.obj = obj;
}
-
- /**
- * Returns the highlights for the given text.
- * @param text the text to be considered for highlighting.
- * @return an array of highlights to be rendered.
- */
- public Highlight[] getHighlights(String text, int cursorTextOffset) {
+
+ @Override
+ public Highlight[] getHighlights(Field field, String text, int cursorTextOffset) {
return provider.getHighlights(text, obj, fieldFactoryClass, cursorTextOffset);
}
-
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/options/OptionsGui.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/options/OptionsGui.java
index 0ef35c6d47..4d58561dec 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/options/OptionsGui.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/options/OptionsGui.java
@@ -51,7 +51,8 @@ public class OptionsGui extends JPanel {
private static final Color DARK_ORANGE = new Color(255, 128, 0);
private static final Color DARK_RED = new Color(130, 0, 75);
private static final Highlight[] NO_HIGHLIGHTS = new Highlight[0];
- private static final HighlightFactory hlFactory = (text, cursorTextOffset) -> NO_HIGHLIGHTS;
+ private static final HighlightFactory hlFactory =
+ (field, text, cursorTextOffset) -> NO_HIGHLIGHTS;
public static final ScreenElement COMMENT_AUTO =
new ScreenElement("Comment, Automatic", Color.LIGHT_GRAY);
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/framework/main/DataTreeDialog.java b/Ghidra/Features/Base/src/main/java/ghidra/framework/main/DataTreeDialog.java
index cee3dd427a..526202aadd 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/framework/main/DataTreeDialog.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/framework/main/DataTreeDialog.java
@@ -26,6 +26,7 @@ import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import docking.*;
+import docking.event.mouse.GMouseListenerAdapter;
import docking.widgets.tree.support.GTreeSelectionEvent;
import docking.widgets.tree.support.GTreeSelectionListener;
import ghidra.framework.main.datatree.ClearCutAction;
@@ -40,7 +41,7 @@ import ghidra.util.layout.PairLayout;
* Dialog to open or save domain data items to a new location or name.
*/
public class DataTreeDialog extends DialogComponentProvider
-implements GTreeSelectionListener, ActionListener {
+ implements GTreeSelectionListener, ActionListener {
/**
* Dialog type for opening domain data files.
@@ -540,10 +541,11 @@ implements GTreeSelectionListener, ActionListener {
protected void addTreeListeners() {
if (type == OPEN) {
- treePanel.addTreeMouseListener(new MouseAdapter() {
+
+ treePanel.addTreeMouseListener(new GMouseListenerAdapter() {
@Override
- public void mousePressed(MouseEvent e) {
- if (e.getClickCount() == 2 && okButton.isEnabled()) {
+ public void doubleClickTriggered(MouseEvent e) {
+ if (okButton.isEnabled()) {
okCallback();
}
}
@@ -671,7 +673,7 @@ implements GTreeSelectionListener, ActionListener {
// populate the combo box
DefaultComboBoxModel model =
- (DefaultComboBoxModel) projectComboBox.getModel();
+ (DefaultComboBoxModel) projectComboBox.getModel();
model.removeAllElements();
Set map = new HashSet<>();
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/framework/main/datatree/GhidraDataFlavorHandlerService.java b/Ghidra/Features/Base/src/main/java/ghidra/framework/main/datatree/GhidraDataFlavorHandlerService.java
index 45967e040a..c17fe17662 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/framework/main/datatree/GhidraDataFlavorHandlerService.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/framework/main/datatree/GhidraDataFlavorHandlerService.java
@@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
- * REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,9 +17,10 @@ package ghidra.framework.main.datatree;
import java.awt.datatransfer.DataFlavor;
-public class GhidraDataFlavorHandlerService extends DataFlavorHandlerService {
- @Override
- protected void doRegisterDataFlavorHandlers() {
+public class GhidraDataFlavorHandlerService {
+
+ public GhidraDataFlavorHandlerService() {
+
try {
DataFlavor linuxFileUrlFlavor =
new DataFlavor("application/x-java-serialized-object;class=java.lang.String");
@@ -31,15 +31,12 @@ public class GhidraDataFlavorHandlerService extends DataFlavorHandlerService {
// should never happen as it is using java.lang.String
}
- final LocalTreeNodeHandler localTreeNodeHandler = new LocalTreeNodeHandler();
+ LocalTreeNodeHandler localNodeHandler = new LocalTreeNodeHandler();
DataTreeDragNDropHandler.addActiveDataFlavorHandler(
- DataTreeDragNDropHandler.localDomainFileTreeFlavor, localTreeNodeHandler);
+ DataTreeDragNDropHandler.localDomainFileTreeFlavor, localNodeHandler);
DataTreeDragNDropHandler.addActiveDataFlavorHandler(DataFlavor.javaFileListFlavor,
new JavaFileListHandler());
DataTreeDragNDropHandler.addActiveDataFlavorHandler(
VersionInfoTransferable.localVersionInfoFlavor, new LocalVersionInfoHandler());
-
- DataTreeDragNDropHandler.addInactiveDataFlavorHandler(
- DataTreeDragNDropHandler.localDomainFileTreeFlavor, localTreeNodeHandler);
}
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/framework/main/datatree/JavaFileListHandler.java b/Ghidra/Features/Base/src/main/java/ghidra/framework/main/datatree/JavaFileListHandler.java
index 69c8bb74a5..cf3c03d8a8 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/framework/main/datatree/JavaFileListHandler.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/framework/main/datatree/JavaFileListHandler.java
@@ -19,13 +19,15 @@
package ghidra.framework.main.datatree;
import java.awt.datatransfer.DataFlavor;
+import java.awt.dnd.DropTargetDropEvent;
import java.io.File;
import java.util.List;
import docking.widgets.tree.GTreeNode;
import ghidra.app.services.FileImporterService;
-import ghidra.framework.main.FrontEndTool;
+import ghidra.app.util.FileOpenDataFlavorHandler;
import ghidra.framework.model.DomainFolder;
+import ghidra.framework.plugintool.PluginTool;
import ghidra.util.Msg;
import util.CollectionUtils;
@@ -33,24 +35,43 @@ import util.CollectionUtils;
* A drag-and-drop handler for trees that is specific to List<File>. (see
* {@link DataFlavor#javaFileListFlavor}).
*/
-final class JavaFileListHandler implements DataFlavorHandler {
- @Override
- public void handle(FrontEndTool tool, DataTree dataTree, GTreeNode destinationNode,
- Object transferData, int dropAction) {
- DomainFolder folder = getDomainFolder(destinationNode);
+public final class JavaFileListHandler implements DataTreeFlavorHandler, FileOpenDataFlavorHandler {
- FileImporterService im = tool.getService(FileImporterService.class);
- if (im == null) {
- Msg.showError(this, dataTree, "Could Not Import", "Could not find importer service");
+ @Override
+ public void handle(PluginTool tool, Object transferData, DropTargetDropEvent e, DataFlavor f) {
+
+ FileImporterService importer = tool.getService(FileImporterService.class);
+ if (importer == null) {
+ Msg.showError(this, null, "Could Not Import", "Could not find Importer Service");
return;
}
- List fileList = CollectionUtils.asList((List>) transferData, File.class);
+ DomainFolder folder = tool.getProject().getProjectData().getRootFolder();
+ doImport(importer, folder, transferData);
+ }
+
+ @Override
+ public void handle(PluginTool tool, DataTree dataTree, GTreeNode destinationNode,
+ Object transferData, int dropAction) {
+
+ FileImporterService importer = tool.getService(FileImporterService.class);
+ if (importer == null) {
+ Msg.showError(this, dataTree, "Could Not Import", "Could not find Importer Service");
+ return;
+ }
+
+ DomainFolder folder = getDomainFolder(destinationNode);
+ doImport(importer, folder, transferData);
+ }
+
+ private void doImport(FileImporterService importer, DomainFolder folder, Object files) {
+
+ List fileList = CollectionUtils.asList((List>) files, File.class);
if (fileList.size() == 1 && fileList.get(0).isFile()) {
- im.importFile(folder, fileList.get(0));
+ importer.importFile(folder, fileList.get(0));
}
else {
- im.importFiles(folder, fileList);
+ importer.importFiles(folder, fileList);
}
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/framework/main/datatree/LinuxFileUrlHandler.java b/Ghidra/Features/Base/src/main/java/ghidra/framework/main/datatree/LinuxFileUrlHandler.java
index 9c6f1c115b..16a7e690ef 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/framework/main/datatree/LinuxFileUrlHandler.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/framework/main/datatree/LinuxFileUrlHandler.java
@@ -27,7 +27,6 @@ import java.util.function.Function;
import docking.widgets.tree.GTreeNode;
import ghidra.app.services.FileImporterService;
import ghidra.app.util.FileOpenDataFlavorHandler;
-import ghidra.framework.main.FrontEndTool;
import ghidra.framework.model.DomainFolder;
import ghidra.framework.plugintool.PluginTool;
import ghidra.framework.plugintool.ServiceProvider;
@@ -38,11 +37,11 @@ import ghidra.util.Msg;
* duty in that it opens files for DataTrees and for Tools (signaled via the interfaces it
* implements).
*/
-public final class LinuxFileUrlHandler implements DataFlavorHandler, FileOpenDataFlavorHandler {
+public final class LinuxFileUrlHandler implements DataTreeFlavorHandler, FileOpenDataFlavorHandler {
@Override
// This is for the DataFlavorHandler interface for handling node drops in DataTrees
- public void handle(FrontEndTool tool, DataTree dataTree, GTreeNode destinationNode,
+ public void handle(PluginTool tool, DataTree dataTree, GTreeNode destinationNode,
Object transferData, int dropAction) {
DomainFolder folder = getDomainFolder(destinationNode);
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/program/util/DiffUtility.java b/Ghidra/Features/Base/src/main/java/ghidra/program/util/DiffUtility.java
index 7b4d9cbf4d..8d8c87e32a 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/program/util/DiffUtility.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/program/util/DiffUtility.java
@@ -193,11 +193,11 @@ public class DiffUtility extends SimpleDiffUtility {
return otherProgram.getSymbolTable().createExternalLibrary(namespace.getName(), source);
}
else if (namespace instanceof GhidraClass) {
- return otherProgram.getSymbolTable().createClass(otherParentNamespace,
- namespace.getName(), source);
+ return otherProgram.getSymbolTable()
+ .createClass(otherParentNamespace, namespace.getName(), source);
}
- return otherProgram.getSymbolTable().createNameSpace(otherParentNamespace,
- namespace.getName(), source);
+ return otherProgram.getSymbolTable()
+ .createNameSpace(otherParentNamespace, namespace.getName(), source);
}
// /**
@@ -329,11 +329,11 @@ public class DiffUtility extends SimpleDiffUtility {
if (toAddr == null) {
return null;
}
- return otherProgram.getReferenceManager().getReference(fromAddr, toAddr,
- ref.getOperandIndex());
+ return otherProgram.getReferenceManager()
+ .getReference(fromAddr, toAddr, ref.getOperandIndex());
}
- Reference otherRef = otherProgram.getReferenceManager().getPrimaryReferenceFrom(fromAddr,
- ref.getOperandIndex());
+ Reference otherRef = otherProgram.getReferenceManager()
+ .getPrimaryReferenceFrom(fromAddr, ref.getOperandIndex());
if (otherRef != null && ref.getToAddress().hasSameAddressSpace(otherRef.getToAddress())) {
return otherRef;
}
@@ -357,11 +357,11 @@ public class DiffUtility extends SimpleDiffUtility {
if (toAddr1 == null) {
return null;
}
- return program.getReferenceManager().getReference(fromAddr1, toAddr1,
- p2Ref.getOperandIndex());
+ return program.getReferenceManager()
+ .getReference(fromAddr1, toAddr1, p2Ref.getOperandIndex());
}
- Reference p1Ref = program.getReferenceManager().getPrimaryReferenceFrom(fromAddr1,
- p2Ref.getOperandIndex());
+ Reference p1Ref = program.getReferenceManager()
+ .getPrimaryReferenceFrom(fromAddr1, p2Ref.getOperandIndex());
if (p1Ref != null && p1Ref.getToAddress().hasSameAddressSpace(p2Ref.getToAddress())) {
return p1Ref;
}
@@ -385,8 +385,9 @@ public class DiffUtility extends SimpleDiffUtility {
otherAddr = getCompatibleAddress(program, addr, otherProgram);
}
// FIXME Should this be passing the Namespace?
- return otherProgram.getExternalManager().addExtLocation(extLoc.getLibraryName(),
- extLoc.getLabel(), otherAddr, extLoc.getSource());
+ return otherProgram.getExternalManager()
+ .addExtLocation(extLoc.getLibraryName(), extLoc.getLabel(), otherAddr,
+ extLoc.getSource());
}
/**
@@ -707,6 +708,9 @@ public class DiffUtility extends SimpleDiffUtility {
Address refAddress = getCompatibleAddress(program, location.refAddr, otherProgram);
if (address != null) {
+ if (byteAddress == null) {
+ byteAddress = address; // Make sure the byte address isn't null.
+ }
ProgramLocation otherLocation = new ProgramLocation(otherProgram, address, byteAddress,
location.getComponentPath(), refAddress, 0, 0, 0);
return otherLocation;
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramDiffDetails.java b/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramDiffDetails.java
index d0cb2dfefd..751d08d165 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramDiffDetails.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/program/util/ProgramDiffDetails.java
@@ -2555,7 +2555,7 @@ public class ProgramDiffDetails {
}
private void addColorAddress(StyledDocument doc, Address addr) {
- String text = addr.toString();
+ String text = (addr != null) ? addr.toString() : "no matching address";
color(ADDRESS_COLOR);
try {
doc.insertString(doc.getLength(), text, textAttrSet);
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/program/util/SymbolicPropogator.java b/Ghidra/Features/Base/src/main/java/ghidra/program/util/SymbolicPropogator.java
index 5486eb65ac..11b468a459 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/program/util/SymbolicPropogator.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/program/util/SymbolicPropogator.java
@@ -43,7 +43,7 @@ public class SymbolicPropogator {
// 1. How are "register-relative" varnodes distinguished based upon target space ? Not sure how we handle wrapping/truncation concerns.
// 1) The offset is the only thing that could be used as a reference.
- private static final int _POINTER_MIN_BOUNDS = 0x7fff;
+ private static final int _POINTER_MIN_BOUNDS = 0x100;
// mask for sub-piece extraction
private static long[] maskSize = { 0xffL, 0xffL, 0xffffL, 0xffffffL, 0xffffffffL, 0xffffffffffL,
@@ -1836,7 +1836,7 @@ public class SymbolicPropogator {
// see if the offset is a large constant offset from the symbolic space
long offset = refLocation.getOffset();
- if (checkPossibleOffsetAddr(offset)) {
+ if (evaluator != null) {
// symbolic spaces will have the name of the symbolic space be the register space
// String spaceName = refLocation.getAddress().getAddressSpace().getName();
// Register register = vContext.getRegister(spaceName);
@@ -1850,7 +1850,7 @@ public class SymbolicPropogator {
// }
// } else
- if (evaluator == null) {
+ if (!vContext.isStackSymbolicSpace(refLocation) && evaluator != null) {
Address constant = program.getAddressFactory().getAddress(
(int) targetSpaceID.getOffset(), offset);
Address newTarget = evaluator.evaluateConstant(vContext, instruction,
@@ -2051,7 +2051,7 @@ public class SymbolicPropogator {
*/
private int getReferenceSpaceID(Instruction instruction, long offset) {
// TODO: this should be passed to the client callback to make the decision
- if (offset <= 4096 && offset >= -1) {
+ if (offset <= 4 && offset >= -1) {
return -1; // don't make speculative reference to certain offset values
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/program/util/VarnodeContext.java b/Ghidra/Features/Base/src/main/java/ghidra/program/util/VarnodeContext.java
index 6266f9d77c..8be976f8d9 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/program/util/VarnodeContext.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/program/util/VarnodeContext.java
@@ -312,7 +312,7 @@ public class VarnodeContext implements ProcessorContext {
/**
* Return true if this varnode is stored in the symbolic stack space
*/
- private boolean isStackSymbolicSpace(Varnode varnode) {
+ public boolean isStackSymbolicSpace(Varnode varnode) {
// symbolic spaces are off of a register, find the space
AddressSpace regSpace = addrFactory.getAddressSpace(varnode.getSpace());
@@ -785,7 +785,9 @@ public class VarnodeContext implements ProcessorContext {
* return the location that this register was last set
* This is a transient thing, so it should only be used as a particular flow is being processed...
*
- * @param reg
+ * @param reg register to find last set location
+ * @param bval value to look for to differentiate set locations, null if don't care
+ *
* @return address that the register was set.
*/
public Address getLastSetLocation(Register reg, BigInteger bval) {
@@ -1256,6 +1258,13 @@ public class VarnodeContext implements ProcessorContext {
// too big anyway,already extended as far as it will go.
vnodeVal = createConstantVarnode(vnodeVal.getOffset(), out.getSize());
}
+ } else if (vnodeVal.isRegister() && vnodeVal.getSize() < out.getSize()) {
+ Register reg = getRegister(vnodeVal);
+ if (reg == null) {
+ throw notFoundExc;
+ }
+ int spaceID = getAddressSpace(reg.getName());
+ vnodeVal = createVarnode(0,spaceID,out.getSize());
}
return vnodeVal;
}
diff --git a/Ghidra/Features/Base/src/test/java/ghidra/framework/options/OptionsTest.java b/Ghidra/Features/Base/src/test/java/ghidra/framework/options/OptionsTest.java
index 6e468ee1e2..792f46f2c9 100644
--- a/Ghidra/Features/Base/src/test/java/ghidra/framework/options/OptionsTest.java
+++ b/Ghidra/Features/Base/src/test/java/ghidra/framework/options/OptionsTest.java
@@ -623,7 +623,7 @@ public class OptionsTest extends AbstractGenericTest {
@Override
public int hashCode() {
- return 1;// set so that this listener gets called after the storingOptionsListnere
+ return 1;// set so that this listener gets called after the storingOptionsListener
}
}
diff --git a/Ghidra/Features/ByteViewer/src/main/java/ghidra/app/plugin/core/byteviewer/ByteField.java b/Ghidra/Features/ByteViewer/src/main/java/ghidra/app/plugin/core/byteviewer/ByteField.java
index b2e3dbd969..db7371f355 100644
--- a/Ghidra/Features/ByteViewer/src/main/java/ghidra/app/plugin/core/byteviewer/ByteField.java
+++ b/Ghidra/Features/ByteViewer/src/main/java/ghidra/app/plugin/core/byteviewer/ByteField.java
@@ -15,8 +15,6 @@
*/
package ghidra.app.plugin.core.byteviewer;
-import ghidra.util.ColorUtils;
-
import java.awt.*;
import java.math.BigInteger;
@@ -28,6 +26,7 @@ import docking.widgets.fieldpanel.internal.FieldBackgroundColorManager;
import docking.widgets.fieldpanel.internal.PaintContext;
import docking.widgets.fieldpanel.support.HighlightFactory;
import docking.widgets.fieldpanel.support.RowColLocation;
+import ghidra.util.ColorUtils;
/**
* Fields for the ByteViewer. This class extends the SimpleTextField to include
@@ -52,7 +51,8 @@ public class ByteField extends SimpleTextField {
* @param hlFactory the factory used to create highlights
*/
public ByteField(String text, FontMetrics fontMetrics, int startX, int width,
- boolean allowCursorAtEnd, int fieldOffset, BigInteger index, HighlightFactory hlFactory) {
+ boolean allowCursorAtEnd, int fieldOffset, BigInteger index,
+ HighlightFactory hlFactory) {
super(text, fontMetrics, startX, width, allowCursorAtEnd, hlFactory);
this.fieldOffset = fieldOffset;
@@ -64,7 +64,7 @@ public class ByteField extends SimpleTextField {
public void paint(JComponent c, Graphics g, PaintContext context,
FieldBackgroundColorManager colorManager, RowColLocation cursorLoc, int rowHeight) {
paintSelection(g, colorManager, 0);
- paintHighlights(g, hlFactory.getHighlights(text, -1));
+ paintHighlights(g, hlFactory.getHighlights(this, text, -1));
g.setFont(metrics.getFont());
if (foregroundColor == null) {
foregroundColor = context.getForeground();
diff --git a/Ghidra/Features/ByteViewer/src/main/java/ghidra/app/plugin/core/byteviewer/FieldFactory.java b/Ghidra/Features/ByteViewer/src/main/java/ghidra/app/plugin/core/byteviewer/FieldFactory.java
index b821e8b3c9..81ed547bfb 100644
--- a/Ghidra/Features/ByteViewer/src/main/java/ghidra/app/plugin/core/byteviewer/FieldFactory.java
+++ b/Ghidra/Features/ByteViewer/src/main/java/ghidra/app/plugin/core/byteviewer/FieldFactory.java
@@ -213,7 +213,7 @@ class FieldFactory {
}
@Override
- public Highlight[] getHighlights(String text, int cursorTextOffset) {
+ public Highlight[] getHighlights(Field field, String text, int cursorTextOffset) {
return provider.getHighlights(text, null, null, -1);
}
}
diff --git a/Ghidra/Features/ByteViewer/src/main/java/ghidra/app/plugin/core/byteviewer/IndexFieldFactory.java b/Ghidra/Features/ByteViewer/src/main/java/ghidra/app/plugin/core/byteviewer/IndexFieldFactory.java
index bd828d425e..cb7ae28d6c 100644
--- a/Ghidra/Features/ByteViewer/src/main/java/ghidra/app/plugin/core/byteviewer/IndexFieldFactory.java
+++ b/Ghidra/Features/ByteViewer/src/main/java/ghidra/app/plugin/core/byteviewer/IndexFieldFactory.java
@@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
- * REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,8 +15,6 @@
*/
package ghidra.app.plugin.core.byteviewer;
-import ghidra.app.plugin.core.format.ByteBlockInfo;
-
import java.awt.Color;
import java.awt.FontMetrics;
import java.math.BigInteger;
@@ -26,6 +23,7 @@ import docking.widgets.fieldpanel.field.Field;
import docking.widgets.fieldpanel.field.SimpleTextField;
import docking.widgets.fieldpanel.support.Highlight;
import docking.widgets.fieldpanel.support.HighlightFactory;
+import ghidra.app.plugin.core.format.ByteBlockInfo;
/**
* Implementation for the index/address field.
@@ -145,7 +143,7 @@ class IndexFieldFactory {
}
@Override
- public Highlight[] getHighlights(String text, int cursorTextOffset) {
+ public Highlight[] getHighlights(Field field, String text, int cursorTextOffset) {
return NO_HIGHLIGHTS;
}
}
diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc
index af1165c37b..e4326eaffd 100644
--- a/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc
+++ b/Ghidra/Features/Decompiler/src/decompile/cpp/ruleaction.cc
@@ -7333,8 +7333,12 @@ bool RuleConditionalMove::BoolExpress::evaluatePropagation(FlowBlock *root,FlowB
if (root == branch) return true; // Can always propagate if there is no branch
if (op->getParent() != branch) return true; // Can propagate if value formed before branch
mustreconstruct = true; // Final op is performed in branch, so it must be reconstructed
+ if (in0->isFree() && !in0->isConstant()) return false;
if (in0->isWritten() && (in0->getDef()->getParent()==branch)) return false;
- if ((optype==2) && in1->isWritten() && (in1->getDef()->getParent()==branch)) return false;
+ if (optype == 2) {
+ if (in1->isFree() && !in1->isConstant()) return false;
+ if (in1->isWritten() && (in1->getDef()->getParent()==branch)) return false;
+ }
return true;
}
diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/ClangTextField.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/ClangTextField.java
index 46020f53ca..4968cf02c6 100644
--- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/ClangTextField.java
+++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/ClangTextField.java
@@ -1,5 +1,6 @@
/* ###
* IP: GHIDRA
+ * REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -197,4 +198,8 @@ public class ClangTextField extends WrappingVerticalLayoutTextField {
return lineNumberFieldElement.getStringWidth();
}
+ public int getLineNumber() {
+ String text = lineNumberFieldElement.getText().trim();
+ return Integer.parseInt(text);
+ }
}
diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/DecompilerHoverProvider.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/DecompilerHoverProvider.java
index 0f54d60bcb..63f1cc7c67 100644
--- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/DecompilerHoverProvider.java
+++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/DecompilerHoverProvider.java
@@ -76,8 +76,9 @@ public class DecompilerHoverProvider extends AbstractHoverProvider {
Varnode vn = token.getVarnode();
if (vn != null) {
- if (vn.getHigh() instanceof HighGlobal) {
- reference = vn.getAddress();
+ HighVariable highVar = vn.getHigh();
+ if (highVar instanceof HighGlobal) {
+ reference = highVar.getRepresentative().getAddress();
}
}
diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/DecompilerManager.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/DecompilerManager.java
index 617215edb3..f56bba85a7 100644
--- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/DecompilerManager.java
+++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/DecompilerManager.java
@@ -51,7 +51,7 @@ public class DecompilerManager {
this.decompilerController = decompilerController;
runManager = new RunManager("Decompiler", null);
- decompiler = new Decompiler(options, options.getDefaultTimeout());
+ decompiler = new Decompiler(options, 0);
updateManager = new SwingUpdateManager(500, () -> doPendingDecompile());
}
diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/DecompilerPanel.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/DecompilerPanel.java
index aed2123de5..0a06f0f9d9 100644
--- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/DecompilerPanel.java
+++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/component/DecompilerPanel.java
@@ -37,11 +37,11 @@ import docking.widgets.indexedscrollpane.IndexedScrollPane;
import ghidra.app.decompiler.*;
import ghidra.app.decompiler.component.hover.DecompilerHoverService;
import ghidra.app.plugin.core.decompile.DecompileClipboardProvider;
+import ghidra.app.plugin.core.decompile.actions.FieldBasedSearchLocation;
import ghidra.program.model.address.*;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Program;
-import ghidra.program.model.pcode.PcodeOp;
-import ghidra.program.model.pcode.Varnode;
+import ghidra.program.model.pcode.*;
import ghidra.program.util.ProgramLocation;
import ghidra.program.util.ProgramSelection;
import ghidra.util.*;
@@ -175,6 +175,9 @@ public class DecompilerPanel extends JPanel implements FieldMouseListener, Field
if (clipboard != null) {
clipboard.selectionChanged(null);
}
+
+ // don't highlight search results across functions
+ currentSearchLocation = null;
}
private void setLocation(DecompileData oldData, DecompileData newData) {
@@ -419,6 +422,10 @@ public class DecompilerPanel extends JPanel implements FieldMouseListener, Field
}
}
+ HighVariable highVar = vn.getHigh();
+ if (highVar instanceof HighGlobal) {
+ vn = highVar.getRepresentative();
+ }
if (vn.isAddress()) {
Address addr = vn.getAddress();
if (addr.isMemoryAddress()) {
@@ -696,9 +703,21 @@ public class DecompilerPanel extends JPanel implements FieldMouseListener, Field
}
class SearchHighlightFactory implements HighlightFactory {
+
@Override
- public Highlight[] getHighlights(String text, int cursorTextOffset) {
- if (currentSearchLocation == null || cursorTextOffset == -1) {
+ public Highlight[] getHighlights(Field field, String text, int cursorTextOffset) {
+ if (currentSearchLocation == null) {
+ return new Highlight[0];
+ }
+
+ ClangTextField cField = (ClangTextField) field;
+ int highlightLine = cField.getLineNumber();
+
+ FieldLocation searchCursorLocation =
+ ((FieldBasedSearchLocation) currentSearchLocation).getFieldLocation();
+ int searchLineNumber = searchCursorLocation.getIndex().intValue() + 1;
+ if (highlightLine != searchLineNumber) {
+ // only highlight the match on the actual line
return new Highlight[0];
}
diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/FieldBasedSearchLocation.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/FieldBasedSearchLocation.java
index 0d1434155c..191c32cc21 100644
--- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/FieldBasedSearchLocation.java
+++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/FieldBasedSearchLocation.java
@@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
- * REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,4 +38,9 @@ public class FieldBasedSearchLocation extends SearchLocation {
public CursorPosition getCursorPosition() {
return new DecompilerCursorPosition(fieldLocation);
}
+
+ @Override
+ protected String fieldsToString() {
+ return super.fieldsToString() + ", fieldLocation=" + fieldLocation;
+ }
}
diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/FindAction.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/FindAction.java
index 78c48a7cf4..70b23623e0 100644
--- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/FindAction.java
+++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/FindAction.java
@@ -1,5 +1,6 @@
/* ###
* IP: GHIDRA
+ * REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -77,13 +78,20 @@ public class FindAction extends DockingAction {
if (text != null) {
dialog.setSearchText(text);
}
+
// show over the root frame, so the user can still see the Decompiler window
tool.showDialog(dialog);
}
protected FindDialog getFindDialog() {
if (findDialog == null) {
- findDialog = new FindDialog("Decompiler Find Text", new DecompilerSearcher());
+ findDialog = new FindDialog("Decompiler Find Text", new DecompilerSearcher()) {
+ @Override
+ protected void dialogClosed() {
+ // clear the search results when the dialog is closed
+ decompilerPanel.setSearchResults(null);
+ }
+ };
findDialog.setHelpLocation(new HelpLocation("DecompilePlugin", "Find"));
}
return findDialog;
diff --git a/Ghidra/Features/ProgramDiff/src/main/java/ghidra/app/plugin/core/diff/ProgramDiffPlugin.java b/Ghidra/Features/ProgramDiff/src/main/java/ghidra/app/plugin/core/diff/ProgramDiffPlugin.java
index 9240662b1a..04183ab7cd 100644
--- a/Ghidra/Features/ProgramDiff/src/main/java/ghidra/app/plugin/core/diff/ProgramDiffPlugin.java
+++ b/Ghidra/Features/ProgramDiff/src/main/java/ghidra/app/plugin/core/diff/ProgramDiffPlugin.java
@@ -441,6 +441,9 @@ public class ProgramDiffPlugin extends ProgramPlugin
Address primaryByteAddr = SimpleDiffUtility.getCompatibleAddress(secondaryDiffProgram,
byteAddr, primaryProgram);
+ if (primaryByteAddr == null) {
+ primaryByteAddr = primaryAddr; // Make sure the byte address isn't null.
+ }
Address primaryRefAddr = SimpleDiffUtility.getCompatibleAddress(secondaryDiffProgram,
refAddr, primaryProgram);
ProgramLocation newP1Location = new ProgramLocation(primaryProgram, primaryAddr,
@@ -463,7 +466,9 @@ public class ProgramDiffPlugin extends ProgramPlugin
}
ProgramLocation previousP1LocationAsP2 = DiffUtility
.getCompatibleProgramLocation(primaryProgram, location, secondaryDiffProgram);
- diffListingPanel.setCursorPosition(previousP1LocationAsP2);
+ if (previousP1LocationAsP2 != null) {
+ diffListingPanel.setCursorPosition(previousP1LocationAsP2);
+ }
if (diffDetailsProvider != null && diffDetails != null) {
diffDetailsProvider.locationChanged(previousP1Location);
}
@@ -749,7 +754,7 @@ public class ProgramDiffPlugin extends ProgramPlugin
runSwing(() -> {
MarkerSet selectionMarkers = getSelectionMarkers();
selectionMarkers.clearAll();
- selectionMarkers.add(p2SelectionAsP1);
+ selectionMarkers.add(p2Selection);
});
diffListingPanel.setSelection(p2SelectionAsP1);
@@ -798,9 +803,9 @@ public class ProgramDiffPlugin extends ProgramPlugin
// Limit the apply to the selection in the view.
AddressSet p2SelectionAsP1 =
DiffUtility.getCompatibleAddressSet(p2Selection, primaryProgram);
- AddressSet p1ApplySet =
- p2SelectionAsP1.intersect(p1ViewAddrSet).subtract(addressesOnlyInP1).subtract(
- compatibleOnlyInP2);
+ AddressSet p1ApplySet = p2SelectionAsP1.intersect(p1ViewAddrSet)
+ .subtract(addressesOnlyInP1)
+ .subtract(compatibleOnlyInP2);
if (p1ApplySet.isEmpty()) {
Msg.showInfo(getClass(), tool.getToolFrame(), "Apply Differences",
(p2Selection.isEmpty()) ? "No diff selection in the current view."
@@ -860,7 +865,7 @@ public class ProgramDiffPlugin extends ProgramPlugin
// Right side markers need p1 addresses since they use p1 indexMap.
MarkerSet diffMarkers = getDiffMarkers(); // Get right side markers for program 2.
diffMarkers.clearAll();
- diffMarkers.add(p2DiffSetAsP1);
+ diffMarkers.add(p2DiffSet);
MarkerSet codeViewerDiffMarkers = getCodeViewerMarkers(); // Get left side markers for program 1.
codeViewerDiffMarkers.clearAll();
@@ -884,7 +889,7 @@ public class ProgramDiffPlugin extends ProgramPlugin
AddressSet p1DiffHighlightSet =
DiffUtility.getCompatibleAddressSet(p2Highlight, primaryProgram);
p2DiffHighlight = p2Highlight;
- diffMarkers.add(p1DiffHighlightSet);
+ diffMarkers.add(p2Highlight);
codeViewerDiffMarkers.add(p1DiffHighlightSet);
}
@@ -1603,7 +1608,14 @@ public class ProgramDiffPlugin extends ProgramPlugin
diffListingPanel.goTo(currentLocation);
MarkerSet cursorMarkers = getCursorMarkers();
- cursorMarkers.setAddressSet(new AddressSet(currentLocation.getAddress()));
+ Address currentP2Address = currentLocation.getAddress();
+ if (currentLocation.getProgram() != secondaryDiffProgram) { // Make sure address is from P2.
+ currentP2Address = SimpleDiffUtility.getCompatibleAddress(currentLocation.getProgram(),
+ currentLocation.getAddress(), secondaryDiffProgram);
+ }
+ if (currentP2Address != null) {
+ cursorMarkers.setAddressSet(new AddressSet(currentP2Address));
+ }
updatePgm2Enablement();
diff --git a/Ghidra/Framework/Docking/src/main/java/docking/ActionContext.java b/Ghidra/Framework/Docking/src/main/java/docking/ActionContext.java
index 3fed77d232..f9d950e63e 100644
--- a/Ghidra/Framework/Docking/src/main/java/docking/ActionContext.java
+++ b/Ghidra/Framework/Docking/src/main/java/docking/ActionContext.java
@@ -47,7 +47,12 @@ public class ActionContext {
}
/**
- * For Testing
+ * Constructor
+ *
+ * @param provider the ComponentProvider that generated this context.
+ * @param contextObject an optional contextObject that the ComponentProvider can provide
+ * @param sourceObject an optional source object; this can be anything that actions wish to
+ * later retrieve
*/
public ActionContext(ComponentProvider provider, Object contextObject, Object sourceObject) {
this(provider, contextObject);
@@ -55,8 +60,8 @@ public class ActionContext {
}
/**
- * Returns the {@link #ComponentProvider} that generated this ActionContext
- * @return
+ * Returns the {@link ComponentProvider} that generated this ActionContext
+ * @return the provider
*/
public ComponentProvider getComponentProvider() {
return provider;
diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/SearchLocation.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/SearchLocation.java
index 9dd7087fe0..064f241389 100644
--- a/Ghidra/Framework/Docking/src/main/java/docking/widgets/SearchLocation.java
+++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/SearchLocation.java
@@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
- * REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -60,6 +59,10 @@ public class SearchLocation {
@Override
public String toString() {
- return searchText + "[start=" + startIndexInclusive + ", end=" + endIndexInclusive + "]";
+ return searchText + "[" + fieldsToString() + "]";
+ }
+
+ protected String fieldsToString() {
+ return startIndexInclusive + ", end=" + endIndexInclusive;
}
}
diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/dialogs/ObjectChooserDialog.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/dialogs/ObjectChooserDialog.java
index 0aa754119b..7c9da99b61 100644
--- a/Ghidra/Framework/Docking/src/main/java/docking/widgets/dialogs/ObjectChooserDialog.java
+++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/dialogs/ObjectChooserDialog.java
@@ -63,7 +63,7 @@ public class ObjectChooserDialog extends DialogComponentProvider {
table.addSelectionListener(t -> objectSelected(t));
- table.setItemPickListner(t -> objectPicked(t));
+ table.setItemPickListener(t -> objectPicked(t));
return table;
}
diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/field/ClippingTextField.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/field/ClippingTextField.java
index 506e1f8667..bb25ba0477 100644
--- a/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/field/ClippingTextField.java
+++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/field/ClippingTextField.java
@@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
- * REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -129,8 +128,8 @@ public class ClippingTextField implements TextField {
int x = findX(col) + startX;
- return new Rectangle(x, -textElement.getHeightAbove(), 2, textElement.getHeightAbove() +
- textElement.getHeightBelow());
+ return new Rectangle(x, -textElement.getHeightAbove(), 2,
+ textElement.getHeightAbove() + textElement.getHeightBelow());
}
/**
@@ -315,7 +314,7 @@ public class ClippingTextField implements TextField {
if (cursorLoc != null) {
cursorTextOffset = screenLocationToTextOffset(cursorLoc.row(), cursorLoc.col());
}
- paintHighlights(g, hlFactory.getHighlights(getString(), cursorTextOffset));
+ paintHighlights(g, hlFactory.getHighlights(this, getString(), cursorTextOffset));
}
protected void paintSelection(Graphics g, FieldBackgroundColorManager colorManager, int row,
@@ -344,10 +343,10 @@ public class ClippingTextField implements TextField {
}
protected void paintHighlights(Graphics g, Highlight[] highlights) {
- for (int i = 0; i < highlights.length; i++) {
- int startCol = Math.max(highlights[i].getStart(), 0);
- int endCol = Math.min(highlights[i].getEnd(), getString().length());
- Color c = highlights[i].getColor();
+ for (Highlight highlight : highlights) {
+ int startCol = Math.max(highlight.getStart(), 0);
+ int endCol = Math.min(highlight.getEnd(), getString().length());
+ Color c = highlight.getColor();
if (endCol >= startCol) {
int start = findX(startCol);
int end = findX(endCol + 1);
diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/field/ReverseClippingTextField.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/field/ReverseClippingTextField.java
index 3ffa173ccb..bffa921952 100644
--- a/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/field/ReverseClippingTextField.java
+++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/field/ReverseClippingTextField.java
@@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
- * REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -142,8 +141,8 @@ public class ReverseClippingTextField implements TextField {
int x = findX(col) + textStartX;
- return new Rectangle(x, -textElement.getHeightAbove(), 2, textElement.getHeightAbove() +
- textElement.getHeightBelow());
+ return new Rectangle(x, -textElement.getHeightAbove(), 2,
+ textElement.getHeightAbove() + textElement.getHeightBelow());
}
/**
@@ -336,8 +335,7 @@ public class ReverseClippingTextField implements TextField {
private void paintDots(Graphics g, int x) {
int pos = 1; // skip one pixel
for (int i = 0; i < 3; i++) {
- if (pos < DOT_DOT_DOT_WIDTH - 2) { // don't paint too close to next
- // field.
+ if (pos < DOT_DOT_DOT_WIDTH - 2) { // don't paint too close to next field
g.drawRect(x + pos, -2, 1, 1);
pos += 4; // add in size of dot and padding
}
@@ -349,14 +347,14 @@ public class ReverseClippingTextField implements TextField {
if (cursorLoc != null) {
cursorTextOffset = screenLocationToTextOffset(cursorLoc.row(), cursorLoc.col());
}
- paintHighlights(g, hlFactory.getHighlights(getString(), cursorTextOffset));
+ paintHighlights(g, hlFactory.getHighlights(this, getString(), cursorTextOffset));
}
protected void paintHighlights(Graphics g, Highlight[] highlights) {
- for (int i = 0; i < highlights.length; i++) {
- int startCol = Math.max(highlights[i].getStart() - startingCharIndex, 0);
- int endCol = Math.min(highlights[i].getEnd() - startingCharIndex, getString().length());
- Color c = highlights[i].getColor();
+ for (Highlight highlight : highlights) {
+ int startCol = Math.max(highlight.getStart() - startingCharIndex, 0);
+ int endCol = Math.min(highlight.getEnd() - startingCharIndex, getString().length());
+ Color c = highlight.getColor();
if (endCol >= startCol) {
int start = findX(startCol);
int end = findX(endCol + 1);
diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/field/SimpleTextField.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/field/SimpleTextField.java
index a4dbdbbbaf..f75903abb6 100644
--- a/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/field/SimpleTextField.java
+++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/field/SimpleTextField.java
@@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
- * REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -202,7 +201,7 @@ public class SimpleTextField implements Field {
public void paint(JComponent c, Graphics g, PaintContext context,
FieldBackgroundColorManager colorManager, RowColLocation cursorLoc, int rowHeight) {
paintSelection(g, colorManager, 0);
- paintHighlights(g, hlFactory.getHighlights(text, -1));
+ paintHighlights(g, hlFactory.getHighlights(this, text, -1));
g.setFont(metrics.getFont());
if (foregroundColor == null) {
foregroundColor = context.getForeground();
@@ -226,10 +225,10 @@ public class SimpleTextField implements Field {
}
protected void paintHighlights(Graphics g, Highlight[] highlights) {
- for (int i = 0; i < highlights.length; i++) {
- int startCol = Math.max(highlights[i].getStart(), 0);
- int endCol = Math.min(highlights[i].getEnd(), text.length());
- Color c = highlights[i].getColor();
+ for (Highlight highlight : highlights) {
+ int startCol = Math.max(highlight.getStart(), 0);
+ int endCol = Math.min(highlight.getEnd(), text.length());
+ Color c = highlight.getColor();
if (endCol >= startCol) {
int start = findX(startCol);
int end = findX(endCol + 1);
diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/field/VerticalLayoutTextField.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/field/VerticalLayoutTextField.java
index 7f4e79319a..dad543cad9 100644
--- a/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/field/VerticalLayoutTextField.java
+++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/field/VerticalLayoutTextField.java
@@ -268,7 +268,7 @@ public class VerticalLayoutTextField implements TextField {
cursorRow = cursorLoc.row();
}
- Highlight[] highlights = hlFactory.getHighlights(getText(), cursorTextOffset);
+ Highlight[] highlights = hlFactory.getHighlights(this, getText(), cursorTextOffset);
int columns = 0;
int n = subFields.size();
Color fieldBackgroundColor = colorManager.getBackgroundColor();
diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/internal/TestBigLayoutModel.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/internal/TestBigLayoutModel.java
index 371314727f..c2803615ea 100644
--- a/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/internal/TestBigLayoutModel.java
+++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/internal/TestBigLayoutModel.java
@@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
- * REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,8 +16,6 @@
package docking.widgets.fieldpanel.internal;
import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
import java.math.BigInteger;
import java.util.ArrayList;
@@ -33,11 +30,8 @@ import docking.widgets.indexedscrollpane.IndexedScrollPane;
public class TestBigLayoutModel implements LayoutModel {
private static final Highlight[] NO_HIGHLIGHTS = new Highlight[0];
- private static final HighlightFactory hlFactory = new HighlightFactory() {
- public Highlight[] getHighlights(String text, int cursorTextOffset) {
- return NO_HIGHLIGHTS;
- }
- };
+ private static final HighlightFactory hlFactory =
+ (field, text, cursorTextOffset) -> NO_HIGHLIGHTS;
ArrayList listeners = new ArrayList();
FontMetrics fm;
@@ -86,15 +80,13 @@ public class TestBigLayoutModel implements LayoutModel {
if (index.compareTo(numIndexes) >= 0) {
return null;
}
- String text =
- name + ": This is line " + index +
- " More text to make line longer abcdefghijklmnopqrstuvwxyzabcdefghijk";
+ String text = name + ": This is line " + index +
+ " More text to make line longer abcdefghijklmnopqrstuvwxyzabcdefghijk";
FieldElement fe1 = new TextFieldElement(new AttributedString(text, Color.BLACK, fm), 0, 0);
FieldElement fe2 =
new TextFieldElement(new AttributedString("More text", Color.BLACK, fm), 0, 0);
- SingleRowLayout layout =
- new SingleRowLayout(new ClippingTextField(20, 300, fe1, hlFactory),
- new ClippingTextField(330, 100, fe2, hlFactory));
+ SingleRowLayout layout = new SingleRowLayout(new ClippingTextField(20, 300, fe1, hlFactory),
+ new ClippingTextField(330, 100, fe2, hlFactory));
if (index.intValue() >= startBigSizes && index.intValue() <= endBigSizes) {
layout.insertSpaceAbove(30);
@@ -143,12 +135,7 @@ public class TestBigLayoutModel implements LayoutModel {
contentPane.setLayout(new BorderLayout());
contentPane.add(scrollPanel);
JButton button = new JButton("Hit Me");
- button.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- model.updateData(1000, 2000);
- }
- });
+ button.addActionListener(e -> model.updateData(1000, 2000));
contentPane.add(button, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/support/HighlightFactory.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/support/HighlightFactory.java
index 3d46ca7e66..8ac6c85d17 100644
--- a/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/support/HighlightFactory.java
+++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/support/HighlightFactory.java
@@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
- * REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,13 +15,18 @@
*/
package docking.widgets.fieldpanel.support;
+import docking.widgets.fieldpanel.field.Field;
+
public interface HighlightFactory {
+
/**
- * Returns the highlights for the given text.
- * @param text the text to be considered for highlighting.
+ * Returns the highlights for the given text
+ *
+ * @param field the field that is requesting the highlight
+ * @param text the text to be considered for highlighting
* @param cursorTextOffset the position in the given text of the cursor. A -1 indicates the
- * cursor is not in this field.
- * @return an array of highlights to be rendered.
+ * cursor is not in this field.
+ * @return an array of highlights to be rendered
*/
- public Highlight[] getHighlights(String text, int cursorTextOffset);
+ public Highlight[] getHighlights(Field field, String text, int cursorTextOffset);
}
diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/table/GTableWidget.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/table/GTableWidget.java
index d85f891941..b8a6a2cfb5 100644
--- a/Ghidra/Framework/Docking/src/main/java/docking/widgets/table/GTableWidget.java
+++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/table/GTableWidget.java
@@ -133,7 +133,7 @@ public class GTableWidget extends JPanel {
listener.itemPicked(gFilterTable.getSelectedRowObject());
}
- public void setItemPickListner(TableItemPickedListener listener) {
+ public void setItemPickListener(TableItemPickedListener listener) {
this.listener = listener;
}
diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/tree/GTree.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/tree/GTree.java
index 2b60c2e053..ea7c7ee19a 100644
--- a/Ghidra/Framework/Docking/src/main/java/docking/widgets/tree/GTree.java
+++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/tree/GTree.java
@@ -867,7 +867,7 @@ public class GTree extends JPanel implements BusyListener {
tree.getModel().addTreeModelListener(listener);
}
- public void removeGTModelListner(TreeModelListener listener) {
+ public void removeGTModelListener(TreeModelListener listener) {
tree.getModel().removeTreeModelListener(listener);
}
diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/tree/support/GTreeNodeTransferable.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/tree/support/GTreeNodeTransferable.java
index db434c3374..7a517077b1 100644
--- a/Ghidra/Framework/Docking/src/main/java/docking/widgets/tree/support/GTreeNodeTransferable.java
+++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/tree/support/GTreeNodeTransferable.java
@@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
- * REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,69 +18,75 @@ package docking.widgets.tree.support;
import java.awt.datatransfer.*;
import java.io.IOException;
import java.util.List;
+import java.util.Objects;
import docking.widgets.tree.GTreeNode;
/**
- * A transferable for sharing data via drag/drop and clipboard operations for GTrees.
+ * A transferable for sharing data via drag/drop and clipboard operations for GTrees
*/
public class GTreeNodeTransferable implements Transferable {
- private final List selectedData;
- private final GTreeTransferHandler transferHandler;
+ private final List selectedData;
+ private final GTreeTransferHandler transferHandler;
- /**
- * Creates this transferable based upon the selected data and uses the given transfer
- * handler to perform {@link Transferable} operations.
- * @param handler the handler used to perform transfer operations.
- * @param selectedData The
- */
- public GTreeNodeTransferable( GTreeTransferHandler handler, List selectedData) {
- this.selectedData = selectedData;
- this.transferHandler = handler;
- }
-
- /**
- * Returns all of the original selected data contained by this transferable.
- * @return all of the original selected data contained by this transferable
- */
- public List getAllData() {
- return selectedData;
- }
-
- /**
- * Gets the transfer data from the selection based upon the given flavor.
- * @param transferNodes The nodes from which to get the data.
- * @param flavor The flavor of data to retreive from the given selection.
- * @return the transfer data from the selection based upon the given flavor.
- * @throws UnsupportedFlavorException if the given flavor is not one of the supported flavors
- * returned by {@link #getSupportedDataFlavors(List)}.
- */
- public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
- return transferHandler.getTransferData(selectedData, flavor);
- }
-
- /**
- * Returns the DataFlavors for the types of data that this transferable supports, based upon
- * the given selection.
- * @param transferNodes The nodes to base the DataFlavor selection upon.
- * @return the DataFlavors for the types of data that this transferable supports, based upon
- * the given selection.
+ /**
+ * Creates this transferable based upon the selected data and uses the given transfer
+ * handler to perform {@link Transferable} operations
+ *
+ * @param handler the handler used to perform transfer operations
+ * @param selectedData The selected tree nodes
*/
- public DataFlavor[] getTransferDataFlavors() {
- return transferHandler.getSupportedDataFlavors(selectedData);
- }
+ public GTreeNodeTransferable(GTreeTransferHandler handler, List selectedData) {
+ this.transferHandler = Objects.requireNonNull(handler);
+ this.selectedData = Objects.requireNonNull(selectedData);
+ }
- /**
- * A convenience method to determine if this transferable supports the given flavor.
- * @return true if this transferable supports the given flavor.
- */
- public boolean isDataFlavorSupported(DataFlavor flavor) {
- DataFlavor[] flavors = transferHandler.getSupportedDataFlavors(selectedData);
- for(int i=0;i getAllData() {
+ return selectedData;
+ }
+
+ /**
+ * Gets the transfer data from the selection based upon the given flavor
+
+ * @param flavor The flavor of data to retrieve from the given selection.
+ * @return the transfer data from the selection based upon the given flavor.
+ * @throws UnsupportedFlavorException if the given flavor is not one of the supported flavors
+ * returned by {@link #getTransferDataFlavors()}
+ */
+ @Override
+ public Object getTransferData(DataFlavor flavor)
+ throws UnsupportedFlavorException, IOException {
+ return transferHandler.getTransferData(selectedData, flavor);
+ }
+
+ /**
+ * Returns the DataFlavors for the types of data that this transferable supports, based upon
+ * the given selection
+ *
+ * @return the DataFlavors for the types of data that this transferable supports, based upon
+ * the given selection
+ */
+ @Override
+ public DataFlavor[] getTransferDataFlavors() {
+ return transferHandler.getSupportedDataFlavors(selectedData);
+ }
+
+ /**
+ * A convenience method to determine if this transferable supports the given flavor
+ * @return true if this transferable supports the given flavor
+ */
+ @Override
+ public boolean isDataFlavorSupported(DataFlavor flavor) {
+ DataFlavor[] flavors = transferHandler.getSupportedDataFlavors(selectedData);
+ for (DataFlavor f : flavors) {
+ if (f.equals(flavor)) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/Ghidra/Framework/Docking/src/test/java/docking/widgets/fieldpanel/FlowLayoutTextFieldTest.java b/Ghidra/Framework/Docking/src/test/java/docking/widgets/fieldpanel/FlowLayoutTextFieldTest.java
index 675ec2b03f..604bd46201 100644
--- a/Ghidra/Framework/Docking/src/test/java/docking/widgets/fieldpanel/FlowLayoutTextFieldTest.java
+++ b/Ghidra/Framework/Docking/src/test/java/docking/widgets/fieldpanel/FlowLayoutTextFieldTest.java
@@ -15,7 +15,7 @@
*/
package docking.widgets.fieldpanel;
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.*;
import java.awt.*;
@@ -40,11 +40,8 @@ public class FlowLayoutTextFieldTest extends AbstractGenericTest {
@Before
public void setUp() throws Exception {
- HighlightFactory factory = new HighlightFactory() {
- @Override
- public Highlight[] getHighlights(String text, int cursorTextOffset) {
- return new Highlight[] { new Highlight(4, 4, Color.YELLOW) };
- }
+ HighlightFactory factory = (field, text, cursorTextOffset) -> {
+ return new Highlight[] { new Highlight(4, 4, Color.YELLOW) };
};
Font font = new Font("Times New Roman", 0, 14);
diff --git a/Ghidra/Framework/Docking/src/test/java/docking/widgets/fieldpanel/VerticalLayoutTextFieldTest.java b/Ghidra/Framework/Docking/src/test/java/docking/widgets/fieldpanel/VerticalLayoutTextFieldTest.java
index 6d77b473e9..dacf10ab15 100644
--- a/Ghidra/Framework/Docking/src/test/java/docking/widgets/fieldpanel/VerticalLayoutTextFieldTest.java
+++ b/Ghidra/Framework/Docking/src/test/java/docking/widgets/fieldpanel/VerticalLayoutTextFieldTest.java
@@ -15,7 +15,7 @@
*/
package docking.widgets.fieldpanel;
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.*;
import java.awt.*;
@@ -40,11 +40,8 @@ public class VerticalLayoutTextFieldTest extends AbstractGenericTest {
@Before
public void setUp() throws Exception {
- HighlightFactory factory = new HighlightFactory() {
- @Override
- public Highlight[] getHighlights(String text, int cursorTextOffset) {
- return new Highlight[] { new Highlight(4, 4, Color.YELLOW) };
- }
+ HighlightFactory factory = (field, text, cursorTextOffset) -> {
+ return new Highlight[] { new Highlight(4, 4, Color.YELLOW) };
};
Font font = new Font("Times New Roman", 0, 14);
diff --git a/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/store/FileSystem.java b/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/store/FileSystem.java
index 4cfd3fb7aa..6db0208eef 100644
--- a/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/store/FileSystem.java
+++ b/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/store/FileSystem.java
@@ -254,7 +254,7 @@ public interface FileSystem {
/**
* Adds the given listener to be notified of file system changes.
- * @param listener the listner to be added.
+ * @param listener the listener to be added.
*/
public void addFileSystemListener(FileSystemListener listener);
diff --git a/Ghidra/Framework/Graph/src/main/java/ghidra/graph/viewer/edge/PathHighlightListner.java b/Ghidra/Framework/Graph/src/main/java/ghidra/graph/viewer/edge/PathHighlightListener.java
similarity index 95%
rename from Ghidra/Framework/Graph/src/main/java/ghidra/graph/viewer/edge/PathHighlightListner.java
rename to Ghidra/Framework/Graph/src/main/java/ghidra/graph/viewer/edge/PathHighlightListener.java
index 68529067a9..366c5dd90f 100644
--- a/Ghidra/Framework/Graph/src/main/java/ghidra/graph/viewer/edge/PathHighlightListner.java
+++ b/Ghidra/Framework/Graph/src/main/java/ghidra/graph/viewer/edge/PathHighlightListener.java
@@ -15,7 +15,7 @@
*/
package ghidra.graph.viewer.edge;
-public interface PathHighlightListner {
+public interface PathHighlightListener {
/**
* Called when the a path is highlighted.
diff --git a/Ghidra/Framework/Graph/src/main/java/ghidra/graph/viewer/edge/VisualGraphPathHighlighter.java b/Ghidra/Framework/Graph/src/main/java/ghidra/graph/viewer/edge/VisualGraphPathHighlighter.java
index 0bc45cd701..f6bf916447 100644
--- a/Ghidra/Framework/Graph/src/main/java/ghidra/graph/viewer/edge/VisualGraphPathHighlighter.java
+++ b/Ghidra/Framework/Graph/src/main/java/ghidra/graph/viewer/edge/VisualGraphPathHighlighter.java
@@ -99,7 +99,7 @@ public class VisualGraphPathHighlighter> postDominanceFuture;
private CompletableFuture circuitFuture;
- private PathHighlightListner listener = isHover -> {
+ private PathHighlightListener listener = isHover -> {
// stub
};
@@ -108,7 +108,7 @@ public class VisualGraphPathHighlighter doUpdateFocusedVertex());
- public VisualGraphPathHighlighter(VisualGraph graph, PathHighlightListner listener) {
+ public VisualGraphPathHighlighter(VisualGraph graph, PathHighlightListener listener) {
this.graph = graph;
if (listener != null) {
this.listener = listener;
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/app/util/FileOpenDataFlavorHandler.java b/Ghidra/Framework/Project/src/main/java/ghidra/app/util/FileOpenDataFlavorHandler.java
index f4bdd441cc..4852c85c39 100644
--- a/Ghidra/Framework/Project/src/main/java/ghidra/app/util/FileOpenDataFlavorHandler.java
+++ b/Ghidra/Framework/Project/src/main/java/ghidra/app/util/FileOpenDataFlavorHandler.java
@@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
- * REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,11 +15,14 @@
*/
package ghidra.app.util;
-import ghidra.framework.plugintool.*;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.dnd.DropTargetDropEvent;
-import java.awt.datatransfer.*;
-import java.awt.dnd.*;
+import ghidra.framework.plugintool.PluginTool;
+/**
+ * Interface for classes that will handle drop actions for files dropped onto the tool
+ */
public interface FileOpenDataFlavorHandler {
- public void handle(PluginTool tool, Object obj, DropTargetDropEvent e, DataFlavor f);
+ public void handle(PluginTool tool, Object obj, DropTargetDropEvent e, DataFlavor f);
}
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/app/util/FileOpenDataFlavorHandlerService.java b/Ghidra/Framework/Project/src/main/java/ghidra/app/util/FileOpenDataFlavorHandlerService.java
deleted file mode 100644
index 687e6aed63..0000000000
--- a/Ghidra/Framework/Project/src/main/java/ghidra/app/util/FileOpenDataFlavorHandlerService.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/* ###
- * IP: GHIDRA
- * REVIEWED: YES
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * 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.util;
-
-import ghidra.framework.PluggableServiceRegistry;
-import ghidra.framework.main.datatree.DataTreeDragNDropHandler;
-import ghidra.framework.main.datatree.VersionInfoTransferable;
-
-public class FileOpenDataFlavorHandlerService {
- static {
- PluggableServiceRegistry.registerPluggableService(FileOpenDataFlavorHandlerService.class, new FileOpenDataFlavorHandlerService());
- }
-
- public static void registerDataFlavorHandlers() {
- FileOpenDataFlavorHandlerService factory = PluggableServiceRegistry.getPluggableService(FileOpenDataFlavorHandlerService.class);
- factory.doRegisterDataFlavorHandlers();
- }
-
- protected void doRegisterDataFlavorHandlers() {
- FileOpenDropHandler.addDataFlavorHandler(DataTreeDragNDropHandler.localDomainFileFlavor, new LocalTreeNodeFlavorHandler());
- FileOpenDropHandler.addDataFlavorHandler(VersionInfoTransferable.localVersionInfoFlavor, new LocalTreeNodeFlavorHandler());
- }
-}
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/app/util/FileOpenDropHandler.java b/Ghidra/Framework/Project/src/main/java/ghidra/app/util/FileOpenDropHandler.java
index 7a16da0504..6a4e4428ce 100644
--- a/Ghidra/Framework/Project/src/main/java/ghidra/app/util/FileOpenDropHandler.java
+++ b/Ghidra/Framework/Project/src/main/java/ghidra/app/util/FileOpenDropHandler.java
@@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
- * REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +15,6 @@
*/
package ghidra.app.util;
-import ghidra.framework.plugintool.PluginTool;
-import ghidra.util.CascadedDropTarget;
-
import java.awt.Component;
import java.awt.Container;
import java.awt.datatransfer.DataFlavor;
@@ -33,6 +29,8 @@ import javax.swing.CellRendererPane;
import docking.DropTargetHandler;
import docking.dnd.DropTgtAdapter;
import docking.dnd.Droppable;
+import ghidra.framework.plugintool.PluginTool;
+import ghidra.util.CascadedDropTarget;
/**
* Handles drag/drop events on a given component such that a file
@@ -44,9 +42,6 @@ import docking.dnd.Droppable;
public class FileOpenDropHandler implements DropTargetHandler, Droppable, ContainerListener {
private static HashMap handlers =
new HashMap();
- static {
- FileOpenDataFlavorHandlerService.registerDataFlavorHandlers();
- }
private DropTgtAdapter dropTargetAdapter;
private DropTarget globalDropTarget;
@@ -75,11 +70,13 @@ public class FileOpenDropHandler implements DropTargetHandler, Droppable, Contai
/**
* Dispose this drop handler.
*/
+ @Override
public void dispose() {
deinitializeComponents(component);
globalDropTarget.removeDropTargetListener(dropTargetAdapter);
}
+ @Override
public boolean isDropOk(DropTargetDragEvent e) {
Set flavors = handlers.keySet();
for (DataFlavor dataFlavor : flavors) {
@@ -90,6 +87,7 @@ public class FileOpenDropHandler implements DropTargetHandler, Droppable, Contai
return false;
}
+ @Override
public void add(Object obj, DropTargetDropEvent e, DataFlavor f) {
FileOpenDataFlavorHandler handler = handlers.get(f);
if (handler != null) {
@@ -97,24 +95,28 @@ public class FileOpenDropHandler implements DropTargetHandler, Droppable, Contai
}
}
+ @Override
public void dragUnderFeedback(boolean ok, DropTargetDragEvent e) {
// nothing to display or do
}
+ @Override
public void undoDragUnderFeedback() {
// nothing to display or do
}
private void initializeComponents(Component comp) {
- if (comp instanceof CellRendererPane)
+ if (comp instanceof CellRendererPane) {
return;
+ }
if (comp instanceof Container) {
Container c = (Container) comp;
c.addContainerListener(this);
Component comps[] = c.getComponents();
- for (Component element : comps)
+ for (Component element : comps) {
initializeComponents(element);
+ }
}
DropTarget primaryDropTarget = comp.getDropTarget();
if (primaryDropTarget != null) {
@@ -123,15 +125,17 @@ public class FileOpenDropHandler implements DropTargetHandler, Droppable, Contai
}
private void deinitializeComponents(Component comp) {
- if (comp instanceof CellRendererPane)
+ if (comp instanceof CellRendererPane) {
return;
+ }
if (comp instanceof Container) {
Container c = (Container) comp;
c.removeContainerListener(this);
Component comps[] = c.getComponents();
- for (Component element : comps)
+ for (Component element : comps) {
deinitializeComponents(element);
+ }
}
DropTarget dt = comp.getDropTarget();
if (dt instanceof CascadedDropTarget) {
@@ -141,15 +145,18 @@ public class FileOpenDropHandler implements DropTargetHandler, Droppable, Contai
}
}
+ @Override
public void componentAdded(ContainerEvent e) {
initializeComponents(e.getChild());
}
+ @Override
public void componentRemoved(ContainerEvent e) {
deinitializeComponents(e.getChild());
}
- public static void addDataFlavorHandler(DataFlavor dataFlavor, FileOpenDataFlavorHandler handler) {
+ public static void addDataFlavorHandler(DataFlavor dataFlavor,
+ FileOpenDataFlavorHandler handler) {
handlers.put(dataFlavor, handler);
}
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/app/util/LocalTreeNodeFlavorHandler.java b/Ghidra/Framework/Project/src/main/java/ghidra/app/util/LocalTreeNodeFlavorHandler.java
deleted file mode 100644
index fe87e5cf59..0000000000
--- a/Ghidra/Framework/Project/src/main/java/ghidra/app/util/LocalTreeNodeFlavorHandler.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/* ###
- * IP: GHIDRA
- * REVIEWED: YES
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * 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.util;
-
-import ghidra.framework.main.GetVersionedObjectTask;
-import ghidra.framework.main.datatree.*;
-import ghidra.framework.model.*;
-import ghidra.framework.plugintool.PluginTool;
-
-import java.awt.datatransfer.DataFlavor;
-import java.awt.dnd.DropTargetDropEvent;
-import java.util.List;
-
-final class LocalTreeNodeFlavorHandler implements FileOpenDataFlavorHandler {
- public void handle(PluginTool tool, Object obj, DropTargetDropEvent e, DataFlavor f) {
- if (f.equals(DataTreeDragNDropHandler.localDomainFileFlavor)) {
- List> files = (List>) obj;
- DomainFile[] domainFiles = new DomainFile[files.size()];
- for (int i = 0; i < files.size(); i++) {
- domainFiles[i] = (DomainFile) files.get(i);
- }
- tool.acceptDomainFiles(domainFiles);
- }
- else if (f.equals(DataTreeDragNDropHandler.localDomainFileTreeFlavor)) {
- List> files = (List>) obj;
- DomainFile[] domainFiles = new DomainFile[files.size()];
- for (int i = 0; i < files.size(); i++) {
- DomainFileNode node = (DomainFileNode) files.get(i);
- domainFiles[i] = node.getDomainFile();
- }
- tool.acceptDomainFiles(domainFiles);
- }
- else if (f.equals(VersionInfoTransferable.localVersionInfoFlavor)) {
- VersionInfo info = (VersionInfo) obj;
- Project project = tool.getProject();
- ProjectData projectData = project.getProjectData();
- DomainFile file = projectData.getFile(info.getDomainFilePath());
- DomainObject versionedObj = getVersionedObject(tool, file, info.getVersionNumber());
-
- if (versionedObj != null) {
- DomainFile domainFile = versionedObj.getDomainFile();
- if (domainFile != null) {
- tool.acceptDomainFiles(new DomainFile[] { domainFile });
- }
- versionedObj.release(this);
- }
- }
- }
-
- private DomainObject getVersionedObject(PluginTool tool, DomainFile file, int versionNumber) {
- GetVersionedObjectTask task = new GetVersionedObjectTask(this, file, versionNumber);
- tool.execute(task, 250);
- return task.getVersionedObject();
- }
-}
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/app/util/LocalVersionInfoFlavorHandler.java b/Ghidra/Framework/Project/src/main/java/ghidra/app/util/LocalVersionInfoFlavorHandler.java
deleted file mode 100644
index 62d2bd7e75..0000000000
--- a/Ghidra/Framework/Project/src/main/java/ghidra/app/util/LocalVersionInfoFlavorHandler.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/* ###
- * IP: GHIDRA
- * REVIEWED: YES
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * 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.util;
-
-import ghidra.framework.main.*;
-import ghidra.framework.main.datatree.*;
-import ghidra.framework.model.*;
-import ghidra.framework.plugintool.*;
-
-import java.awt.datatransfer.*;
-import java.awt.dnd.*;
-
-final class LocalVersionInfoFlavorHandler implements
- FileOpenDataFlavorHandler {
- public void handle(PluginTool tool, Object obj, DropTargetDropEvent e, DataFlavor f) {
- VersionInfo info = (VersionInfo) obj;
-
- DomainFile file = tool.getProject().getProjectData().getFile(info.getDomainFilePath());
- GetVersionedObjectTask task = new GetVersionedObjectTask(this, file,
- info.getVersionNumber());
- tool.execute(task, 250);
- DomainObject versionedObj = task.getVersionedObject();
-
- if (versionedObj != null) {
- DomainFile vfile = versionedObj.getDomainFile();
- tool.acceptDomainFiles(new DomainFile[] {vfile});
- versionedObj.release(this);
- }
- }
-}
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatable/ProjectDataActionContext.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatable/ProjectDataActionContext.java
index 179325b06a..c2acecdda6 100644
--- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatable/ProjectDataActionContext.java
+++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatable/ProjectDataActionContext.java
@@ -30,6 +30,7 @@ public class ProjectDataActionContext extends ActionContext implements DomainFil
private Component comp;
private boolean isActiveProject;
private ProjectData projectData;
+ private boolean isTransient;
public ProjectDataActionContext(ComponentProvider provider, ProjectData projectData,
Object contextObject, List selectedFolders,
@@ -112,4 +113,20 @@ public class ProjectDataActionContext extends ActionContext implements DomainFil
}
return false;
}
+
+ /**
+ * Transient data is that which will appear in a temporary project dialog
+ * @param isTransient true if transient
+ */
+ public void setTransient(boolean isTransient) {
+ this.isTransient = isTransient;
+ }
+
+ /**
+ * Transient data is that which will appear in a temporary project dialog
+ * @return true if transient
+ */
+ public boolean isTransient() {
+ return isTransient;
+ }
}
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatable/ProjectDataContextAction.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatable/ProjectDataContextAction.java
index 5e9daa17eb..dd853ebb3a 100644
--- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatable/ProjectDataContextAction.java
+++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatable/ProjectDataContextAction.java
@@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
- * REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,20 +25,42 @@ public abstract class ProjectDataContextAction extends DockingAction {
}
@Override
- public final boolean isEnabledForContext(ActionContext actionContext) {
+ public boolean isEnabledForContext(ActionContext actionContext) {
if (!(actionContext instanceof ProjectDataActionContext)) {
return false;
}
+
ProjectDataActionContext context = (ProjectDataActionContext) actionContext;
+ if (ignoreTransientProject(context)) {
+ return false;
+ }
+
return isEnabledForContext(context);
}
+ protected boolean ignoreTransientProject(ProjectDataActionContext context) {
+ if (supportsTransientProjectData()) {
+ return false;
+ }
+ return context.isTransient();
+ }
+
+ /**
+ * Signals that this action can work on normal project data, as well as transient data.
+ * Transient data is that which will appear in a temporary project dialog.
+ *
+ * @return true if this action works on transient project data
+ */
+ protected boolean supportsTransientProjectData() {
+ return false;
+ }
+
protected boolean isEnabledForContext(ProjectDataActionContext context) {
return context.hasOneOrMoreFilesAndFolders();
}
@Override
- public final void actionPerformed(ActionContext context) {
+ public void actionPerformed(ActionContext context) {
actionPerformed((ProjectDataActionContext) context);
}
@@ -59,7 +80,7 @@ public abstract class ProjectDataContextAction extends DockingAction {
@Override
public boolean isAddToPopup(ActionContext context) {
- if (!(context instanceof ProjectDataActionContext)) {
+ if (!isEnabledForContext(context)) {
return false;
}
return isAddToPopup((ProjectDataActionContext) context);
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatable/ProjectDataContextToggleAction.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatable/ProjectDataContextToggleAction.java
index d1fcb555f5..2b9dc7b39c 100644
--- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatable/ProjectDataContextToggleAction.java
+++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatable/ProjectDataContextToggleAction.java
@@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
- * REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,10 +29,32 @@ public abstract class ProjectDataContextToggleAction extends ToggleDockingAction
if (!(actionContext instanceof ProjectDataActionContext)) {
return false;
}
+
ProjectDataActionContext context = (ProjectDataActionContext) actionContext;
+ if (ignoreTransientProject(context)) {
+ return false;
+ }
+
return isEnabledForContext(context);
}
+ protected boolean ignoreTransientProject(ProjectDataActionContext context) {
+ if (supportsTransientProjectData()) {
+ return false;
+ }
+ return context.isTransient();
+ }
+
+ /**
+ * Signals that this action can work on normal project data, as well as transient data.
+ * Transient data is that which will appear in a temporary project dialog.
+ *
+ * @return true if this action works on transient project data
+ */
+ protected boolean supportsTransientProjectData() {
+ return false;
+ }
+
protected boolean isEnabledForContext(ProjectDataActionContext context) {
return context.hasOneOrMoreFilesAndFolders();
}
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatable/ProjectDataTreeContextAction.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatable/ProjectDataTreeContextAction.java
index 137b73986f..7df40012df 100644
--- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatable/ProjectDataTreeContextAction.java
+++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatable/ProjectDataTreeContextAction.java
@@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
- * REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +15,9 @@
*/
package ghidra.framework.main.datatable;
-import ghidra.framework.main.datatree.ProjectDataTreeActionContext;
import docking.ActionContext;
import docking.action.DockingAction;
+import ghidra.framework.main.datatree.ProjectDataTreeActionContext;
public abstract class ProjectDataTreeContextAction extends DockingAction {
@@ -31,10 +30,32 @@ public abstract class ProjectDataTreeContextAction extends DockingAction {
if (!(actionContext instanceof ProjectDataTreeActionContext)) {
return false;
}
+
ProjectDataTreeActionContext context = (ProjectDataTreeActionContext) actionContext;
+ if (ignoreTransientProject(context)) {
+ return false;
+ }
+
return isEnabledForContext(context);
}
+ protected boolean ignoreTransientProject(ProjectDataActionContext context) {
+ if (supportsTransientProjectData()) {
+ return false;
+ }
+ return context.isTransient();
+ }
+
+ /**
+ * Signals that this action can work on normal project data, as well as transient data.
+ * Transient data is that which will appear in a temporary project dialog.
+ *
+ * @return true if this action works on transient project data
+ */
+ protected boolean supportsTransientProjectData() {
+ return false;
+ }
+
protected boolean isEnabledForContext(ProjectDataTreeActionContext context) {
return context.hasOneOrMoreFilesAndFolders();
}
@@ -60,7 +81,7 @@ public abstract class ProjectDataTreeContextAction extends DockingAction {
@Override
public boolean isAddToPopup(ActionContext context) {
- if (!(context instanceof ProjectDataTreeActionContext)) {
+ if (!isEnabledForContext(context)) {
return false;
}
return isAddToPopup((ProjectDataTreeActionContext) context);
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DataFlavorHandlerService.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DataFlavorHandlerService.java
deleted file mode 100644
index 3d6bedb22b..0000000000
--- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DataFlavorHandlerService.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/* ###
- * IP: GHIDRA
- * REVIEWED: YES
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * 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.framework.main.datatree;
-
-import ghidra.framework.PluggableServiceRegistry;
-
-public class DataFlavorHandlerService {
- static {
- PluggableServiceRegistry.registerPluggableService(DataFlavorHandlerService.class, new DataFlavorHandlerService());
- }
-
- public static void registerDataFlavorHandlers() {
- DataFlavorHandlerService factory = PluggableServiceRegistry.getPluggableService(DataFlavorHandlerService.class);
- factory.doRegisterDataFlavorHandlers();
- }
-
- protected void doRegisterDataFlavorHandlers() {
- final LocalTreeNodeHandler localTreeNodeHandler = new LocalTreeNodeHandler();
- DataTreeDragNDropHandler.addActiveDataFlavorHandler(DataTreeDragNDropHandler.localDomainFileTreeFlavor, localTreeNodeHandler);
- DataTreeDragNDropHandler.addActiveDataFlavorHandler(VersionInfoTransferable.localVersionInfoFlavor, new LocalVersionInfoHandler());
-
- DataTreeDragNDropHandler.addInactiveDataFlavorHandler(DataTreeDragNDropHandler.localDomainFileTreeFlavor, localTreeNodeHandler);
- }
-}
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DataTree.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DataTree.java
index 513e2aab26..d2e3c8d145 100644
--- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DataTree.java
+++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DataTree.java
@@ -16,8 +16,7 @@
package ghidra.framework.main.datatree;
import java.awt.Component;
-import java.awt.event.*;
-import java.util.List;
+import java.awt.event.KeyEvent;
import javax.swing.JTree;
import javax.swing.KeyStroke;
@@ -30,20 +29,13 @@ import docking.widgets.tree.support.GTreeRenderer;
import ghidra.framework.main.FrontEndTool;
/**
- * Tree that shows the folders and domain files in a Project.
+ * Tree that shows the folders and domain files in a Project
*/
public class DataTree extends GTree {
- static {
- DataFlavorHandlerService.registerDataFlavorHandlers();
- }
private boolean isActive;
private DataTreeDragNDropHandler dragNDropHandler;
- /**
- * Constructor
- * @param folder root domain folder for the project.
- */
DataTree(FrontEndTool tool, GTreeRootNode root) {
super(root);
@@ -53,30 +45,11 @@ public class DataTree extends GTree {
docking.ToolTipManager.sharedInstance().registerComponent(this);
- //When the user right clicks, change selection to what the mouse was under
- addMouseListener(new MouseAdapter() {
- @Override
- public void mousePressed(MouseEvent evt) {
- if (evt.getButton() == MouseEvent.BUTTON3) {
- //Find the would-be newly selected path
- TreePath newPath = getPathForLocation(evt.getX(), evt.getY());
- if (newPath == null) {
- return;
- }
- //Determine if the path is already selected--If so, do not change the selection
- TreePath[] paths = getSelectionPaths();
- if (paths != null) {
- for (TreePath element : paths) {
- if (element.equals(newPath)) {
- return;
- }
- }
- }
- }
- }
- });
- dragNDropHandler = new DataTreeDragNDropHandler(tool, this, isActive);
- setDragNDropHandler(dragNDropHandler);
+ if (tool != null) {
+ dragNDropHandler = new DataTreeDragNDropHandler(tool, this, isActive);
+ setDragNDropHandler(dragNDropHandler);
+ }
+
initializeKeyEvents();
}
@@ -92,74 +65,10 @@ public class DataTree extends GTree {
KeyStroke.getKeyStroke(KeyEvent.VK_X, DockingUtils.CONTROL_KEY_MODIFIER_MASK));
}
- void setProjectActive(boolean b) {
- dragNDropHandler.setProjectActive(b);
- }
-
- /**
- * Return true if this path has all of its subpaths expanded.
- */
- public boolean allPathsExpanded(TreePath path) {
-
- GTreeNode node = (GTreeNode) path.getLastPathComponent();
- if (node.isLeaf()) {
- return true;
+ void setProjectActive(boolean isActive) {
+ if (dragNDropHandler != null) {
+ dragNDropHandler.setProjectActive(isActive);
}
- if (isCollapsed(path)) {
- return false;
- }
-
- boolean allLeaves = true;
-
- List children = node.getChildren();
- for (GTreeNode child : children) {
- if (child.isLeaf()) {
- continue;
- }
- allLeaves = false;
- if (!isExpanded(child.getTreePath())) {
- return false;
- }
-
- if (!allPathsExpanded(child.getTreePath())) {
- return false;
- }
- }
- if (allLeaves) {
- return isExpanded(path);
- }
- return true;
- }
-
- /**
- * Return true if this path has all of its subpaths collapsed.
- */
- public boolean allPathsCollapsed(TreePath path) {
- GTreeNode node = (GTreeNode) path.getLastPathComponent();
-
- if (isExpanded(path)) {
- return false;
- }
- boolean allLeaves = true; // variable for knowing whether all children are leaves
-
- node.getChildren();
- for (GTreeNode child : node) {
- if (child.isLeaf()) {
- continue;
- }
- allLeaves = false;
- if (!isCollapsed(child.getTreePath())) {
- return false;
- }
-
- if (!allPathsCollapsed(child.getTreePath())) {
- return false;
- }
- }
- if (allLeaves) {
- return isCollapsed(path);
- }
- return true;
}
public void clearSelection() {
@@ -183,20 +92,7 @@ public class DataTree extends GTree {
getJTree().stopEditing();
}
- //////////////////////////////////////////////////////////////////////
- // *** private methods
- //////////////////////////////////////////////////////////////////////
- /**
- * Tree cell renderer to use the appropriate icons for the
- * DataTreeNodes.
- */
private class DataTreeCellRenderer extends GTreeRenderer {
-
- /**
- * Configures the renderer based on the passed in components.
- * The icon is set according to value, expanded, and leaf
- * parameters.
- */
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel,
boolean expanded, boolean leaf, int row, boolean doesHaveFocus) {
@@ -209,7 +105,5 @@ public class DataTree extends GTree {
}
return this;
}
-
}
-
}
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DataTreeClipboardUtils.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DataTreeClipboardUtils.java
index 40cdb3a720..f522152a2a 100644
--- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DataTreeClipboardUtils.java
+++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DataTreeClipboardUtils.java
@@ -23,6 +23,7 @@ import javax.swing.tree.TreePath;
import docking.dnd.GClipboard;
import docking.widgets.tree.GTreeNode;
+import docking.widgets.tree.support.GTreeNodeTransferable;
import ghidra.util.Msg;
/**
@@ -35,14 +36,8 @@ public class DataTreeClipboardUtils {
* Static instance of a callback handler that is notified when the clipboard is changed
* and our data is discarded.
*/
- private static final ClipboardOwner DATATREE_CLIPBOARD_OWNER = new ClipboardOwner() {
- @Override
- public void lostOwnership(Clipboard clipboard, Transferable contents) {
- // This is called when something other than this class modifies the clipboard
- // and our data is discarded.
- clearCuttables(contents);
- }
- };
+ private static final ClipboardOwner DATATREE_CLIPBOARD_OWNER =
+ (clipboard, contents) -> clearCuttables(contents);
/**
* Pushes the GTreeNodes in the specified TreePath array to the clipboard.
@@ -59,8 +54,9 @@ public class DataTreeClipboardUtils {
GTreeNode node = (GTreeNode) element.getLastPathComponent();
list.add(node);
}
- DataTreeNodeTransferable contents =
- new DataTreeNodeTransferable(tree.getDragNDropHandler(), list);
+
+ GTreeNodeTransferable contents =
+ new GTreeNodeTransferable(tree.getDragNDropHandler(), list);
try {
clipboard.setContents(contents, DATATREE_CLIPBOARD_OWNER);
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DataTreeDragNDropHandler.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DataTreeDragNDropHandler.java
index a7b9f32770..70293082f3 100644
--- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DataTreeDragNDropHandler.java
+++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DataTreeDragNDropHandler.java
@@ -30,9 +30,7 @@ import ghidra.util.Msg;
import ghidra.util.exception.AssertException;
public class DataTreeDragNDropHandler implements GTreeDragNDropHandler {
- private static Map activeProjectDropFlavorHandlerMap =
- new HashMap<>();
- private static Map inactiveProjectDropFlavorHandlerMap =
+ private static Map activeProjectDropFlavorHandlerMap =
new HashMap<>();
public static DataFlavor localDomainFileTreeFlavor = createLocalTreeNodeFlavor();
public static DataFlavor localDomainFileFlavor = createLocalTreeFlavor();
@@ -79,29 +77,31 @@ public class DataTreeDragNDropHandler implements GTreeDragNDropHandler {
public void drop(GTreeNode destination, Transferable transferable, int dropAction) {
DataFlavor[] transferDataFlavors = transferable.getTransferDataFlavors();
for (DataFlavor dataFlavor : transferDataFlavors) {
- DataFlavorHandler flavorHandler = getFlavorHandler(dataFlavor);
+ DataTreeFlavorHandler flavorHandler = getFlavorHandler(dataFlavor);
if (flavorHandler != null) {
- try {
- Object transferData = transferable.getTransferData(dataFlavor);
- flavorHandler.handle(tool, tree, destination, transferData, dropAction);
- }
- catch (UnsupportedFlavorException e) {
- throw new AssertException(
- "Got unsupported flavor from using a supported flavor");
- }
- catch (IOException e) {
- Msg.showError(this, null, "IO Error", "Error during drop", e);
- }
+ handleDrop(destination, transferable, dropAction, dataFlavor, flavorHandler);
return;
}
}
}
- private DataFlavorHandler getFlavorHandler(DataFlavor flavor) {
- if (isActiveProject) {
- return activeProjectDropFlavorHandlerMap.get(flavor);
+ private void handleDrop(GTreeNode destination, Transferable transferable, int dropAction,
+ DataFlavor dataFlavor, DataTreeFlavorHandler flavorHandler) {
+
+ try {
+ Object transferData = transferable.getTransferData(dataFlavor);
+ flavorHandler.handle(tool, tree, destination, transferData, dropAction);
}
- return inactiveProjectDropFlavorHandlerMap.get(flavor);
+ catch (UnsupportedFlavorException e) {
+ throw new AssertException("Got unsupported flavor from using a supported flavor");
+ }
+ catch (IOException e) {
+ Msg.showError(this, null, "IO Error", "Error during drop", e);
+ }
+ }
+
+ private DataTreeFlavorHandler getFlavorHandler(DataFlavor flavor) {
+ return activeProjectDropFlavorHandlerMap.get(flavor);
}
@Override
@@ -134,13 +134,6 @@ public class DataTreeDragNDropHandler implements GTreeDragNDropHandler {
@Override
public DataFlavor[] getSupportedDataFlavors(List transferNodes) {
return allSupportedFlavors;
-// Set keySet = null;
-// if (isActiveProject) {
-// keySet = activeProjectDropFlavorHandlerMap.keySet();
-// } else {
-// keySet = inactiveProjectDropFlavorHandlerMap.keySet();
-// }
-// return keySet.toArray(new DataFlavor[keySet.size()]);
}
@Override
@@ -196,24 +189,15 @@ public class DataTreeDragNDropHandler implements GTreeDragNDropHandler {
return false;
}
- public static void addActiveDataFlavorHandler(DataFlavor flavor, DataFlavorHandler handler) {
+ public static void addActiveDataFlavorHandler(DataFlavor flavor, DataTreeFlavorHandler handler) {
activeProjectDropFlavorHandlerMap.put(flavor, handler);
}
- public static void addInactiveDataFlavorHandler(DataFlavor flavor, DataFlavorHandler handler) {
- inactiveProjectDropFlavorHandlerMap.put(flavor, handler);
- }
-
- public static DataFlavorHandler removeActiveDataFlavorHandler(DataFlavor flavor) {
+ public static DataTreeFlavorHandler removeActiveDataFlavorHandler(DataFlavor flavor) {
return activeProjectDropFlavorHandlerMap.remove(flavor);
}
- public static DataFlavorHandler removeInctiveDataFlavorHandler(DataFlavor flavor) {
- return inactiveProjectDropFlavorHandlerMap.remove(flavor);
- }
-
public void setProjectActive(boolean b) {
isActiveProject = b;
}
-
}
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DataFlavorHandler.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DataTreeFlavorHandler.java
similarity index 69%
rename from Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DataFlavorHandler.java
rename to Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DataTreeFlavorHandler.java
index f63e22469c..18aba84d63 100644
--- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DataFlavorHandler.java
+++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DataTreeFlavorHandler.java
@@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
- * REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,10 +15,13 @@
*/
package ghidra.framework.main.datatree;
-import ghidra.framework.main.FrontEndTool;
import docking.widgets.tree.GTreeNode;
+import ghidra.framework.plugintool.PluginTool;
-public interface DataFlavorHandler {
- public void handle(FrontEndTool tool, DataTree dataTree, GTreeNode destinationNode,
- Object transferData, int dropAction);
+/**
+ * Interface for classes that will handle drop actions for {@link DataTree}s.
+ */
+public interface DataTreeFlavorHandler {
+ public void handle(PluginTool tool, DataTree dataTree, GTreeNode destinationNode,
+ Object transferData, int dropAction);
}
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DataTreeNodeTransferable.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DataTreeNodeTransferable.java
deleted file mode 100644
index 793a178278..0000000000
--- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/DataTreeNodeTransferable.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/* ###
- * IP: GHIDRA
- * REVIEWED: YES
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * 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.framework.main.datatree;
-
-import java.util.List;
-
-import docking.widgets.tree.GTreeNode;
-import docking.widgets.tree.support.GTreeNodeTransferable;
-import docking.widgets.tree.support.GTreeTransferHandler;
-
-public class DataTreeNodeTransferable extends GTreeNodeTransferable {
- public DataTreeNodeTransferable(GTreeTransferHandler handler, List selectedData) {
- super(handler, selectedData);
- }
-
-}
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/LocalTreeNodeHandler.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/LocalTreeNodeHandler.java
index a31fcc76af..bcc70cdd84 100644
--- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/LocalTreeNodeHandler.java
+++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/LocalTreeNodeHandler.java
@@ -15,29 +15,55 @@
*/
package ghidra.framework.main.datatree;
+import java.awt.datatransfer.DataFlavor;
import java.awt.dnd.DnDConstants;
+import java.awt.dnd.DropTargetDropEvent;
import java.io.IOException;
import java.util.List;
-import javax.swing.SwingUtilities;
-
import docking.widgets.tree.GTreeNode;
import docking.widgets.tree.GTreeState;
-import ghidra.framework.main.FrontEndTool;
+import ghidra.app.util.FileOpenDataFlavorHandler;
import ghidra.framework.model.DomainFile;
import ghidra.framework.model.DomainFolder;
+import ghidra.framework.plugintool.PluginTool;
import ghidra.util.Msg;
+import ghidra.util.SystemUtilities;
import ghidra.util.exception.DuplicateFileException;
import ghidra.util.exception.FileInUseException;
import ghidra.util.task.*;
-final class LocalTreeNodeHandler implements DataFlavorHandler {
+public final class LocalTreeNodeHandler
+ implements DataTreeFlavorHandler, FileOpenDataFlavorHandler {
+
private DataTree dataTree;
private GTreeState treeState;
+ @Override
+ public void handle(PluginTool tool, Object obj, DropTargetDropEvent e, DataFlavor f) {
+
+ if (f.equals(DataTreeDragNDropHandler.localDomainFileFlavor)) {
+ List> files = (List>) obj;
+ DomainFile[] domainFiles = new DomainFile[files.size()];
+ for (int i = 0; i < files.size(); i++) {
+ domainFiles[i] = (DomainFile) files.get(i);
+ }
+ tool.acceptDomainFiles(domainFiles);
+ }
+ else if (f.equals(DataTreeDragNDropHandler.localDomainFileTreeFlavor)) {
+ List> files = (List>) obj;
+ DomainFile[] domainFiles = new DomainFile[files.size()];
+ for (int i = 0; i < files.size(); i++) {
+ DomainFileNode node = (DomainFileNode) files.get(i);
+ domainFiles[i] = node.getDomainFile();
+ }
+ tool.acceptDomainFiles(domainFiles);
+ }
+ }
+
@Override
@SuppressWarnings("unchecked")
- public void handle(FrontEndTool tool, DataTree tree, GTreeNode destinationNode,
+ public void handle(PluginTool tool, DataTree tree, GTreeNode destinationNode,
Object transferData, int dropAction) {
this.dataTree = tree;
@@ -52,12 +78,9 @@ final class LocalTreeNodeHandler implements DataFlavorHandler {
new TaskLauncher(task, dataTree, 1000);
if (treeState != null) { // is set to null if drag results in a task
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- treeState.updateStateForMovedNodes();
- dataTree.restoreTreeState(treeState);
- }
+ SystemUtilities.runSwingLater(() -> {
+ treeState.updateStateForMovedNodes();
+ dataTree.restoreTreeState(treeState);
});
}
}
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/LocalVersionInfoHandler.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/LocalVersionInfoHandler.java
index 3dc8e451ec..294f45895d 100644
--- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/LocalVersionInfoHandler.java
+++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/LocalVersionInfoHandler.java
@@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
- * REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,42 +13,64 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/**
- *
- */
package ghidra.framework.main.datatree;
-import ghidra.framework.client.*;
-import ghidra.framework.main.FrontEndTool;
-import ghidra.framework.model.DomainFile;
-import ghidra.framework.model.DomainFolder;
-import ghidra.util.task.TaskLauncher;
-
+import java.awt.datatransfer.DataFlavor;
+import java.awt.dnd.DropTargetDropEvent;
import java.io.IOException;
import docking.widgets.tree.GTreeNode;
+import ghidra.app.util.FileOpenDataFlavorHandler;
+import ghidra.framework.client.*;
+import ghidra.framework.main.GetVersionedObjectTask;
+import ghidra.framework.model.*;
+import ghidra.framework.plugintool.PluginTool;
+import ghidra.util.task.TaskLauncher;
-final class LocalVersionInfoHandler implements DataFlavorHandler {
- public void handle(FrontEndTool tool, DataTree dataTree, GTreeNode destinationNode,
- Object transferData, int dropAction) {
- DomainFolder folder = getDomainFolder(destinationNode);
-
- VersionInfo info = (VersionInfo) transferData;
- RepositoryAdapter rep = tool.getProject().getProjectData().getRepository();
- try {
- if (rep != null) {
- rep.connect();
- }
- DomainFile file = tool.getProject().getProjectData().getFile(info.getDomainFilePath());
- if (file != null) {
- new TaskLauncher(new CopyFileVersionTask(file, info.getVersionNumber(), folder), dataTree, 500);
- }
- }
- catch (NotConnectedException exc) {}
- catch (IOException exc) {
- ClientUtil.handleException(rep, exc, "Repository Connection", tool.getToolFrame());
- }
- }
+public final class LocalVersionInfoHandler
+ implements DataTreeFlavorHandler, FileOpenDataFlavorHandler {
+
+ @Override
+ public void handle(PluginTool tool, Object obj, DropTargetDropEvent e, DataFlavor f) {
+ VersionInfo info = (VersionInfo) obj;
+
+ DomainFile file = tool.getProject().getProjectData().getFile(info.getDomainFilePath());
+ GetVersionedObjectTask task =
+ new GetVersionedObjectTask(this, file, info.getVersionNumber());
+ tool.execute(task, 250);
+ DomainObject versionedObj = task.getVersionedObject();
+
+ if (versionedObj != null) {
+ DomainFile vfile = versionedObj.getDomainFile();
+ tool.acceptDomainFiles(new DomainFile[] { vfile });
+ versionedObj.release(this);
+ }
+ }
+
+ @Override
+ public void handle(PluginTool tool, DataTree dataTree, GTreeNode destinationNode,
+ Object transferData, int dropAction) {
+ DomainFolder folder = getDomainFolder(destinationNode);
+
+ VersionInfo info = (VersionInfo) transferData;
+ RepositoryAdapter rep = tool.getProject().getProjectData().getRepository();
+ try {
+ if (rep != null) {
+ rep.connect();
+ }
+ DomainFile file = tool.getProject().getProjectData().getFile(info.getDomainFilePath());
+ if (file != null) {
+ new TaskLauncher(new CopyFileVersionTask(file, info.getVersionNumber(), folder),
+ dataTree, 500);
+ }
+ }
+ catch (NotConnectedException exc) {
+ // not sure why we squash this?
+ }
+ catch (IOException exc) {
+ ClientUtil.handleException(rep, exc, "Repository Connection", tool.getToolFrame());
+ }
+ }
private DomainFolder getDomainFolder(GTreeNode destinationNode) {
if (destinationNode instanceof DomainFolderNode) {
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/ProjectDataTreeActionContext.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/ProjectDataTreeActionContext.java
index 63eba46ece..cffbbc0d28 100644
--- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/ProjectDataTreeActionContext.java
+++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/ProjectDataTreeActionContext.java
@@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
- * REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,14 +15,13 @@
*/
package ghidra.framework.main.datatree;
-import ghidra.framework.main.datatable.ProjectDataActionContext;
-import ghidra.framework.model.*;
-
import java.util.List;
import javax.swing.tree.TreePath;
import docking.ComponentProvider;
+import ghidra.framework.main.datatable.ProjectDataActionContext;
+import ghidra.framework.model.*;
public class ProjectDataTreeActionContext extends ProjectDataActionContext {
@@ -52,7 +50,7 @@ public class ProjectDataTreeActionContext extends ProjectDataActionContext {
return selectionPaths;
}
- public DataTree getDataTree() {
+ public DataTree getTree() {
return tree;
}
}
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/ProjectDataTreePanel.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/ProjectDataTreePanel.java
index 1651798827..a3514f5748 100644
--- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/ProjectDataTreePanel.java
+++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/ProjectDataTreePanel.java
@@ -55,33 +55,26 @@ public class ProjectDataTreePanel extends JPanel {
private ChangeManager changeMgr;
private boolean isActiveProject;
- private FrontEndTool tool; // may be null if the panel is inside of the
-
+ // these may be null if the panel is inside of a dialog
+ private FrontEndTool tool;
private FrontEndPlugin plugin;
- // data tree dialog
-
/**
- * Construct an empty panel that is going to be used as the active
- * panel.
- * @param tool front end tool
+ * Construct an empty panel that is going to be used as the active panel
+ * @param plugin front end plugin
*/
public ProjectDataTreePanel(FrontEndPlugin plugin) {
this(null, true, plugin, null);
}
/**
- * Construct a new DataTreePanel.
+ * Constructor
+ *
* @param projectName name of project
- * @param projectData object that provides access to all the user data
- * folders in a project
* @param isActiveProject true if the project is active, and the
* data tree may be modified
- * @param tool front end tool; will be null if the panel is used in a dialog
- * @param actionMgr class to handle enablement of actions; an ActionManager
- * is passed in when several data tree panels all need to use the
- * same ActionManager, e.g., the viewed projects in the front end tool;
- * actionMgr will be null if the panel is used in a dialog
+ * @param plugin front end plugin; will be null if the panel is used in a dialog
+ * @param filter optional filter that is used to hide programs from view
*/
public ProjectDataTreePanel(String projectName, boolean isActiveProject, FrontEndPlugin plugin,
DomainFileFilter filter) {
@@ -211,9 +204,6 @@ public class ProjectDataTreePanel extends JPanel {
}
}
- /**
- * Set the help location for the data tree.
- */
public void setHelpLocation(HelpLocation helpLocation) {
HelpService help = Help.getHelpService();
help.registerHelp(tree, helpLocation);
@@ -228,8 +218,9 @@ public class ProjectDataTreePanel extends JPanel {
}
/**
- * Get the number of selected items in the tree.
- * These could be either DomainFile's or DomainFolder's.
+ * Get the number of selected items in the tree. These could be either files or folders.
+ *
+ * @return the number of selected items in the tree.
*/
public int getSelectedItemCount() {
return tree.getSelectionCount();
@@ -279,47 +270,31 @@ public class ProjectDataTreePanel extends JPanel {
tree.removeGTreeSelectionListener(l);
}
- /**
- * Add a mouse listener to the data tree.
- */
public void addTreeMouseListener(MouseListener l) {
tree.addMouseListener(l);
}
- /**
- * Remove the mouse listener from the data tree.
- */
public void removeTreeMouseListener(MouseListener l) {
tree.removeMouseListener(l);
}
- /**
- * Set the preferred size of the scroll pane that contains the
- * data tree.
- */
public void setPreferredTreePanelSize(Dimension d) {
tree.setPreferredSize(d);
}
- /**
- * Get the project data that this data tree panel is operating on.
- */
public ProjectData getProjectData() {
return projectData;
}
/**
* Notification that the project was renamed; update the root node name
- * and reload the node.
+ * and reload the node
+ * @param newName the new project name
*/
public void projectRenamed(String newName) {
updateProjectName(newName);
}
- /**
- * Notification that panel is being disposed.
- *
- */
public void dispose() {
if (projectData != null) {
projectData.removeDomainFolderChangeListener(changeMgr);
@@ -328,10 +303,12 @@ public class ProjectDataTreePanel extends JPanel {
}
/**
- * Get the data tree node that is selected.
- * @param e mouse event for the popup; may be null if this is being
- * called as a result of the key binding pressed
- * @return null if there is no selection
+ * Get the data tree node that is selected
+ *
+ * @param provider the provider with which to construct the new context
+ * @param e mouse event for the popup; may be null if this is being called as a result of
+ * the key binding pressed
+ * @return the new context; null if there is no selection
*/
public ActionContext getActionContext(ComponentProvider provider, MouseEvent e) {
if (root instanceof NoProjectNode) {
@@ -360,13 +337,13 @@ public class ProjectDataTreePanel extends JPanel {
}
}
- return new ProjectDataTreeActionContext(provider, projectData, selectionPaths,
- domainFolderList, domainFileList, tree, isActiveProject);
+ ProjectDataTreeActionContext context = new ProjectDataTreeActionContext(provider,
+ projectData, selectionPaths, domainFolderList, domainFileList, tree, isActiveProject);
+ boolean isTransient = tool == null; // null for stand-alone dialog, not the project's tree
+ context.setTransient(isTransient);
+ return context;
}
- /**
- * get the data tree for this data tree panel.
- */
public DataTree getDataTree() {
return tree;
}
@@ -380,17 +357,10 @@ public class ProjectDataTreePanel extends JPanel {
tree.setFilterVisible(enabled);
}
- /**
- * Return true if this data tree panel is listening to domain folder
- * changes.
- */
boolean domainFolderListenerAdded() {
return changeMgr != null;
}
- /**
- * Get the folder change listener.
- */
DomainFolderChangeListener getFolderChangeListener() {
return changeMgr;
}
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataCollapseAction.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataCollapseAction.java
index fdec297512..6e60a4ad5b 100644
--- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataCollapseAction.java
+++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataCollapseAction.java
@@ -33,7 +33,7 @@ public class ProjectDataCollapseAction extends ProjectDataTreeContextAction {
@Override
protected void actionPerformed(ProjectDataTreeActionContext context) {
- DataTree tree = context.getDataTree();
+ DataTree tree = context.getTree();
TreePath[] paths = context.getSelectionPaths();
collapse(tree, paths[0]);
}
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataCopyAction.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataCopyAction.java
index 858fb08888..c1207ec325 100644
--- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataCopyAction.java
+++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataCopyAction.java
@@ -40,7 +40,7 @@ public class ProjectDataCopyAction extends ProjectDataCopyCutBaseAction {
protected void actionPerformed(ProjectDataTreeActionContext context) {
TreePath[] paths = adjustSelectionPaths(context.getSelectionPaths());
- DataTreeClipboardUtils.setClipboardContents(context.getDataTree(), paths);
+ DataTreeClipboardUtils.setClipboardContents(context.getTree(), paths);
}
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataCutAction.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataCutAction.java
index 9341248252..ee80774d39 100644
--- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataCutAction.java
+++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataCutAction.java
@@ -40,7 +40,7 @@ public class ProjectDataCutAction extends ProjectDataCopyCutBaseAction {
protected void actionPerformed(ProjectDataTreeActionContext context) {
TreePath[] paths = adjustSelectionPaths(context.getSelectionPaths());
- DataTreeClipboardUtils.setClipboardContents(context.getDataTree(), paths);
+ DataTreeClipboardUtils.setClipboardContents(context.getTree(), paths);
markNodesCut(paths);
}
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataExpandAction.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataExpandAction.java
index 393457277e..576ce289c3 100644
--- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataExpandAction.java
+++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataExpandAction.java
@@ -33,7 +33,7 @@ public class ProjectDataExpandAction extends ProjectDataTreeContextAction {
@Override
protected void actionPerformed(ProjectDataTreeActionContext context) {
- DataTree tree = context.getDataTree();
+ DataTree tree = context.getTree();
TreePath[] paths = context.getSelectionPaths();
expand(tree, paths[0]);
}
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataNewFolderAction.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataNewFolderAction.java
index 2e658cf93d..44d8dddf06 100644
--- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataNewFolderAction.java
+++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataNewFolderAction.java
@@ -41,6 +41,12 @@ public class ProjectDataNewFolderAction extends ProjectDataContextAction {
markHelpUnnecessary();
}
+ @Override
+ protected boolean supportsTransientProjectData() {
+ // we allow the user to create new folders even in transient projects
+ return true;
+ }
+
@Override
protected void actionPerformed(ProjectDataActionContext context) {
createNewFolder(context);
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataPasteAction.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataPasteAction.java
index 9bbaee00c5..5bf29f7245 100644
--- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataPasteAction.java
+++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataPasteAction.java
@@ -44,7 +44,7 @@ public class ProjectDataPasteAction extends ProjectDataCopyCutBaseAction {
GTreeNode node = (GTreeNode) context.getContextObject();
DomainFolderNode destNode = getFolderForNode(node);
- paste(context.getDataTree(), destNode);
+ paste(context.getTree(), destNode);
}
@Override
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataReadOnlyAction.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataReadOnlyAction.java
index b7e8837547..4ca5086dcf 100644
--- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataReadOnlyAction.java
+++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataReadOnlyAction.java
@@ -50,6 +50,10 @@ public class ProjectDataReadOnlyAction extends ProjectDataContextToggleAction {
if (context.getFolderCount() != 0 || context.getFileCount() != 1) {
return false;
}
+ if (ignoreTransientProject(context)) {
+ return false;
+ }
+
DomainFile domainFile = context.getSelectedFiles().get(0);
setSelected(domainFile.isReadOnly());
return true;
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataSelectAction.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataSelectAction.java
index f584babf9d..f3fa36668e 100644
--- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataSelectAction.java
+++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/projectdata/actions/ProjectDataSelectAction.java
@@ -36,7 +36,7 @@ public class ProjectDataSelectAction extends ProjectDataTreeContextAction {
@Override
protected void actionPerformed(ProjectDataTreeActionContext context) {
- DataTree tree = context.getDataTree();
+ DataTree tree = context.getTree();
TreePath[] paths = context.getSelectionPaths();
GTreeNode node = (GTreeNode) paths[0].getLastPathComponent();
selectAllChildren(tree, node);
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/task/gui/GProgressBar.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/task/gui/GProgressBar.java
index 99b316b2e1..29eb284923 100644
--- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/task/gui/GProgressBar.java
+++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/task/gui/GProgressBar.java
@@ -59,12 +59,12 @@ public class GProgressBar extends JPanel {
private Timer updateTimer;
private EmptyBorderButton cancelButton;
- private CancelledListener cancelledListner;
+ private CancelledListener cancelledListener;
- public GProgressBar(CancelledListener cancelledListner, boolean includeTextField,
+ public GProgressBar(CancelledListener cancelledListener, boolean includeTextField,
boolean includeCancelButton, boolean includeAnimatedIcon, float fontSize) {
super(new BorderLayout(5, 1));
- this.cancelledListner = cancelledListner;
+ this.cancelledListener = cancelledListener;
this.fontSize = fontSize;
buildProgressPanel(includeTextField, includeCancelButton, includeAnimatedIcon);
@@ -199,13 +199,13 @@ public class GProgressBar extends JPanel {
}
public void cancel() {
- if (cancelledListner != null) {
- cancelledListner.cancelled();
+ if (cancelledListener != null) {
+ cancelledListener.cancelled();
}
}
public void setCancelledListener(CancelledListener listener) {
- this.cancelledListner = listener;
+ this.cancelledListener = listener;
}
private void buildProgressPanel(boolean includeTextField, boolean includeCancelButton,
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighCompiler.g b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighCompiler.g
index ba0bffac28..7170783b57 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighCompiler.g
+++ b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighCompiler.g
@@ -1473,8 +1473,10 @@ expr_apply returns [Object value]
;
expr_operands returns [VectorSTL value]
+ scope Return;
@init {
$value = new VectorSTL();
+ $Return::noReturn = false;
}
: (e=expr { value.push_back(e); })*
;
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/PcodeDataTypeManager.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/PcodeDataTypeManager.java
index d75023a482..8a8bd055f2 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/PcodeDataTypeManager.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/PcodeDataTypeManager.java
@@ -261,10 +261,7 @@ public class PcodeDataTypeManager {
if (type instanceof Array) {
return buildType(type, size);
}
- if (type instanceof FunctionDefinition) {
- return buildType(type, size);
- }
- if (type.getLength() <= 0) {
+ if (!(type instanceof FunctionDefinition) && type.getLength() <= 0) {
return buildType(type, size);
}
StringBuilder resBuf = new StringBuilder();
@@ -541,7 +538,7 @@ public class PcodeDataTypeManager {
}
resBuf.append(" ACCESS_LEVEL = Set.of(Modifier.PUBLIC);
-
private Reporter log;
private File destDir;
@@ -122,8 +120,7 @@ public class JsonDoclet implements Doclet {
//@formatter:off
ElementFilter.typesIn(docEnv.getIncludedElements())
.stream()
- .filter(el -> el.getModifiers().containsAll(ACCESS_LEVEL))
- .filter(el -> el.getKind().equals(ElementKind.CLASS))
+ .filter(el -> el.getKind().equals(ElementKind.CLASS) || el.getKind().equals(ElementKind.INTERFACE))
.forEach(el -> writeJsonToFile(classToJson(el), el.getQualifiedName()));
//@formatter:on
@@ -211,9 +208,6 @@ public class JsonDoclet implements Doclet {
JSONArray methodArray = new JSONArray();
for (Element el : classElement.getEnclosedElements()) {
- if (!el.getModifiers().containsAll(ACCESS_LEVEL)) {
- continue;
- }
JSONObject obj = new JSONObject();
obj.put("name", el.getSimpleName().toString());
diff --git a/GhidraBuild/Skeleton/data/build.xml b/GhidraBuild/Skeleton/data/build.xml
new file mode 100644
index 0000000000..1e2a6276bc
--- /dev/null
+++ b/GhidraBuild/Skeleton/data/build.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gradleScripts/distribution.gradle b/gradleScripts/distribution.gradle
index 7aaf03b2f4..15260c088c 100644
--- a/gradleScripts/distribution.gradle
+++ b/gradleScripts/distribution.gradle
@@ -134,6 +134,10 @@ task createJsondocs(type: Javadoc, description: 'Generate JSON docs for all proj
it.sourceSets.test.compileClasspath
})
+ // Generate at package level because user may try to get help directly on an object they have
+ // rather than its public interface.
+ options.addBooleanOption("package", true)
+
// Some internal packages are not public and need to be exported.
options.addMultilineStringsOption("-add-exports").setValue(["java.desktop/sun.awt.image=ALL-UNNAMED",
"java.desktop/sun.awt=ALL-UNNAMED",
diff --git a/licenses/FAMFAMFAM_MINI_ICONS_-_Public_Domain.txt b/licenses/FAMFAMFAM_Mini_Icons_-_Public_Domain.txt
similarity index 100%
rename from licenses/FAMFAMFAM_MINI_ICONS_-_Public_Domain.txt
rename to licenses/FAMFAMFAM_Mini_Icons_-_Public_Domain.txt
diff --git a/licenses/certification.manifest b/licenses/certification.manifest
index 94ef6577e7..b11781ed93 100644
--- a/licenses/certification.manifest
+++ b/licenses/certification.manifest
@@ -5,7 +5,8 @@ Christian_Plattner.txt||LICENSE||||END|
Creative_Commons_Attribution_2.5.html||LICENSE||||END|
Crystal_Clear_Icons_-_LGPL_2.1.txt||LICENSE||||END|
FAMFAMFAM_Icons_-_CC_2.5.txt||LICENSE||||END|
-FAMFAMFAM_MINI_ICONS_-_Public_Domain.txt||LICENSE||||END|
+FAMFAMFAM_Mini_Icons_-_Public_Domain.txt||LICENSE||||END|
+FAMFAMFAM Mini Icons - Public Domain.txt||LICENSE||||END|
GPL_2_With_Classpath_Exception.txt||LICENSE||||END|
JDOM_License.txt||LICENSE||||END|
Jython_License.txt||LICENSE||||END|