GP-65 - Error Dialog - updated the error dialog to accumulate errors

while it is open instead of repeatedly showing new dialogs
This commit is contained in:
dragonmacher
2020-08-20 17:37:44 -04:00
parent 4506acddf9
commit fc247aa499
44 changed files with 1784 additions and 1662 deletions
@@ -498,7 +498,7 @@ class AnalyzeAllOpenProgramsTask extends Task {
if (message != null && message.toLowerCase().startsWith("<html>")) {
JEditorPane editorPane = new JEditorPane();
editorPane.setEditorKit(new HTMLEditorKit());
editorPane.setName("MESSAGE-COMPONENT");
editorPane.setName(MESSAGE_COMPONENT_NAME);
editorPane.setText(message);
editorPane.setBackground(new GLabel().getBackground());
@@ -15,6 +15,10 @@
*/
package ghidra.app.plugin.core.datamgr.actions;
import docking.ActionContext;
import docking.action.DockingAction;
import docking.action.MenuData;
import docking.widgets.tree.GTreeState;
import ghidra.app.plugin.core.datamgr.*;
import ghidra.app.plugin.core.datamgr.archive.DataTypeManagerHandler;
import ghidra.app.plugin.core.datamgr.tree.ArchiveNode;
@@ -23,10 +27,6 @@ import ghidra.program.model.data.DataTypeManager;
import ghidra.program.model.data.SourceArchive;
import ghidra.util.HelpLocation;
import ghidra.util.Msg;
import docking.ActionContext;
import docking.action.DockingAction;
import docking.action.MenuData;
import docking.widgets.tree.GTreeState;
public class SyncRefreshAction extends DockingAction {
@@ -92,7 +92,7 @@ public class SyncRefreshAction extends DockingAction {
getClass(),
plugin.getTool().getToolFrame(),
"Refresh Completed",
"Sync indicators refresh for " + dtm.getName() + " to archive \"" +
"Sync indicators have been refreshed between " + dtm.getName() + " and archive \"" +
sourceArchive.getName() + "\".");
tree.restoreTreeState(treeState);
@@ -24,7 +24,6 @@ import java.util.regex.Pattern;
import javax.swing.ImageIcon;
import docking.*;
import docking.action.DockingAction;
import docking.action.builder.ActionBuilder;
import docking.tool.ToolConstants;
import docking.widgets.fieldpanel.support.Highlight;
@@ -96,8 +95,6 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
private static final String DESCRIPTION = "Search program text for string";
private final static int DEFAULT_SEARCH_LIMIT = 500;
private final static Highlight[] NO_HIGHLIGHTS = new Highlight[0];
private DockingAction searchAction;
private DockingAction searchAgainAction;
private boolean waitingForSearchAll;
private SearchTextDialog searchDialog;
@@ -379,7 +376,7 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
private void createActions() {
String subGroup = getClass().getName();
searchAction = new ActionBuilder("Search Text", getName())
new ActionBuilder("Search Text", getName())
.menuPath("&Search", "Program &Text...")
.menuGroup("search", subGroup)
.keyBinding("ctrl shift E")
@@ -393,7 +390,7 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
})
.buildAndInstall(tool);
searchAgainAction = new ActionBuilder("Repeat Text Search", getName())
new ActionBuilder("Repeat Text Search", getName())
.menuPath("&Search", "Repeat Text Search")
.menuGroup("search", subGroup)
.keyBinding("ctrl shift F3")
@@ -145,7 +145,7 @@ public abstract class AbstractMergeTest extends AbstractGhidraHeadedIntegrationT
List<Dialog> modals =
WindowUtilities.getOpenModalDialogsFor(mergeMgr.getMergeTool().getToolFrame());
Msg.debug(this, "Open modal dialog: ");
Msg.debug(this, "Open modal dialogs: ");
for (Dialog dialog : modals) {
capture(dialog);
}
@@ -25,7 +25,6 @@ import ghidra.program.model.data.*;
import ghidra.program.model.data.Enum;
import ghidra.util.exception.DuplicateNameException;
import ghidra.util.task.TaskMonitor;
import ghidra.util.task.TaskMonitorAdapter;
/**
* More data type merge tests.
@@ -46,7 +45,7 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
try {
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
dtm.remove(s, TaskMonitorAdapter.DUMMY);
dtm.remove(s, TaskMonitor.DUMMY);
// 2 components should get removed from CoolUnion
commit = true;
}
@@ -119,7 +118,7 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
try {
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
dtm.remove(s, TaskMonitorAdapter.DUMMY);
dtm.remove(s, TaskMonitor.DUMMY);
// 2 components should get removed from CoolUnion
commit = true;
}
@@ -192,7 +191,7 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
try {
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
dtm.remove(s, TaskMonitorAdapter.DUMMY);
dtm.remove(s, TaskMonitor.DUMMY);
// 2 components should get removed from CoolUnion
commit = true;
}
@@ -573,7 +572,7 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
DataType dt =
dtm.getDataType(new CategoryPath("/Category1/Category2"), "Structure_1");
try {
dtm.remove(dt, TaskMonitorAdapter.DUMMY);
dtm.remove(dt, TaskMonitor.DUMMY);
commit = true;
}
finally {
@@ -649,7 +648,7 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
DataType dt =
dtm.getDataType(new CategoryPath("/Category1/Category2"), "Structure_1");
try {
dtm.remove(dt, TaskMonitorAdapter.DUMMY);
dtm.remove(dt, TaskMonitor.DUMMY);
// causes Bar to be marked as changed
commit = true;
}
@@ -724,7 +723,7 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
DataType dt =
dtm.getDataType(new CategoryPath("/Category1/Category2"), "Structure_1");
try {
dtm.remove(dt, TaskMonitorAdapter.DUMMY);
dtm.remove(dt, TaskMonitor.DUMMY);
// causes Bar to be marked as changed
commit = true;
}
@@ -801,7 +800,7 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
Structure ms = (Structure) dtm.getDataType(new CategoryPath("/Category1/Category2"),
"MyStruct");
try {
dtm.remove(dt, TaskMonitorAdapter.DUMMY);
dtm.remove(dt, TaskMonitor.DUMMY);
Structure s1 = new StructureDataType(
new CategoryPath("/Category1/Category2/Category5"), "s1", 0);
s1.add(ms);
@@ -916,7 +915,7 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
int transactionID = program.startTransaction("test");
DataType dt = dtm.getDataType(new CategoryPath("/Category1/Category2"), "BF");
try {
dtm.remove(dt, TaskMonitorAdapter.DUMMY);
dtm.remove(dt, TaskMonitor.DUMMY);
}
finally {
program.endTransaction(transactionID, true);
@@ -1260,7 +1259,7 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
try {
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
dtm.remove(s, TaskMonitorAdapter.DUMMY);
dtm.remove(s, TaskMonitor.DUMMY);
// 2 components should get removed from CoolUnion
commit = true;
}
@@ -1353,7 +1352,7 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
try {
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
dtm.remove(s, TaskMonitorAdapter.DUMMY);
dtm.remove(s, TaskMonitor.DUMMY);
// 2 components should get removed from CoolUnion
commit = true;
}
@@ -1436,10 +1435,10 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
try {
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
dtm.remove(s, TaskMonitorAdapter.DUMMY);
dtm.remove(s, TaskMonitor.DUMMY);
DataType dt =
dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
dtm.remove(dt, TaskMonitorAdapter.DUMMY);
dtm.remove(dt, TaskMonitor.DUMMY);
commit = true;
}
finally {
@@ -1524,10 +1523,10 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
try {
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
dtm.remove(s, TaskMonitorAdapter.DUMMY);
dtm.remove(s, TaskMonitor.DUMMY);
DataType dt =
dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
dtm.remove(dt, TaskMonitorAdapter.DUMMY);
dtm.remove(dt, TaskMonitor.DUMMY);
commit = true;
}
finally {
@@ -1613,10 +1612,10 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
try {
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
dtm.remove(s, TaskMonitorAdapter.DUMMY);
dtm.remove(s, TaskMonitor.DUMMY);
DataType dt =
dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
dtm.remove(dt, TaskMonitorAdapter.DUMMY);
dtm.remove(dt, TaskMonitor.DUMMY);
commit = true;
}
finally {
@@ -1701,10 +1700,10 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
try {
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
dtm.remove(s, TaskMonitorAdapter.DUMMY);
dtm.remove(s, TaskMonitor.DUMMY);
DataType dt =
dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
dtm.remove(dt, TaskMonitorAdapter.DUMMY);
dtm.remove(dt, TaskMonitor.DUMMY);
commit = true;
}
finally {
@@ -1795,10 +1794,10 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
try {
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
dtm.remove(s, TaskMonitorAdapter.DUMMY);
dtm.remove(s, TaskMonitor.DUMMY);
DataType dt =
dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
dtm.remove(dt, TaskMonitorAdapter.DUMMY);
dtm.remove(dt, TaskMonitor.DUMMY);
commit = true;
}
finally {
@@ -1897,10 +1896,10 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
try {
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
dtm.remove(s, TaskMonitorAdapter.DUMMY);
dtm.remove(s, TaskMonitor.DUMMY);
DataType dt =
dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
dtm.remove(dt, TaskMonitorAdapter.DUMMY);
dtm.remove(dt, TaskMonitor.DUMMY);
commit = true;
}
finally {
@@ -755,8 +755,4 @@ public class StructureEditorProviderTest extends AbstractStructureEditorTest {
assertEquals("325", model.getLengthAsString());
}
private void runSwingLater(Runnable r) {
runSwing(r, false);
}
}
@@ -15,8 +15,7 @@
*/
package ghidra.app.plugin.core.datamgr.editor;
import static ghidra.app.plugin.core.datamgr.editor.EnumTableModel.NAME_COL;
import static ghidra.app.plugin.core.datamgr.editor.EnumTableModel.VALUE_COL;
import static ghidra.app.plugin.core.datamgr.editor.EnumTableModel.*;
import static org.junit.Assert.*;
import java.awt.*;
@@ -42,7 +41,7 @@ import ghidra.program.model.data.Enum;
import ghidra.program.model.listing.Program;
import ghidra.program.model.symbol.EquateTable;
import ghidra.test.*;
import ghidra.util.task.TaskMonitorAdapter;
import ghidra.util.task.TaskMonitor;
/**
* Tests for editing an Enumerated data type.
@@ -54,10 +53,6 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
private TestEnv env;
private DataTypeManagerPlugin plugin;
public EnumEditor1Test() {
super();
}
@Before
public void setUp() throws Exception {
env = new TestEnv();
@@ -80,8 +75,10 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
@Test
public void testEnumFields() throws Exception {
Category c = program.getListing().getDataTypeManager().getCategory(
new CategoryPath(CategoryPath.ROOT, "Category1"));
Category c = program.getListing()
.getDataTypeManager()
.getCategory(
new CategoryPath(CategoryPath.ROOT, "Category1"));
Enum enumm = createEnum(c, "TestEnum", 1);
edit(enumm);
@@ -133,8 +130,10 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
@Test
public void testEnumSize1() throws Exception {
Category category = program.getListing().getDataTypeManager().getCategory(
new CategoryPath(CategoryPath.ROOT, "Category1"));
Category category = program.getListing()
.getDataTypeManager()
.getCategory(
new CategoryPath(CategoryPath.ROOT, "Category1"));
Enum enumm = createEnum(category, "TestEnum", 1);
edit(enumm);
@@ -183,8 +182,10 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
@Test
public void testEnumSize1BadInput() throws Exception {
// test entering too large a value
Category category = program.getListing().getDataTypeManager().getCategory(
new CategoryPath(CategoryPath.ROOT, "Category1"));
Category category = program.getListing()
.getDataTypeManager()
.getCategory(
new CategoryPath(CategoryPath.ROOT, "Category1"));
Enum enumm = createEnum(category, "TestEnum", 1);
edit(enumm);
@@ -225,8 +226,10 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
@Test
public void testEnumSize4BadInput() throws Exception {
Category category = program.getListing().getDataTypeManager().getCategory(
new CategoryPath(CategoryPath.ROOT, "Category1"));
Category category = program.getListing()
.getDataTypeManager()
.getCategory(
new CategoryPath(CategoryPath.ROOT, "Category1"));
Enum enumm = createEnum(category, "MyTestEnum", 4);
edit(enumm);
@@ -275,8 +278,10 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
@Test
public void testBadInputForValue() throws Exception {
Category cat = program.getListing().getDataTypeManager().getCategory(
new CategoryPath(CategoryPath.ROOT, "Category1"));
Category cat = program.getListing()
.getDataTypeManager()
.getCategory(
new CategoryPath(CategoryPath.ROOT, "Category1"));
Enum enumm = createEnum(cat, "TestEnum", 1);
edit(enumm);
@@ -303,8 +308,10 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
@Test
public void testEditExistingEnum1() throws Exception {
Category cat = program.getListing().getDataTypeManager().getCategory(
new CategoryPath(CategoryPath.ROOT, "Category1"));
Category cat = program.getListing()
.getDataTypeManager()
.getCategory(
new CategoryPath(CategoryPath.ROOT, "Category1"));
final Enum enumm = new EnumDataType("Colors", 1);
enumm.add("Red", 0);
enumm.add("Green", 1);
@@ -366,8 +373,10 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
@Test
public void testValueForNewEntry() throws Exception {
Category cat = program.getListing().getDataTypeManager().getCategory(
new CategoryPath(CategoryPath.ROOT, "Category1"));
Category cat = program.getListing()
.getDataTypeManager()
.getCategory(
new CategoryPath(CategoryPath.ROOT, "Category1"));
final Enum enumm = new EnumDataType("Colors", 1);
enumm.add("Red", 0x10);
enumm.add("Green", 0x20);
@@ -521,10 +530,7 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
removeCategory(enummDt);
OptionDialog dialog =
waitForDialogComponent(null, OptionDialog.class, DEFAULT_WINDOW_TIMEOUT);
assertNotNull(dialog);
pressButtonByText(dialog.getComponent(), "OK");
close(waitForErrorDialog());
}
@Test
@@ -564,10 +570,7 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
replaceDataType(enummDt, newEnummDt);
OptionDialog dialog =
waitForDialogComponent(null, OptionDialog.class, DEFAULT_WINDOW_TIMEOUT);
assertNotNull(dialog);
pressButtonByText(dialog.getComponent(), "OK");
close(waitForErrorDialog());
}
@Test
@@ -612,15 +615,12 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
DataTypeManager dtm = program.getDataTypeManager();
int transactionID = program.startTransaction("Test");
dtm.remove(enummDt, TaskMonitorAdapter.DUMMY_MONITOR);
dtm.remove(enummDt, TaskMonitor.DUMMY);
program.endTransaction(transactionID, true);
program.flushEvents();
waitForSwing();
OptionDialog optionDialog =
waitForDialogComponent(null, OptionDialog.class, DEFAULT_WINDOW_TIMEOUT);
assertNotNull("Did not get informed of deleted enum", optionDialog);
pressButtonByText(optionDialog.getComponent(), "OK");
close(waitForErrorDialog());
}
@Test
@@ -762,8 +762,10 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
@Test
public void testChangeEnumSizeAndInStructure() throws Exception {
Category category = program.getListing().getDataTypeManager().getCategory(
new CategoryPath(CategoryPath.ROOT, "Category1"));
Category category = program.getListing()
.getDataTypeManager()
.getCategory(
new CategoryPath(CategoryPath.ROOT, "Category1"));
Enum enumm = createEnum(category, "EnumX", 2);
int transactionID = program.startTransaction("Test");
@@ -803,7 +805,7 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
assertEquals(intValue, 2);
runSwing(() -> {
sizeComboBox.setSelectedItem(new Integer(4));
sizeComboBox.setSelectedItem(4);
});
apply();
@@ -831,8 +833,10 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
@Test
public void testChangeEnumDescriptionEtcAndInStructure() throws Exception {
Category category = program.getListing().getDataTypeManager().getCategory(
new CategoryPath(CategoryPath.ROOT, "Category1"));
Category category = program.getListing()
.getDataTypeManager()
.getCategory(
new CategoryPath(CategoryPath.ROOT, "Category1"));
Enum enumm = createEnum(category, "EnumX", 2);
int transactionID = program.startTransaction("Test");
@@ -887,7 +891,7 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
runSwing(() -> {
nameField.setText("EnumY");
descField.setText("XYZ");
sizeComboBox.setSelectedItem(new Integer(4));
sizeComboBox.setSelectedItem(4);
table.editCellAt(1, NAME_COL);
@@ -1026,7 +1030,7 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
try {
Category newCategory = dtm.createCategory(new CategoryPath("/Test/Category"));
category = dtm.getCategory(enummDt.getCategoryPath());
newCategory.moveCategory(category, TaskMonitorAdapter.DUMMY_MONITOR);
newCategory.moveCategory(category, TaskMonitor.DUMMY);
}
finally {
program.endTransaction(txID, true);
@@ -1046,7 +1050,7 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
Category category = dtm.getCategory(enummDt.getCategoryPath());
Category parentCategory = category.getParent();
assertTrue("Did not remove category", parentCategory.removeCategory(category.getName(),
TaskMonitorAdapter.DUMMY_MONITOR));
TaskMonitor.DUMMY));
}
finally {
program.endTransaction(txID, true);
@@ -1138,8 +1142,10 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
}
private Enum createRedGreenBlueEnum() {
Category cat = program.getListing().getDataTypeManager().getCategory(
new CategoryPath(CategoryPath.ROOT, "Category1"));
Category cat = program.getListing()
.getDataTypeManager()
.getCategory(
new CategoryPath(CategoryPath.ROOT, "Category1"));
final Enum enumm = new EnumDataType("Colors", 1);
enumm.add("Red", 0);
enumm.add("Green", 1);
@@ -1274,7 +1280,7 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
editValueInTable(0, "2");
// This IS the warning dialog
OptionDialog dialog = env.waitForDialogComponent(OptionDialog.class, 1000);
OptionDialog dialog = waitForDialogComponent(OptionDialog.class);
pressButtonByText(dialog, alsoRemove ? "Save and remove" : "Save");
waitForTasks();
@@ -17,14 +17,13 @@ package ghidra.app.plugin.core.function;
import static org.junit.Assert.*;
import javax.swing.JDialog;
import javax.swing.JTextField;
import org.junit.*;
import docking.AbstractErrDialog;
import docking.ActionContext;
import docking.action.DockingActionIf;
import docking.widgets.MultiLineLabel;
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
import ghidra.app.util.viewer.field.FunctionSignatureFieldFactory;
import ghidra.framework.plugintool.PluginTool;
@@ -70,30 +69,25 @@ public class ThunkReferenceAddressDialogTest extends AbstractGhidraHeadedIntegra
@Test
public void testSetThunkedFunction() throws Exception {
ThunkReferenceAddressDialog dialog = popupSetThunkDialog(addr(0x100194b));
ThunkReferenceAddressDialog dialog = showThunkDialog(addr(0x100194b));
JTextField textEntryField = findComponent(dialog, JTextField.class);
assertNotNull(textEntryField);
// Invalid Entry
setText(textEntryField, "bar");
pressButtonByText(dialog, "OK", false);
JDialog errorDialog = waitForJDialog("Invalid Entry Error");
MultiLineLabel errorLabel =
(MultiLineLabel) findComponentByName(errorDialog, "MESSAGE-COMPONENT");
assertNotNull(errorLabel);
assertEquals("Invalid thunk reference address or name specified: bar",
errorLabel.getLabel());
AbstractErrDialog errorDialog = waitForErrorDialog();
assertEquals("Invalid Entry Error", errorDialog.getTitle());
assertEquals(
"Invalid thunk reference address or name specified: bar",
errorDialog.getMessage());
pressButtonByText(errorDialog, "OK");
// Try again
setText(textEntryField, "IsTextUnicode");
pressButtonByText(dialog, "OK");
waitForBusyTool(tool);
@@ -110,7 +104,7 @@ public class ThunkReferenceAddressDialogTest extends AbstractGhidraHeadedIntegra
@Test
public void testSetThunkedFunctionWithNamespace() throws Exception {
ThunkReferenceAddressDialog dialog = popupSetThunkDialog(addr(0x100194b));
ThunkReferenceAddressDialog dialog = showThunkDialog(addr(0x100194b));
JTextField textEntryField = findComponent(dialog, JTextField.class);
assertNotNull(textEntryField);
@@ -130,19 +124,10 @@ public class ThunkReferenceAddressDialogTest extends AbstractGhidraHeadedIntegra
}
// @Test
// public void testClearThunkedFunction() throws Exception {
//
// testSetThunkedFunctionWithNamespace(); // sets thunk
//
// revertThunk.actionPerformed(context);
//
// }
@Test
public void testSetThunkedFunctionWithOriginalName() throws Exception {
ThunkReferenceAddressDialog dialog = popupSetThunkDialog(addr(0x100194b));
ThunkReferenceAddressDialog dialog = showThunkDialog(addr(0x100194b));
JTextField textEntryField = findComponent(dialog, JTextField.class);
assertNotNull(textEntryField);
@@ -166,54 +151,38 @@ public class ThunkReferenceAddressDialogTest extends AbstractGhidraHeadedIntegra
@Test
public void testSetThunkedFunctionWithOriginalNameConflict() throws Exception {
int txId = program.startTransaction("add label");
try {
tx(program, () -> {
program.getSymbolTable().createLabel(addr(0x1001900), "_Zxyz", SourceType.USER_DEFINED);
}
finally {
program.endTransaction(txId, true);
}
ThunkReferenceAddressDialog dialog = popupSetThunkDialog(addr(0x100194b));
});
ThunkReferenceAddressDialog dialog = showThunkDialog(addr(0x100194b));
JTextField textEntryField = findComponent(dialog, JTextField.class);
assertNotNull(textEntryField);
// Multiple Symbols
setText(textEntryField, "_Zxyz");
pressButtonByText(dialog, "OK", false);
JDialog errorDialog = waitForJDialog("Ambiguous Symbol Name");
MultiLineLabel errorLabel =
(MultiLineLabel) findComponentByName(errorDialog, "MESSAGE-COMPONENT");
assertNotNull(errorLabel);
AbstractErrDialog errorDialog = waitForErrorDialog();
assertEquals("Ambiguous Symbol Name", errorDialog.getTitle());
assertEquals(
"Specified symbol is ambiguous. Try full namespace name, mangled name or address.",
errorLabel.getLabel());
errorDialog.getMessage());
pressButtonByText(errorDialog, "OK");
waitForBusyTool(tool);
Function f = program.getFunctionManager().getFunctionAt(addr(0x100194b));
assertFalse(f.isThunk());
setText(textEntryField, "LibFoo::xyz");
pressButtonByText(dialog, "OK", false);
waitForBusyTool(tool);
Function thunkedFunction = f.getThunkedFunction(false);
assertNotNull(thunkedFunction);
assertTrue(thunkedFunction.isExternal());
assertEquals("LibFoo::xyz", thunkedFunction.getName(true));
}
private ThunkReferenceAddressDialog popupSetThunkDialog(Address address) {
private ThunkReferenceAddressDialog showThunkDialog(Address address) {
codeBrowserPlugin.goToField(address, FunctionSignatureFieldFactory.FIELD_NAME, 0, 0);
waitForBusyTool(tool);
@@ -20,11 +20,13 @@ import static org.junit.Assert.*;
import java.awt.Component;
import java.awt.Container;
import javax.swing.*;
import javax.swing.JButton;
import javax.swing.JTable;
import javax.swing.table.TableModel;
import org.junit.*;
import docking.AbstractErrDialog;
import docking.action.DockingActionIf;
import docking.widgets.MultiLineLabel;
import docking.widgets.OptionDialog;
@@ -38,7 +40,7 @@ import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.Memory;
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
import ghidra.test.TestEnv;
import ghidra.util.task.TaskMonitorAdapter;
import ghidra.util.task.TaskMonitor;
/**
* Tests for merging memory blocks.
@@ -86,25 +88,22 @@ public class MemoryMapProvider4Test extends AbstractGhidraHeadedIntegrationTest
@After
public void tearDown() throws Exception {
env.release(program);
env.dispose();
}
@Test
public void testMergeBlocks() throws Exception {
// create 4 blocks: 0-0f, 10-1f, 20-20f, 40-4f.
int transactionID = program.startTransaction("test");
memory.createInitializedBlock("block1", getAddr(0), 0x10, (byte) 0,
TaskMonitorAdapter.DUMMY_MONITOR, false);
memory.createInitializedBlock("block2", getAddr(0x10), 0x10, (byte) 0,
TaskMonitorAdapter.DUMMY_MONITOR, false);
memory.createInitializedBlock("block3", getAddr(0x20), 0x10, (byte) 0,
TaskMonitorAdapter.DUMMY_MONITOR, false);
memory.createInitializedBlock("block4", getAddr(0x40), 0x10, (byte) 0,
TaskMonitorAdapter.DUMMY_MONITOR, false);
program.endTransaction(transactionID, true);
program.flushEvents();
waitForPostedSwingRunnables();
tx(program, () -> {
memory.createInitializedBlock("block1", getAddr(0), 0x10, (byte) 0,
TaskMonitor.DUMMY, false);
memory.createInitializedBlock("block2", getAddr(0x10), 0x10, (byte) 0,
TaskMonitor.DUMMY, false);
memory.createInitializedBlock("block3", getAddr(0x20), 0x10, (byte) 0,
TaskMonitor.DUMMY, false);
memory.createInitializedBlock("block4", getAddr(0x40), 0x10, (byte) 0,
TaskMonitor.DUMMY, false);
});
assertEquals("0000004f", model.getValueAt(3, MemoryMapModel.END));
// select rows 0 through 3
@@ -112,7 +111,7 @@ public class MemoryMapProvider4Test extends AbstractGhidraHeadedIntegrationTest
DockingActionIf action = getAction(plugin, "Merge Blocks");
assertTrue(action.isEnabled());
performAction(action, false);
waitForPostedSwingRunnables();
waitForSwing();
assertEquals("block1", model.getValueAt(0, MemoryMapModel.NAME));
assertEquals("00000000", model.getValueAt(0, MemoryMapModel.START));
@@ -127,18 +126,17 @@ public class MemoryMapProvider4Test extends AbstractGhidraHeadedIntegrationTest
@Test
public void testMergeBlocksDisjoint() throws Exception {
// create 4 blocks: 0-0f, 10-1f, 20-20f, 40-4f.
int transactionID = program.startTransaction("test");
memory.createInitializedBlock("block1", getAddr(0), 0x10, (byte) 0,
TaskMonitorAdapter.DUMMY_MONITOR, false);
memory.createInitializedBlock("block2", getAddr(0x10), 0x10, (byte) 0,
TaskMonitorAdapter.DUMMY_MONITOR, false);
memory.createInitializedBlock("block3", getAddr(0x20), 0x10, (byte) 0,
TaskMonitorAdapter.DUMMY_MONITOR, false);
memory.createInitializedBlock("block4", getAddr(0x40), 0x10, (byte) 0,
TaskMonitorAdapter.DUMMY_MONITOR, false);
program.endTransaction(transactionID, true);
program.flushEvents();
waitForPostedSwingRunnables();
tx(program, () -> {
memory.createInitializedBlock("block1", getAddr(0), 0x10, (byte) 0,
TaskMonitor.DUMMY, false);
memory.createInitializedBlock("block2", getAddr(0x10), 0x10, (byte) 0,
TaskMonitor.DUMMY, false);
memory.createInitializedBlock("block3", getAddr(0x20), 0x10, (byte) 0,
TaskMonitor.DUMMY, false);
memory.createInitializedBlock("block4", getAddr(0x40), 0x10, (byte) 0,
TaskMonitor.DUMMY, false);
});
assertEquals("block1", model.getValueAt(0, MemoryMapModel.NAME));
assertEquals("block2", model.getValueAt(1, MemoryMapModel.NAME));
@@ -153,26 +151,20 @@ public class MemoryMapProvider4Test extends AbstractGhidraHeadedIntegrationTest
DockingActionIf action = getAction(plugin, "Merge Blocks");
assertTrue(action.isEnabled());
performAction(action, false);
waitForPostedSwingRunnables();
final OptionDialog d =
waitForDialogComponent(tool.getToolFrame(), OptionDialog.class, 2000);
assertNotNull(d);
assertEquals("Merge Blocks Failed", d.getTitle());
assertEquals("Can't merge blocks because they are not contiguous",
findMessage(d.getComponent()));
AbstractErrDialog d = waitForErrorDialog();
runSwing(() -> d.close());
assertEquals("Merge Blocks Failed", d.getTitle());
assertEquals("Can't merge blocks because they are not contiguous", d.getMessage());
close(d);
}
@Test
public void testMergeBlocksFarApart() throws Exception {
int transactionID = program.startTransaction("test");
memory.createInitializedBlock("block1", getAddr(0), 0x50, (byte) 0,
TaskMonitorAdapter.DUMMY_MONITOR, false);
program.endTransaction(transactionID, true);
program.flushEvents();
waitForPostedSwingRunnables();
tx(program, () -> {
memory.createInitializedBlock("block1", getAddr(0), 0x50, (byte) 0,
TaskMonitor.DUMMY, false);
});
// select rows 0 and 1
table.setRowSelectionInterval(0, 1);
@@ -180,20 +172,19 @@ public class MemoryMapProvider4Test extends AbstractGhidraHeadedIntegrationTest
DockingActionIf action = getAction(plugin, "Merge Blocks");
assertTrue(action.isEnabled());
performAction(action, false);
waitForPostedSwingRunnables();
OptionDialog d = waitForDialogComponent(tool.getToolFrame(), OptionDialog.class, 2000);
assertNotNull(d);
waitForSwing();
OptionDialog d = waitForDialogComponent(OptionDialog.class);
assertEquals("Merge Memory Blocks", d.getTitle());
String message = findMessage(d.getComponent());
assertTrue(
message.startsWith("Merging these blocks will create 16387K extra bytes in memory"));
final JButton b = findButton(d.getComponent(), "Merge Blocks");
JButton b = findButton(d.getComponent(), "Merge Blocks");
assertNotNull(b);
SwingUtilities.invokeAndWait(() -> b.getActionListeners()[0].actionPerformed(null));
runSwing(() -> b.getActionListeners()[0].actionPerformed(null));
waitForPostedSwingRunnables();
waitForSwing();
assertEquals("block1", model.getValueAt(0, MemoryMapModel.NAME));
assertEquals("00000000", model.getValueAt(0, MemoryMapModel.START));
assertEquals("010075ff", model.getValueAt(0, MemoryMapModel.END));
@@ -217,10 +208,10 @@ public class MemoryMapProvider4Test extends AbstractGhidraHeadedIntegrationTest
int transactionID = program.startTransaction("test");
memory.createInitializedBlock("block1", getAddr(0), 0x50, (byte) 0,
TaskMonitorAdapter.DUMMY_MONITOR, false);
TaskMonitor.DUMMY, false);
program.endTransaction(transactionID, true);
program.flushEvents();
waitForPostedSwingRunnables();
waitForSwing();
// select rows 0 and 1
table.setRowSelectionInterval(0, 1);
@@ -228,24 +219,21 @@ public class MemoryMapProvider4Test extends AbstractGhidraHeadedIntegrationTest
DockingActionIf action = getAction(plugin, "Merge Blocks");
assertTrue(action.isEnabled());
performAction(action, false);
waitForPostedSwingRunnables();
OptionDialog d = waitForDialogComponent(tool.getToolFrame(), OptionDialog.class, 2000);
assertNotNull(d);
OptionDialog d = waitForDialogComponent(OptionDialog.class);
assertEquals("Merge Memory Blocks", d.getTitle());
assertTrue(findMessage(d.getComponent()).startsWith(
"Merging these blocks will create 16387K extra bytes in memory"));
final JButton b = findButton(d.getComponent(), "Cancel");
JButton b = findButton(d.getComponent(), "Cancel");
assertNotNull(b);
SwingUtilities.invokeAndWait(() -> b.getActionListeners()[0].actionPerformed(null));
runSwing(() -> b.getActionListeners()[0].actionPerformed(null));
assertEquals("0000004f", model.getValueAt(0, MemoryMapModel.END));
}
private void showProvider() {
DockingActionIf action = getAction(plugin, "Memory Map");
performAction(action, true);
waitForPostedSwingRunnables();
waitForSwing();
provider = plugin.getMemoryMapProvider();
table = provider.getTable();
model = table.getModel();
@@ -28,11 +28,10 @@ import javax.swing.*;
import org.junit.*;
import docking.AbstractErrDialog;
import docking.ActionContext;
import docking.action.DockingActionIf;
import docking.tool.ToolConstants;
import docking.widgets.MultiLineLabel;
import docking.widgets.OptionDialog;
import docking.widgets.table.GTable;
import docking.widgets.table.threaded.GThreadedTablePanel;
import ghidra.app.events.ProgramSelectionPluginEvent;
@@ -954,12 +953,9 @@ public class SearchTextPlugin1Test extends AbstractGhidraHeadedIntegrationTest {
}
private void closeMaxSearchResultsDialog() throws Exception {
final OptionDialog d = waitForDialogComponent(OptionDialog.class);
assertNotNull(d);
String msg = findMessage(d.getComponent());
assertNotNull(msg);
assertTrue(msg.indexOf("Stopped search") >= 0);
runSwing(() -> d.close());
AbstractErrDialog d = waitForErrorDialog();
assertTrue(d.getMessage().contains("Stopped search"));
close(d);
waitForSwing();
}
@@ -1071,22 +1067,6 @@ public class SearchTextPlugin1Test extends AbstractGhidraHeadedIntegrationTest {
return null;
}
private String findMessage(Container container) {
Component[] c = container.getComponents();
for (Component element : c) {
if (element instanceof MultiLineLabel) {
return ((MultiLineLabel) element).getLabel();
}
if (element instanceof Container) {
String str = findMessage((Container) element);
if (str != null) {
return str;
}
}
}
return null;
}
private SearchTextDialog getDialog() throws Exception {
runSwing(() -> searchAction.actionPerformed(provider.getActionContext(null)));
return plugin.getSearchDialog();
@@ -15,7 +15,7 @@
*/
package ghidra.app.plugin.core.string;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import java.nio.charset.StandardCharsets;
@@ -83,7 +83,7 @@ public class StringTableProviderTest extends AbstractGhidraHeadedIntegrationTest
CodeViewerProvider cbProvider = cb.getProvider();
SwingUtilities.invokeLater(
() -> searchAction.actionPerformed(cbProvider.getActionContext(null)));
waitForPostedSwingRunnables();
waitForSwing();
return getDialogComponent(SearchStringDialog.class);
}
@@ -317,7 +317,7 @@ public class StringTableProviderTest extends AbstractGhidraHeadedIntegrationTest
selectRows(address); // string abcefg is here
performAction(makeStringAction, false);
waitForPostedSwingRunnables();
waitForSwing();
OptionDialog dialogProvider = getDialogComponent(OptionDialog.class);
assertNotNull(dialogProvider);
@@ -435,13 +435,9 @@ public class StringTableProviderTest extends AbstractGhidraHeadedIntegrationTest
}
private void createDataAt(Address addr) throws Exception {
int id = program.startTransaction("test");
try {
tx(program, () -> {
program.getListing().createData(addr, new ByteDataType());
}
finally {
program.endTransaction(id, true);
}
});
}
private void setCheckbox(final JCheckBox checkbox, final boolean selected) {
@@ -527,15 +523,6 @@ public class StringTableProviderTest extends AbstractGhidraHeadedIntegrationTest
}
// protected void waitForTable() throws Exception {
// int nWaits = 0;
// while (model.isBusy() && nWaits++ < 500) {
// Thread.sleep(50);
// }
//
// assertTrue("Timed-out waiting for table model to update.", nWaits < 500);
// }
private void toggleDefinedStateButtons(final boolean defined, final boolean undefined,
final boolean partial, final boolean conflicting) {
runSwing(() -> {
@@ -24,9 +24,9 @@ import javax.swing.*;
import org.junit.After;
import org.junit.Before;
import docking.AbstractErrDialog;
import docking.action.DockingActionIf;
import docking.test.AbstractDockingTest;
import docking.widgets.OptionDialog;
import docking.widgets.combobox.GhidraComboBox;
import docking.widgets.tree.GTree;
import docking.widgets.tree.GTreeNode;
@@ -55,16 +55,17 @@ import ghidra.test.AbstractGhidraHeadedIntegrationTest;
import ghidra.test.TestEnv;
import ghidra.util.SystemUtilities;
import ghidra.util.exception.*;
import ghidra.util.task.TaskMonitorAdapter;
import ghidra.util.task.TaskMonitor;
/**
* Tests for the symbol tree plugin.
*/
public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhidraHeadedIntegrationTest {
public abstract class AbstractSymbolTreePluginExternalsTest
extends AbstractGhidraHeadedIntegrationTest {
protected static final String GZF_NAME = "WinHelloCPP.exe";
protected static final String PROGRAM_NAME = "WinHelloCPP";
protected static final String EXTERNAL_PROGRAM_PATHNAME = "/" + PROGRAM_NAME;
protected static String GZF_NAME = "WinHelloCPP.exe";
protected static String PROGRAM_NAME = "WinHelloCPP";
protected static String EXTERNAL_PROGRAM_PATHNAME = "/" + PROGRAM_NAME;
protected TestEnv env;
protected PluginTool tool;
@@ -107,9 +108,6 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
env.showTool();
}
/*
* @see TestCase#tearDown()
*/
@After
public void tearDown() throws Exception {
closeProgram();
@@ -120,10 +118,10 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
throws Exception {
selectExternalLocation(libraryName, name);
performAction(editExternalLocationAction, util.getProvider(), false);
waitForPostedSwingRunnables();
waitForSwing();
EditExternalLocationDialog createDialog = AbstractDockingTest.waitForDialogComponent(
plugin.getTool().getToolFrame(), EditExternalLocationDialog.class, 2000);
EditExternalLocationDialog.class);
waitForBusyTool(tool);
return createDialog;
}
@@ -151,11 +149,7 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
}
}
//==================================================================================================
// Private Methods
//==================================================================================================
protected void changeToFunction(final EditExternalLocationDialog createDialog,
protected void changeToFunction(EditExternalLocationDialog createDialog,
boolean isFunction) {
EditExternalLocationPanel extLocPanel = findComponent(
createDialog.getComponent().getRootPane(), EditExternalLocationPanel.class);
@@ -163,8 +157,8 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
functionCheckBox.setSelected(isFunction);
}
protected ExternalLocation setupExternalLocation(final String library, final String label,
final Address address, final SourceType sourceType, boolean isFunction)
protected ExternalLocation setupExternalLocation(String library, String label,
Address address, SourceType sourceType, boolean isFunction)
throws InvalidInputException, DuplicateNameException {
boolean success = false;
int transactionID =
@@ -187,19 +181,19 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
}
}
protected ExternalLocation setupExternalLocation(final String library, final String label,
final Address address, final SourceType sourceType)
protected ExternalLocation setupExternalLocation(String library, String label,
Address address, SourceType sourceType)
throws InvalidInputException, DuplicateNameException {
return setupExternalLocation(library, label, address, sourceType, false);
}
protected ExternalLocation setupExternalFunction(final String library, final String label,
final Address address, final SourceType sourceType)
protected ExternalLocation setupExternalFunction(String library, String label,
Address address, SourceType sourceType)
throws InvalidInputException, DuplicateNameException {
return setupExternalLocation(library, label, address, sourceType, true);
}
protected Namespace addNamespace(final String libraryName, final String namespace)
protected Namespace addNamespace(String libraryName, String namespace)
throws InvalidInputException {
boolean success = false;
int transactionID = program.startTransaction(
@@ -217,7 +211,7 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
}
}
protected Namespace getLibraryScope(final String libaryName) {
protected Namespace getLibraryScope(String libaryName) {
Symbol s = program.getSymbolTable().getLibrarySymbol(libaryName);
if (s instanceof LibrarySymbol) {
return (Namespace) s.getObject();
@@ -225,27 +219,27 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
return null;
}
protected void closeExternalLocation(final EditExternalLocationDialog createDialog,
final String buttonText) {
protected void closeExternalLocation(EditExternalLocationDialog createDialog,
String buttonText) {
pressButtonByText(createDialog.getComponent(), buttonText);
assertFalse(createDialog.isShowing());
waitForPostedSwingRunnables();
waitForSwing();
}
protected GTreeNode selectLibraryNode(final String libraryName) throws Exception {
protected GTreeNode selectLibraryNode(String libraryName) throws Exception {
flushAndWaitForTree();
GTreeNode importsNode = rootNode.getChild("Imports");
assertNotNull(importsNode);
util.expandNode(importsNode);
waitForPostedSwingRunnables();
waitForSwing();
flushAndWaitForTree();
GTreeNode advapiNode = importsNode.getChild(libraryName);
assertNotNull(advapiNode);
tree.expandPath(advapiNode);
tree.setSelectedNode(advapiNode);
waitForPostedSwingRunnables();
waitForSwing();
flushAndWaitForTree();
GTreeNode selectedNode = util.getSelectedNode();
assertEquals(advapiNode, selectedNode);
@@ -254,26 +248,26 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
return advapiNode;
}
protected GTreeNode selectExternalLocation(final String libraryName,
final String externalLocation) throws Exception {
protected GTreeNode selectExternalLocation(String libraryName,
String externalLocation) throws Exception {
flushAndWaitForTree();
GTreeNode importsNode = rootNode.getChild("Imports");
assertNotNull(importsNode);
util.expandNode(importsNode);
waitForPostedSwingRunnables();
waitForSwing();
flushAndWaitForTree();
GTreeNode advapiNode = importsNode.getChild(libraryName);
assertNotNull(advapiNode);
util.expandNode(advapiNode);
waitForPostedSwingRunnables();
waitForSwing();
flushAndWaitForTree();
GTreeNode locationNode = advapiNode.getChild(externalLocation);
assertNotNull(locationNode);
tree.setSelectedNode(locationNode);
waitForPostedSwingRunnables();
waitForSwing();
flushAndWaitForTree();
GTreeNode selectedNode = util.getSelectedNode();
assertEquals(locationNode, selectedNode);
@@ -282,8 +276,8 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
return locationNode;
}
protected void checkExternalLocationPath(final EditExternalLocationDialog createDialog,
final String externalProgramPath) {
protected void checkExternalLocationPath(EditExternalLocationDialog createDialog,
String externalProgramPath) {
SystemUtilities.runSwingNow(() -> {
EditExternalLocationPanel panel = findComponent(
createDialog.getComponent().getRootPane(), EditExternalLocationPanel.class);
@@ -294,8 +288,8 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
});
}
protected void checkExternalLibraryName(final EditExternalLocationDialog createDialog,
final String expectedName) {
protected void checkExternalLibraryName(EditExternalLocationDialog createDialog,
String expectedName) {
SystemUtilities.runSwingNow(() -> {
EditExternalLocationPanel panel = findComponent(
createDialog.getComponent().getRootPane(), EditExternalLocationPanel.class);
@@ -306,8 +300,8 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
});
}
protected void chooseExternalLibraryName(final EditExternalLocationDialog createDialog,
final String libraryName) {
protected void chooseExternalLibraryName(EditExternalLocationDialog createDialog,
String libraryName) {
SystemUtilities.runSwingNow(() -> {
EditExternalLocationPanel panel = findComponent(
createDialog.getComponent().getRootPane(), EditExternalLocationPanel.class);
@@ -317,8 +311,8 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
});
}
protected void typeExternalLibraryName(final EditExternalLocationDialog createDialog,
final String libraryName) {
protected void typeExternalLibraryName(EditExternalLocationDialog createDialog,
String libraryName) {
runSwing(() -> {
EditExternalLocationPanel panel = findComponent(
@@ -335,8 +329,8 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
});
}
protected void checkExternalLocationPathEndsWith(final EditExternalLocationDialog createDialog,
final String externalProgramPathEndsWith) {
protected void checkExternalLocationPathEndsWith(EditExternalLocationDialog createDialog,
String externalProgramPathEndsWith) {
EditExternalLocationPanel panel = findComponent(createDialog.getComponent().getRootPane(),
EditExternalLocationPanel.class);
Object pathTextObj = getInstanceField("extLibPathTextField", panel);
@@ -347,16 +341,16 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
text.endsWith(externalProgramPathEndsWith));
}
protected void chooseProgram(final Project project, final String programName) {
protected void chooseProgram(Project project, String programName) {
final DataTreeDialog chooseDialog = AbstractDockingTest.waitForDialogComponent(
plugin.getTool().getToolFrame(), DataTreeDialog.class, 2000);
DataTreeDialog chooseDialog = AbstractDockingTest.waitForDialogComponent(
DataTreeDialog.class);
ProjectData projectData = project.getProjectData();
DomainFolder folder = projectData.getFolder("/");
assertNotNull(folder);
final DomainFile file = folder.getFile(programName);
DomainFile file = folder.getFile(programName);
assertNotNull(file);
setFileInDataTreeDialog(chooseDialog, file);
@@ -368,15 +362,15 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
flushAndWaitForTree();
}
protected void chooseProgramButCancel(final Project project, final String programName) {
protected void chooseProgramButCancel(Project project, String programName) {
final DataTreeDialog chooseDialog = AbstractDockingTest.waitForDialogComponent(
plugin.getTool().getToolFrame(), DataTreeDialog.class, 2000);
DataTreeDialog chooseDialog = AbstractDockingTest.waitForDialogComponent(
DataTreeDialog.class);
ProjectData projectData = project.getProjectData();
DomainFolder folder = projectData.getFolder("/");
assertNotNull(folder);
final DomainFile file = folder.getFile(programName);
DomainFile file = folder.getFile(programName);
assertNotNull(file);
setFileInDataTreeDialog(chooseDialog, file);
@@ -390,13 +384,9 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
protected void closeErrorDialog(String expectedTitle) {
final OptionDialog errorDialog = AbstractDockingTest.waitForDialogComponent(
plugin.getTool().getToolFrame(), OptionDialog.class, 2000);
String actualTitle = errorDialog.getTitle();
pressButtonByText(errorDialog.getComponent().getRootPane(), "OK", false);
AbstractErrDialog d = waitForErrorDialog();
String actualTitle = d.getTitle();
close(d);
assertEquals(expectedTitle, actualTitle);
waitForBusyTool(tool);
@@ -404,7 +394,7 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
flushAndWaitForTree();
}
protected void checkExternalLocationLabel(final EditExternalLocationDialog createDialog,
protected void checkExternalLocationLabel(EditExternalLocationDialog createDialog,
String label) {
EditExternalLocationPanel extLocPanel = findComponent(
createDialog.getComponent().getRootPane(), EditExternalLocationPanel.class);
@@ -414,7 +404,7 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
assertEquals(label, text);
}
protected void setExternalLocationLabel(final EditExternalLocationDialog createDialog,
protected void setExternalLocationLabel(EditExternalLocationDialog createDialog,
String label) {
runSwing(() -> {
EditExternalLocationPanel extLocPanel = findComponent(
@@ -425,7 +415,7 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
});
}
protected void checkExternalLocationAddressInput(final EditExternalLocationDialog createDialog,
protected void checkExternalLocationAddressInput(EditExternalLocationDialog createDialog,
String space, String address) {
EditExternalLocationPanel extLocPanel = findComponent(
createDialog.getComponent().getRootPane(), EditExternalLocationPanel.class);
@@ -443,7 +433,7 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
assertEquals(address, currentAddress);
}
protected void setExternalLocationAddressInput(final EditExternalLocationDialog createDialog,
protected void setExternalLocationAddressInput(EditExternalLocationDialog createDialog,
AddressSpace addressSpace, String address) {
runSwing(() -> {
EditExternalLocationPanel extLocPanel = findComponent(
@@ -468,13 +458,13 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
Address address = program.getAddressFactory().getAddress(startAddress);
Memory memory = program.getMemory();
memory.createInitializedBlock(name, address, length, (byte) 0,
TaskMonitorAdapter.DUMMY_MONITOR, true);
TaskMonitor.DUMMY, true);
program.endTransaction(transactionID, true);
}
protected void closeProgram() throws Exception {
final ProgramManager pm = tool.getService(ProgramManager.class);
SwingUtilities.invokeAndWait(() -> pm.closeProgram());
ProgramManager pm = tool.getService(ProgramManager.class);
runSwing(() -> pm.closeProgram());
}
protected void showSymbolTree() throws Exception {
@@ -514,26 +504,26 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
assertNotNull(goToExtLocAction);
}
protected void pressDataTreeDialogOK(final DataTreeDialog dialog) {
protected void pressDataTreeDialogOK(DataTreeDialog dialog) {
pressButtonByText(dialog.getComponent(), "OK");
assertFalse(dialog.isShowing());
waitForPostedSwingRunnables();
waitForSwing();
}
protected void pressDataTreeDialogCancel(final DataTreeDialog dialog) {
protected void pressDataTreeDialogCancel(DataTreeDialog dialog) {
pressButtonByText(dialog.getComponent(), "Cancel");
assertFalse(dialog.isShowing());
waitForPostedSwingRunnables();
waitForSwing();
}
protected void setFileInDataTreeDialog(final DataTreeDialog dialog, final DomainFile file) {
protected void setFileInDataTreeDialog(DataTreeDialog dialog, DomainFile file) {
runSwing(() -> dialog.selectDomainFile(file), true);
waitForDialogTree(dialog);
}
protected void waitForDialogTree(DataTreeDialog dialog) {
waitForPostedSwingRunnables();
waitForSwing();
ProjectDataTreePanel treePanel =
(ProjectDataTreePanel) getInstanceField("treePanel", dialog);
DataTree dataTree = treePanel.getDataTree();
@@ -542,7 +532,7 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
protected void flushAndWaitForTree() {
program.flushEvents();
waitForPostedSwingRunnables();
waitForSwing();
util.waitForTree();
}
}
@@ -15,7 +15,7 @@
*/
package ghidra.app.util.viewer.field;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import java.awt.*;
@@ -32,6 +32,7 @@ import ghidra.app.nav.Navigatable;
import ghidra.app.nav.TestDummyNavigatable;
import ghidra.app.services.*;
import ghidra.framework.model.*;
import ghidra.framework.plugintool.ServiceProvider;
import ghidra.framework.plugintool.TestDummyServiceProvider;
import ghidra.framework.project.ProjectDataService;
import ghidra.program.database.ProgramBuilder;
@@ -247,7 +248,7 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
SpyNavigatable spyNavigatable = new SpyNavigatable();
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
annotatedElement.handleMouseClicked(spyNavigatable, spyServiceProvider);
click(spyNavigatable, spyServiceProvider, annotatedElement);
assertTrue(spyServiceProvider.programOpened(programName));
assertTrue(spyNavigatable.navigatedTo(programName));
@@ -257,7 +258,7 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
public void testProgramAnnotation_ProgramNameAndAddress() {
String programName = OTHER_PROGRAM_NAME;
String address = "01001014"; // some non-start addresss
String address = "01001014"; // some non-start address
String annotationText = "{@program " + programName + "@" + address + "}";
String rawComment = "My comment - " + annotationText;
AttributedString prototype = prototype();
@@ -274,7 +275,7 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
SpyNavigatable spyNavigatable = new SpyNavigatable();
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
annotatedElement.handleMouseClicked(spyNavigatable, spyServiceProvider);
click(spyNavigatable, spyServiceProvider, annotatedElement);
assertTrue(spyServiceProvider.programOpened(programName));
assertTrue(spyNavigatable.navigatedTo(programName, address));
@@ -284,7 +285,7 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
public void testProgramAnnotation_ProgramNameAndAddress_InvalidAddress() {
String programName = OTHER_PROGRAM_NAME;
String address = "01FFFFFF"; // some non-start addresss
String address = "01FFFFFF"; // some non-start address
String annotationText = "{@program " + programName + "@" + address + "}";
String rawComment = "My comment - " + annotationText;
AttributedString prototype = prototype();
@@ -301,14 +302,13 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
SpyNavigatable spyNavigatable = new SpyNavigatable();
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
annotatedElement.handleMouseClicked(spyNavigatable, spyServiceProvider);
click(spyNavigatable, spyServiceProvider, annotatedElement);
assertErrorDialog("No Symbol");
assertTrue(spyServiceProvider.programOpened(programName));
assertTrue(spyServiceProvider.programClosed(programName));
assertFalse(spyNavigatable.navigatedTo(programName, address));
Window window = waitForWindowByTitleContaining("No Symbol");
window.setVisible(false);
}
@Test
@@ -332,7 +332,7 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
SpyNavigatable spyNavigatable = new SpyNavigatable();
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
annotatedElement.handleMouseClicked(spyNavigatable, spyServiceProvider);
click(spyNavigatable, spyServiceProvider, annotatedElement);
assertTrue(spyServiceProvider.programOpened(programName));
assertTrue(spyNavigatable.navigatedTo(programName, symbol));
@@ -359,14 +359,13 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
SpyNavigatable spyNavigatable = new SpyNavigatable();
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
annotatedElement.handleMouseClicked(spyNavigatable, spyServiceProvider);
click(spyNavigatable, spyServiceProvider, annotatedElement);
assertErrorDialog("No Symbol");
assertTrue(spyServiceProvider.programOpened(programName));
assertTrue(spyServiceProvider.programClosed(programName));
assertFalse(spyNavigatable.navigatedTo(programName, symbol));
Window window = waitForWindowByTitleContaining("No Symbol");
window.setVisible(false);
}
@Test
@@ -390,7 +389,7 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
SpyNavigatable spyNavigatable = new SpyNavigatable();
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
annotatedElement.handleMouseClicked(spyNavigatable, spyServiceProvider);
click(spyNavigatable, spyServiceProvider, annotatedElement);
assertTrue(spyServiceProvider.programOpened(programName));
assertTrue(spyNavigatable.navigatedTo(programName, symbol));
@@ -416,12 +415,11 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
SpyNavigatable spyNavigatable = new SpyNavigatable();
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
annotatedElement.handleMouseClicked(spyNavigatable, spyServiceProvider);
click(spyNavigatable, spyServiceProvider, annotatedElement);
assertErrorDialog("No Program");
assertFalse(spyServiceProvider.programOpened(programName));
Window window = waitForWindowByTitleContaining("No Program");
window.setVisible(false);
}
@Test
@@ -430,8 +428,7 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
SpyNavigatable spyNavigatable = new SpyNavigatable();
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
String addressString = "1001000";
Address address = program.getAddressFactory().getAddress(addressString);
String addresstring = "1001000";
// path in comment
String otherProgramPath = "folder1/folder2/program_f1_f2.exe";
@@ -440,25 +437,24 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
String realPath = "folder1/program_f1_f2.exe";
addFakeProgramByPath(spyServiceProvider, realPath);
String annotationText = "{@program " + otherProgramPath + "@" + addressString + "}";
String annotationText = "{@program " + otherProgramPath + "@" + addresstring + "}";
String rawComment = "My comment - " + annotationText;
AttributedString prototype = prototype();
FieldElement element =
CommentUtils.parseTextForAnnotations(rawComment, program, prototype, 0);
String displayString = element.getText();
assertEquals("My comment - " + otherProgramPath + "@" + addressString, displayString);
assertEquals("My comment - " + otherProgramPath + "@" + addresstring, displayString);
//
// When clicking an element with bad path program should not open
//
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
annotatedElement.handleMouseClicked(spyNavigatable, spyServiceProvider);
click(spyNavigatable, spyServiceProvider, annotatedElement);
assertErrorDialog("No Folder");
assertFalse(spyServiceProvider.programOpened(otherProgramPath));
Window window = waitForWindowByTitleContaining("No Folder");
window.setVisible(false);
}
@Test
@@ -484,7 +480,7 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
// should be opened
//
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
annotatedElement.handleMouseClicked(spyNavigatable, spyServiceProvider);
click(spyNavigatable, spyServiceProvider, annotatedElement);
assertTrue(spyServiceProvider.programOpened(otherProgramPath));
assertTrue(spyNavigatable.navigatedTo(otherProgramPath));
@@ -496,27 +492,27 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
SpyNavigatable spyNavigatable = new SpyNavigatable();
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
String addressString = "1001000";
Address address = program.getAddressFactory().getAddress(addressString);
String addresstring = "1001000";
Address address = program.getAddressFactory().getAddress(addresstring);
String otherProgramPath = "/folder1/folder2/program_f1_f2.exe";
addFakeProgramByPath(spyServiceProvider, otherProgramPath);
String annotationText = "{@program " + otherProgramPath + "@" + addressString + "}";
String annotationText = "{@program " + otherProgramPath + "@" + addresstring + "}";
String rawComment = "My comment - " + annotationText;
AttributedString prototype = prototype();
FieldElement element =
CommentUtils.parseTextForAnnotations(rawComment, program, prototype, 0);
String displayString = element.getText();
assertEquals("My comment - " + otherProgramPath + "@" + addressString, displayString);
assertEquals("My comment - " + otherProgramPath + "@" + addresstring, displayString);
//
// When clicking an element with only a program name, the result is that the program
// should be opened
//
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
annotatedElement.handleMouseClicked(spyNavigatable, spyServiceProvider);
click(spyNavigatable, spyServiceProvider, annotatedElement);
assertTrue(spyServiceProvider.programOpened(otherProgramPath));
assertTrue(spyNavigatable.navigatedTo(otherProgramPath, address));
@@ -529,28 +525,28 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
SpyNavigatable spyNavigatable = new SpyNavigatable();
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
String addressString = "1001000";
Address address = program.getAddressFactory().getAddress(addressString);
String addresstring = "1001000";
Address address = program.getAddressFactory().getAddress(addresstring);
String otherProgramPath = "/folder1/folder2/program_f1_f2.exe";
String annotationPath = "\\folder1\\folder2\\program_f1_f2.exe";
addFakeProgramByPath(spyServiceProvider, otherProgramPath);
String annotationText = "{@program " + annotationPath + "@" + addressString + "}";
String annotationText = "{@program " + annotationPath + "@" + addresstring + "}";
String rawComment = "My comment - " + annotationText;
AttributedString prototype = prototype();
FieldElement element =
CommentUtils.parseTextForAnnotations(rawComment, program, prototype, 0);
String displayString = element.getText();
assertEquals("My comment - " + annotationPath + "@" + addressString, displayString);
assertEquals("My comment - " + annotationPath + "@" + addresstring, displayString);
//
// When clicking an element with only a program name, the result is that the program
// should be opened
//
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
annotatedElement.handleMouseClicked(spyNavigatable, spyServiceProvider);
click(spyNavigatable, spyServiceProvider, annotatedElement);
assertTrue(spyServiceProvider.programOpened(otherProgramPath));
assertTrue(spyNavigatable.navigatedTo(otherProgramPath, address));
@@ -562,28 +558,28 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
SpyNavigatable spyNavigatable = new SpyNavigatable();
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
String addressString = "1001000";
Address address = program.getAddressFactory().getAddress(addressString);
String addresstring = "1001000";
Address address = program.getAddressFactory().getAddress(addresstring);
String otherProgramPath = "folder1/folder2/program_f1_f2.exe";
String annotationPath = "folder1\\folder2\\program_f1_f2.exe";
addFakeProgramByPath(spyServiceProvider, otherProgramPath);
String annotationText = "{@program " + annotationPath + "@" + addressString + "}";
String annotationText = "{@program " + annotationPath + "@" + addresstring + "}";
String rawComment = "My comment - " + annotationText;
AttributedString prototype = prototype();
FieldElement element =
CommentUtils.parseTextForAnnotations(rawComment, program, prototype, 0);
String displayString = element.getText();
assertEquals("My comment - " + annotationPath + "@" + addressString, displayString);
assertEquals("My comment - " + annotationPath + "@" + addresstring, displayString);
//
// When clicking an element with only a program name, the result is that the program
// should be opened
//
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
annotatedElement.handleMouseClicked(spyNavigatable, spyServiceProvider);
click(spyNavigatable, spyServiceProvider, annotatedElement);
assertTrue(spyServiceProvider.programOpened(otherProgramPath));
assertTrue(spyNavigatable.navigatedTo(otherProgramPath, address));
@@ -596,31 +592,30 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
SpyNavigatable spyNavigatable = new SpyNavigatable();
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
String addressString = "1001000";
Address address = program.getAddressFactory().getAddress(addressString);
String addresstring = "1001000";
Address address = program.getAddressFactory().getAddress(addresstring);
String otherProgramPath = "folder1/folder2/program_f1_f2.exe";
addFakeProgramByPath(spyServiceProvider, otherProgramPath);
String annotationText = "{@program " + otherProgramPath + "@" + addressString + "}";
String annotationText = "{@program " + otherProgramPath + "@" + addresstring + "}";
String rawComment = "My comment - " + annotationText;
AttributedString prototype = prototype();
FieldElement element =
CommentUtils.parseTextForAnnotations(rawComment, program, prototype, 0);
String displayString = element.getText();
assertEquals("My comment - " + otherProgramPath + "@" + addressString, displayString);
assertEquals("My comment - " + otherProgramPath + "@" + addresstring, displayString);
//
// When clicking an element with only a program name, the result is that the program
// should be opened
//
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
annotatedElement.handleMouseClicked(spyNavigatable, spyServiceProvider);
click(spyNavigatable, spyServiceProvider, annotatedElement);
assertTrue(spyServiceProvider.programOpened(otherProgramPath));
assertTrue(spyNavigatable.navigatedTo(otherProgramPath, address));
}
@Test
@@ -728,6 +723,14 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
// Private Methods
//==================================================================================================
private void click(Navigatable navigatable, ServiceProvider sp,
AnnotatedTextFieldElement annotatedElement) {
// this may show an error dialog; invoke later
runSwingLater(() -> annotatedElement.handleMouseClicked(navigatable, sp));
waitForSwing();
}
private AnnotatedTextFieldElement getAnnotatedTextFieldElement(FieldElement element) {
assertThat(element, instanceOf(CompositeFieldElement.class));
@@ -795,6 +798,12 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
}
}
private void assertErrorDialog(String title) {
Window window = waitForWindowByTitleContaining(title);
runSwing(() -> window.setVisible(false));
waitForSwing(); // let post-dialog processing happen
}
//==================================================================================================
// Fake/Spy Classes
//==================================================================================================
@@ -858,24 +867,20 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
private List<TestDummyDomainFolder> folders = CollectionUtils.asList(this);
private List<TestDummyDomainFile> files =
private List<TestDummyDomainFile> folderFiles =
CollectionUtils.asList(new TestDummyDomainFile(this, OTHER_PROGRAM_NAME));
public FakeRootFolder() {
super(null, "Fake Root Folder");
}
void addFile(TestDummyDomainFile f) {
files.add(f);
}
void addFolder(TestDummyDomainFolder f) {
folders.add(f);
}
@Override
public synchronized DomainFile[] getFiles() {
return files.toArray(new TestDummyDomainFile[files.size()]);
return folderFiles.toArray(new TestDummyDomainFile[folderFiles.size()]);
}
@Override
@@ -28,7 +28,7 @@ import javax.swing.tree.TreePath;
import org.junit.*;
import docking.ActionContext;
import docking.*;
import docking.action.DockingActionIf;
import docking.action.ToggleDockingAction;
import docking.test.AbstractDockingTest;
@@ -92,11 +92,11 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
@Test
public void testNewFolder() throws Exception {
final DockingActionIf newFolderAction = getAction("New Folder");
DockingActionIf newFolderAction = getAction("New Folder");
setSelectionPaths(new TreePath[] { rootNode.getTreePath() });
int count = rootNode.getChildCount();
performAction(newFolderAction, getDomainFileActionContext(), true);
SwingUtilities.invokeAndWait(() -> tree.stopEditing());
runSwing(() -> tree.stopEditing());
assertEquals(count + 1, rootNode.getChildCount());
assertNotNull(getChild(rootNode, "NewFolder"));
}
@@ -104,11 +104,11 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
@Test
public void testNewFolderBlankName() throws Exception {
// try entering a blank name
final DockingActionIf newFolderAction = getAction("New Folder");
DockingActionIf newFolderAction = getAction("New Folder");
setSelectionPaths(new TreePath[] { rootNode.getTreePath() });
performAction(newFolderAction, getDomainFileActionContext(), true);
waitForTree();
SwingUtilities.invokeLater(() -> {
runSwingLater(() -> {
GTreeNode node = rootNode.getChild("NewFolder");
int row = tree.getRowForPath(node.getTreePath());
DefaultTreeCellEditor cellEditor = (DefaultTreeCellEditor) tree.getCellEditor();
@@ -123,10 +123,9 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
});
waitForSwing();
OptionDialog d = waitForDialogComponent(OptionDialog.class);
assertNotNull(d);
AbstractErrDialog d = waitForErrorDialog();
assertEquals("Rename Failed", d.getTitle());
pressButtonByText(d.getComponent(), "OK");
close(d);
}
@Test
@@ -137,7 +136,7 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
setSelectionPaths(new TreePath[] { rootNode.getTreePath() });
performAction(newFolderAction, getDomainFileActionContext(), true);
waitForTree();
SwingUtilities.invokeAndWait(() -> tree.stopEditing());
runSwing(() -> tree.stopEditing());
waitForTree();
if (i > 0) {
assertNotNull(getChild(rootNode, "NewFolder" + (i + 1)));
@@ -371,9 +370,9 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
rootFolder.createFolder("otherFolder");
waitForSwing();
final GTreeNode otherNode = getChild(rootNode, "otherFolder");
GTreeNode otherNode = getChild(rootNode, "otherFolder");
// drag myFolder to otherFolder
final GTreeNode myNode = getChild(rootNode, "myFolder");
GTreeNode myNode = getChild(rootNode, "myFolder");
doDrag(otherNode, DnDConstants.ACTION_MOVE, myNode);
@@ -460,10 +459,9 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
doDrag(myNode, DnDConstants.ACTION_MOVE, npNode);
waitForTree();
OptionDialog d = waitForDialogComponent(OptionDialog.class);
assertNotNull(d);
AbstractErrDialog d = waitForErrorDialog();
assertEquals("Cannot Move File", d.getTitle());
pressButtonByText(d.getComponent(), "OK");
close(d);
expandTreePath(myNode.getTreePath());
assertEquals(0, myNode.getChildCount());
@@ -535,7 +533,7 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
rootFolder.createFolder("myFolder");
waitForSwing();
final GTreeNode myNode = rootNode.getChild("myFolder");
GTreeNode myNode = rootNode.getChild("myFolder");
setSelectionPath(myNode.getTreePath());
DockingActionIf renameAction = getAction("Rename");
@@ -543,7 +541,7 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
waitForTree();
// select "Rename" action
SwingUtilities.invokeAndWait(() -> {
runSwing(() -> {
int row = tree.getRowForPath(myNode.getTreePath());
JTree jTree = (JTree) getInstanceField("tree", tree);
DefaultTreeCellEditor cellEditor = (DefaultTreeCellEditor) tree.getCellEditor();
@@ -561,7 +559,7 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
@Test
public void testRenameFile() throws Exception {
final GTreeNode npNode = rootNode.getChild("notepad");
GTreeNode npNode = rootNode.getChild("notepad");
setSelectionPath(npNode.getTreePath());
DockingActionIf renameAction = getAction("Rename");
@@ -569,7 +567,7 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
waitForTree();
// select "Rename" action
SwingUtilities.invokeAndWait(() -> {
runSwing(() -> {
int row = tree.getRowForPath(npNode.getTreePath());
DefaultTreeCellEditor cellEditor = (DefaultTreeCellEditor) tree.getCellEditor();
JTree jTree = (JTree) getInstanceField("tree", tree);
@@ -588,7 +586,7 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
@Test
public void testRenameFileInUse() throws Exception {
final GTreeNode npNode = rootNode.getChild("notepad");
GTreeNode npNode = rootNode.getChild("notepad");
DomainFile df = ((DomainFileNode) npNode).getDomainFile();
setInUse(df);
@@ -599,9 +597,9 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
executeOnSwingWithoutBlocking(
() -> performAction(renameAction, getDomainFileActionContext(), true));
waitForSwing();
OptionDialog dlg = waitForDialogComponent(OptionDialog.class);
assertEquals("Rename Not Allowed", dlg.getTitle());
pressButtonByText(dlg.getComponent(), "OK");
DialogComponentProvider d = waitForDialogComponent("Rename Not Allowed");
pressButtonByText(d.getComponent(), "OK");
assertNotNull(rootNode.getChild("notepad"));
}
@@ -618,7 +616,7 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
DomainFile df = f.createFile("notepad", p, TaskMonitor.DUMMY);
waitForSwing();
final GTreeNode myNode = rootNode.getChild("myFolder");
GTreeNode myNode = rootNode.getChild("myFolder");
((DomainFolderNode) myNode).getDomainFolder().createFile("notepad", p, TaskMonitor.DUMMY);
p.release(this);
@@ -630,12 +628,12 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
setSelectionPath(myNode.getTreePath());
final DockingActionIf renameAction = getAction("Rename");
DockingActionIf renameAction = getAction("Rename");
performAction(renameAction, getDomainFileActionContext(), true);
waitForTree();
// attempt to rename "myFolder"
SwingUtilities.invokeLater(() -> {
runSwingLater(() -> {
int row = tree.getRowForPath(myNode.getTreePath());
DefaultTreeCellEditor cellEditor = (DefaultTreeCellEditor) tree.getCellEditor();
JTree jTree = (JTree) getInstanceField("tree", tree);
@@ -649,10 +647,9 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
waitForSwing();
OptionDialog d = waitForDialogComponent(OptionDialog.class);
assertNotNull(d);
AbstractErrDialog d = waitForErrorDialog();
assertEquals("Rename Failed", d.getTitle());
pressButtonByText(d.getComponent(), "OK");
close(d);
assertNotNull(rootNode.getChild("myFolder"));
}
@@ -756,7 +753,7 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
// Private Methods
//==================================================================================================
private void setSelectionPath(final TreePath path) throws Exception {
private void setSelectionPath(TreePath path) throws Exception {
tree.setSelectionPath(path);
waitForTree();
}
@@ -802,7 +799,7 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
setInUse(df, "/notepad");
}
private void setInUse(DomainFile df, final String path) throws Exception {
private void setInUse(DomainFile df, String path) throws Exception {
ProgramDB program = createDefaultProgram("test1", ProgramBuilder._TOY, this);
//
@@ -41,10 +41,6 @@ public class CloseToolTest extends AbstractGhidraHeadedIntegrationTest {
private TestEnv env;
public CloseToolTest() {
super();
}
@Before
public void setUp() throws Exception {
@@ -105,7 +105,7 @@ public final class CryptoKeyFactory {
}
}
catch (Exception e) {
Msg.showWarn(CryptoKeyFactory.class, null, "Error Parsing Crypto Keys File",
Msg.showError(CryptoKeyFactory.class, null, "Error Parsing Crypto Keys File",
"Unable to process crypto keys files.", e);
}
}
@@ -29,17 +29,14 @@ import ghidra.program.model.symbol.*;
import ghidra.program.util.ProgramSelection;
public class DiffApplyIgnoreTest extends DiffApplyTestAdapter {
public DiffApplyIgnoreTest() {
super();
}
@Test
public void testProgramContextIgnore() throws Exception {
openDiff(diffTestP1, diffTestP2);
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Memory Differs", 2000);
JDialog dialog = waitForJDialog("Memory Differs");
assertNotNull(dialog);
pressButtonByText(dialog, "OK");
waitForPostedSwingRunnables();
waitForSwing();
showApplySettings();
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
@@ -54,10 +51,10 @@ public class DiffApplyIgnoreTest extends DiffApplyTestAdapter {
public void testByteIgnore() throws Exception {
openDiff(diffTestP1, diffTestP2);
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Memory Differs", 2000);
JDialog dialog = waitForJDialog("Memory Differs");
assertNotNull(dialog);
pressButtonByText(dialog, "OK");
waitForPostedSwingRunnables();
waitForSwing();
showApplySettings();
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
@@ -71,10 +68,10 @@ public class DiffApplyIgnoreTest extends DiffApplyTestAdapter {
@Test
public void testCodeUnitIgnore() throws Exception {
openDiff(diffTestP1, diffTestP2);
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Memory Differs", 2000);
JDialog dialog = waitForJDialog("Memory Differs");
assertNotNull(dialog);
pressButtonByText(dialog, "OK");
waitForPostedSwingRunnables();
waitForSwing();
showApplySettings();
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
@@ -88,10 +85,10 @@ public class DiffApplyIgnoreTest extends DiffApplyTestAdapter {
@Test
public void testReferenceIgnore() throws Exception {
openDiff(diffTestP1, diffTestP2);
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Memory Differs", 2000);
JDialog dialog = waitForJDialog("Memory Differs");
assertNotNull(dialog);
pressButtonByText(dialog, "OK");
waitForPostedSwingRunnables();
waitForSwing();
showApplySettings();
memRefIgnore();
@@ -208,10 +205,10 @@ public class DiffApplyIgnoreTest extends DiffApplyTestAdapter {
@Test
public void testBookmarkIgnore() throws Exception {
openDiff(diffTestP1, diffTestP2);
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Memory Differs", 2000);
JDialog dialog = waitForJDialog("Memory Differs");
assertNotNull(dialog);
pressButtonByText(dialog, "OK");
waitForPostedSwingRunnables();
waitForSwing();
showApplySettings();
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
@@ -225,10 +222,10 @@ public class DiffApplyIgnoreTest extends DiffApplyTestAdapter {
@Test
public void testPropertyIgnore() throws Exception {
openDiff(diffTestP1, diffTestP2);
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Memory Differs", 2000);
JDialog dialog = waitForJDialog("Memory Differs");
assertNotNull(dialog);
pressButtonByText(dialog, "OK");
waitForPostedSwingRunnables();
waitForSwing();
showApplySettings();
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
@@ -242,10 +239,10 @@ public class DiffApplyIgnoreTest extends DiffApplyTestAdapter {
@Test
public void testFunctionIgnore() throws Exception {
openDiff(diffTestP1, diffTestP2);
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Memory Differs", 2000);
JDialog dialog = waitForJDialog("Memory Differs");
assertNotNull(dialog);
pressButtonByText(dialog, "OK");
waitForPostedSwingRunnables();
waitForSwing();
showApplySettings();
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
@@ -15,8 +15,7 @@
*/
package ghidra.app.plugin.core.diff;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.*;
import java.util.*;
@@ -36,14 +35,10 @@ import ghidra.util.exception.InvalidInputException;
public class DiffApplyReplaceTest extends DiffApplyTestAdapter {
public DiffApplyReplaceTest() {
super();
}
@Test
public void testProgramContextReplace() throws Exception {
openDiff(diffTestP1, diffTestP2);
waitForPostedSwingRunnables();
waitForSwing();
showApplySettings();
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
@@ -57,9 +52,9 @@ public class DiffApplyReplaceTest extends DiffApplyTestAdapter {
@Test
public void testByteReplace() throws Exception {
openDiff(diffTestP1, diffTestP2);
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Memory Differs", 2000);
JDialog dialog = waitForJDialog("Memory Differs");
pressButtonByText(dialog, "OK");
waitForPostedSwingRunnables();
waitForSwing();
showApplySettings();
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
@@ -73,9 +68,9 @@ public class DiffApplyReplaceTest extends DiffApplyTestAdapter {
@Test
public void testCodeUnitReplace() throws Exception {
openDiff(diffTestP1, diffTestP2);
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Memory Differs", 2000);
JDialog dialog = waitForJDialog("Memory Differs");
pressButtonByText(dialog, "OK");
waitForPostedSwingRunnables();
waitForSwing();
showApplySettings();
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
@@ -89,9 +84,9 @@ public class DiffApplyReplaceTest extends DiffApplyTestAdapter {
@Test
public void testReferenceReplace() throws Exception {
openDiff(diffTestP1, diffTestP2);
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Memory Differs", 2000);
JDialog dialog = waitForJDialog("Memory Differs");
pressButtonByText(dialog, "OK");
waitForPostedSwingRunnables();
waitForSwing();
showApplySettings();
memRefReplace();
extRefReplace();
@@ -284,9 +279,9 @@ public class DiffApplyReplaceTest extends DiffApplyTestAdapter {
@Test
public void testBookmarkReplace() throws Exception {
openDiff(diffTestP1, diffTestP2);
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Memory Differs", 2000);
JDialog dialog = waitForJDialog("Memory Differs");
pressButtonByText(dialog, "OK");
waitForPostedSwingRunnables();
waitForSwing();
showApplySettings();
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
@@ -300,9 +295,9 @@ public class DiffApplyReplaceTest extends DiffApplyTestAdapter {
@Test
public void testPropertyReplace() throws Exception {
openDiff(diffTestP1, diffTestP2);
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Memory Differs", 2000);
JDialog dialog = waitForJDialog("Memory Differs");
pressButtonByText(dialog, "OK");
waitForPostedSwingRunnables();
waitForSwing();
showApplySettings();
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
@@ -316,9 +311,9 @@ public class DiffApplyReplaceTest extends DiffApplyTestAdapter {
@Test
public void testFunctionReplace() throws Exception {
openDiff(diffTestP1, diffTestP2);
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Memory Differs", 2000);
JDialog dialog = waitForJDialog("Memory Differs");
pressButtonByText(dialog, "OK");
waitForPostedSwingRunnables();
waitForSwing();
showApplySettings();
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
@@ -24,7 +24,6 @@ import javax.swing.*;
import org.junit.Before;
import org.junit.Test;
import docking.widgets.MultiLineLabel;
import ghidra.app.events.ProgramSelectionPluginEvent;
import ghidra.program.database.ProgramBuilder;
import ghidra.program.model.address.AddressSet;
@@ -353,9 +352,6 @@ public class DiffGetTest extends DiffTestAdapter {
assertNull(fp2.getTopLevelAncestor());
Window win = waitForWindow("Can't Open Selected Program");
assertNotNull(win);
String msg = findComponent(win, MultiLineLabel.class).getLabel();
assertTrue(msg.startsWith("Programs languages don't match."));
pressButton(win, "OK");
win = waitForWindow("Select Other Program");
assertNotNull(win);
@@ -147,9 +147,6 @@ public class DualProgramTest extends DiffTestAdapter {
waitForTasks();
win = waitForWindow("Can't Open Selected Program");
assertNotNull(win);
MultiLineLabel mll = findComponent(win, MultiLineLabel.class);
assertTrue(mll.getLabel().startsWith("Programs languages don't match."));
pressButton(win, "OK");
win = waitForWindow("Select Other Program");
@@ -24,7 +24,6 @@ import javax.swing.table.TableModel;
import org.junit.*;
import docking.widgets.MultiLineLabel;
import docking.wizard.WizardManager;
import docking.wizard.WizardPanel;
import generic.test.TestUtils;
@@ -46,8 +45,8 @@ import ghidra.util.table.GhidraTable;
public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
private static final String TEST_SOURCE_PROGRAM_NAME = "VersionTracking/WallaceSrc";
private static final String TEST_DESTINATION_PROGRAM_NAME = "VersionTracking/WallaceVersion2";
private static String TEST_SOURCE_PROGRAM_NAME = "VersionTracking/WallaceSrc";
private static String TEST_DESTINATION_PROGRAM_NAME = "VersionTracking/WallaceVersion2";
private enum VTWizardPanelAction {
BACK, NEXT, FINISH, CANCEL;
@@ -130,7 +129,7 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
createWizardManager();
SystemUtilities.runSwingLater(
runSwingLater(
() -> wizardManager.showWizard(controller.getParentComponent()));
waitForDialogComponent(WizardManager.class);
@@ -186,7 +185,7 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
createWizardManager();
SystemUtilities.runSwingLater(
runSwingLater(
() -> wizardManager.showWizard(controller.getParentComponent()));
waitForDialogComponent(WizardManager.class);
@@ -248,7 +247,7 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
createWizardManager();
SystemUtilities.runSwingLater(
runSwingLater(
() -> wizardManager.showWizard(controller.getParentComponent()));
waitForDialogComponent(WizardManager.class);
@@ -310,7 +309,7 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
createWizardManager();
SystemUtilities.runSwingLater(
runSwingLater(
() -> wizardManager.showWizard(controller.getParentComponent()));
waitForDialogComponent(WizardManager.class);
@@ -387,7 +386,7 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
createWizardManager();
SystemUtilities.runSwingLater(
runSwingLater(
() -> wizardManager.showWizard(controller.getParentComponent()));
waitForDialogComponent(WizardManager.class);
@@ -451,7 +450,7 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
createWizardManager();
SystemUtilities.runSwingLater(
runSwingLater(
() -> wizardManager.showWizard(controller.getParentComponent()));
waitForDialogComponent(WizardManager.class);
@@ -515,7 +514,7 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
createWizardManager();
SystemUtilities.runSwingLater(
runSwingLater(
() -> wizardManager.showWizard(controller.getParentComponent()));
waitForDialogComponent(WizardManager.class);
@@ -592,7 +591,7 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
createWizardManager();
SystemUtilities.runSwingLater(
runSwingLater(
() -> wizardManager.showWizard(controller.getParentComponent()));
waitForDialogComponent(WizardManager.class);
@@ -694,7 +693,7 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
createWizardManager();
SystemUtilities.runSwingLater(
runSwingLater(
() -> wizardManager.showWizard(controller.getParentComponent()));
waitForDialogComponent(WizardManager.class);
@@ -725,12 +724,12 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
String msgContains = "Data Reference Match";
JDialog dialog = waitForJDialog("Version Tracking: Add To Session");
assertNotNull("Info dialog not found", dialog);
MultiLineLabel label = (MultiLineLabel) findComponentByName(dialog, "MESSAGE-COMPONENT");
assertNotNull("Expected server error dialog", label);
String message = getMessageText(dialog);
assertTrue("Expected Server Error message starting with: " + msgStart,
label.getLabel().startsWith(msgStart));
message.startsWith(msgStart));
assertTrue("Expected Server Error message containing: " + msgContains,
label.getLabel().contains(msgContains));
message.contains(msgContains));
pressButtonByText(dialog, "OK");
waitForSwing();
@@ -747,17 +746,13 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
assertEquals("Number of matches", 0, vtMatchSet2.getMatchCount());
}
//********************************************
// Private Work/Validation methods.
//********************************************
private void chooseFromCorrelationPanel(final String correlatorName,
final VTWizardPanelAction wizardAction) {
private void chooseFromCorrelationPanel(String correlatorName,
VTWizardPanelAction wizardAction) {
WizardPanel currentWizardPanel = wizardManager.getCurrentWizardPanel();
assertNotNull(currentWizardPanel);
assertTrue(currentWizardPanel instanceof CorrelatorPanel);
final CorrelatorPanel correlatorPanel = (CorrelatorPanel) currentWizardPanel;
CorrelatorPanel correlatorPanel = (CorrelatorPanel) currentWizardPanel;
SystemUtilities.runSwingNow(() -> {
GhidraTable table = (GhidraTable) TestUtils.getInstanceField("table", correlatorPanel);
TableModel model = table.getModel();
@@ -771,7 +766,7 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
}
private void changeCorrelatorOptionsPanel(Object correlatorOptionsObject,
final VTWizardPanelAction wizardAction) {
VTWizardPanelAction wizardAction) {
// Options Panel
WizardPanel currentWizardPanel = wizardManager.getCurrentWizardPanel();
@@ -837,7 +832,7 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
}
private void changeAddressSetOptionsPanel(boolean excludeAccepted, boolean limitAddressSets,
final VTWizardPanelAction wizardAction) {
VTWizardPanelAction wizardAction) {
// Address Set Options Panel
WizardPanel currentWizardPanel = wizardManager.getCurrentWizardPanel();
@@ -1002,22 +997,22 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
}
}
private void changeAddressSetViaListRemoveRange(final boolean isSource,
final AddressSetPanel addressSetPanel, final AddressSetView desiredAddressSet) {
private void changeAddressSetViaListRemoveRange(boolean isSource,
AddressSetPanel addressSetPanel, AddressSetView desiredAddressSet) {
ChooseAddressSetEditorPanel panel =
(ChooseAddressSetEditorPanel) TestUtils.getInstanceField("panel", addressSetPanel);
assertNotNull(panel);
final JButton addRangeButton =
JButton addRangeButton =
(JButton) TestUtils.getInstanceField("addRangeButton", panel);
assertNotNull("Couldn't get button for adding address range.", addRangeButton);
JButton listRemoveRangeButton =
(JButton) TestUtils.getInstanceField("removeRangeButton", panel);
assertNotNull("Couldn't get button for removing address range for list selection.",
listRemoveRangeButton);
final JList list = (JList) TestUtils.getInstanceField("list", panel);
JList<?> list = (JList<?>) TestUtils.getInstanceField("list", panel);
SystemUtilities.runSwingNow(() -> {
ListModel model = list.getModel();
ListModel<?> model = list.getModel();
int size = model.getSize();
list.setSelectionInterval(0, size - 1);// Select all items in the list.
});
@@ -1033,17 +1028,16 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
}
}
private void changeAddressSetViaSubtractDialog(final boolean isSource,
final AddressSetPanel addressSetPanel, final AddressSetView desiredAddressSet) {
private void changeAddressSetViaSubtractDialog(boolean isSource,
AddressSetPanel addressSetPanel, AddressSetView desiredAddressSet) {
ChooseAddressSetEditorPanel panel =
(ChooseAddressSetEditorPanel) TestUtils.getInstanceField("panel", addressSetPanel);
assertNotNull(panel);
final JButton addRangeButton =
JButton addRangeButton =
(JButton) TestUtils.getInstanceField("addRangeButton", panel);
final JButton subtractRangeButton =
JButton subtractRangeButton =
(JButton) TestUtils.getInstanceField("subtractRangeButton", panel);
JList list = (JList) TestUtils.getInstanceField("list", panel);
Runnable r = () -> subtractRangeButton.doClick();
runSwing(r, false);
@@ -1057,11 +1051,11 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
}
}
private void enterAddressRange(final boolean isSource, final String buttonText,
final String minAddress, final String maxAddress) {
private void enterAddressRange(boolean isSource, String buttonText,
String minAddress, String maxAddress) {
final AddRemoveAddressRangeDialog addRemoveDialog =
env.waitForDialogComponent(AddRemoveAddressRangeDialog.class, 2000);
AddRemoveAddressRangeDialog addRemoveDialog =
waitForDialogComponent(AddRemoveAddressRangeDialog.class);
assertNotNull(addRemoveDialog);
waitForSwing();
@@ -1069,20 +1063,20 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
assertEquals((isSource ? "Source" : "Destination") + " Address Range",
addRemoveDialog.getTitle());
final AddressInput minAddressField =
AddressInput minAddressField =
(AddressInput) TestUtils.getInstanceField("minAddressField", addRemoveDialog);
assertNotNull(minAddressField);
SystemUtilities.runSwingLater(() -> {
runSwingLater(() -> {
Address address = isSource ? sourceAddress(minAddress) : destinationAddress(minAddress);
minAddressField.setAddress(address);
});
waitForSwing();
final AddressInput maxAddressField =
AddressInput maxAddressField =
(AddressInput) TestUtils.getInstanceField("maxAddressField", addRemoveDialog);
assertNotNull(maxAddressField);
SystemUtilities.runSwingLater(() -> {
runSwingLater(() -> {
Address address = isSource ? sourceAddress(maxAddress) : destinationAddress(maxAddress);
maxAddressField.setAddress(address);
});
@@ -1093,11 +1087,11 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
assertTrue("Dialog not closed after pressing: " + buttonText, !addRemoveDialog.isShowing());
}
private void enterAddressRange(final boolean isSource, final String buttonText,
final Address minAddress, final Address maxAddress) {
private void enterAddressRange(boolean isSource, String buttonText,
Address minAddress, Address maxAddress) {
final AddRemoveAddressRangeDialog addRemoveDialog =
env.waitForDialogComponent(AddRemoveAddressRangeDialog.class, 2000);
AddRemoveAddressRangeDialog addRemoveDialog =
waitForDialogComponent(AddRemoveAddressRangeDialog.class);
assertNotNull(addRemoveDialog);
waitForSwing();
@@ -1105,18 +1099,18 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
assertEquals((isSource ? "Source" : "Destination") + " Address Range",
addRemoveDialog.getTitle());
final AddressInput minAddressField =
AddressInput minAddressField =
(AddressInput) TestUtils.getInstanceField("minAddressField", addRemoveDialog);
assertNotNull(minAddressField);
SystemUtilities.runSwingLater(() -> minAddressField.setAddress(minAddress));
runSwingLater(() -> minAddressField.setAddress(minAddress));
waitForSwing();
final AddressInput maxAddressField =
AddressInput maxAddressField =
(AddressInput) TestUtils.getInstanceField("maxAddressField", addRemoveDialog);
assertNotNull(maxAddressField);
SystemUtilities.runSwingLater(() -> {
runSwingLater(() -> {
maxAddressField.setAddress(maxAddress);
});
@@ -1133,7 +1127,7 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
}
private void changeAddressSetsPanel(AddressSetChoice sourceChoice,
AddressSetChoice destinationChoice, final VTWizardPanelAction wizardAction) {
AddressSetChoice destinationChoice, VTWizardPanelAction wizardAction) {
changeAddressSetChoices(sourceChoice, destinationChoice);
@@ -1154,8 +1148,8 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
setSelectionInTool(destinationTool, destinationSelection);
}
private void checkSummaryPanel(final String labelString, final String summaryString,
final VTWizardPanelAction wizardAction) {
private void checkSummaryPanel(String labelString, String summaryString,
VTWizardPanelAction wizardAction) {
// Address Set Options Panel
WizardPanel currentWizardPanel = wizardManager.getCurrentWizardPanel();
@@ -1174,7 +1168,8 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
assertEquals(labelString, labelText);
assertEquals(summaryString, summaryText);
SystemUtilities.runSwingNow(() -> invoke(wizardAction));
runSwingLater(() -> invoke(wizardAction));
waitForSwing();
}
private int getRowWithFieldValueInColumn(String string, TableModel model, int column) {
@@ -0,0 +1,58 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package docking;
import utility.function.Callback;
/**
* A dialog that is meant to be extended for showing exceptions
*/
public abstract class AbstractErrDialog extends DialogComponentProvider {
// at some point, there are too many exceptions to show
protected static final int MAX_EXCEPTIONS = 100;
private static final String ERRORS_PREFIX = " (";
private static final String ERRORS_SUFFIX = " Errors)";
private Callback closedCallback = Callback.dummy();
protected AbstractErrDialog(String title) {
super(title, true, false, true, false);
}
@Override
protected final void dialogClosed() {
closedCallback.call();
}
/**
* Returns the string message of this error dialog
* @return the message
*/
public abstract String getMessage();
abstract void addException(String message, Throwable t);
abstract int getExceptionCount();
void updateTitle() {
setTitle(getTitle() + ERRORS_PREFIX + getExceptionCount() + ERRORS_SUFFIX);
}
void setClosedCallback(Callback callback) {
closedCallback = Callback.dummyIfNull(callback);
}
}
@@ -220,6 +220,12 @@ public class DockingDialog extends JDialog implements HelpDescriptor {
component.escapeCallback();
}
@Override
public void windowClosed(WindowEvent e) {
// this call is needed to handle the case where the dialog is closed by Java and
// not by the user closing the dialog or calling close() through the API
cleanup();
}
};
this.addWindowListener(windowAdapter);
modalFixWindowAdapter = new WindowAdapter() {
@@ -249,6 +255,10 @@ public class DockingDialog extends JDialog implements HelpDescriptor {
}
void close() {
cleanup();
}
private void cleanup() {
if (component.getRemberSize() || component.getRememberLocation()) {
String key = getKey();
Rectangle rect = getBounds();
@@ -258,7 +268,10 @@ public class DockingDialog extends JDialog implements HelpDescriptor {
component.setDialog(null);
removeWindowListener(windowAdapter);
// this will do nothing if already closed
setVisible(false);
component.dialogClosed();
component = null;
getContentPane().removeAll();
@@ -17,7 +17,6 @@ package docking;
import java.awt.Component;
import java.awt.Window;
import java.io.*;
import docking.widgets.OkDialog;
import docking.widgets.OptionDialog;
@@ -26,7 +25,16 @@ import ghidra.util.exception.MultipleCauses;
public class DockingErrorDisplay implements ErrorDisplay {
private static final int TRACE_BUFFER_SIZE = 250;
/**
* Error dialog used to append exceptions.
*
* <p>While this dialog is showing all new exceptions will be added to the dialog. When
* this dialog is closed, this reference will be cleared.
*
* <p>Note: all use of this variable <b>must be on the Swing thread</b> to avoid thread
* visibility issues.
*/
private static AbstractErrDialog activeDialog;
ConsoleErrorDisplay consoleDisplay = new ConsoleErrorDisplay();
@@ -52,8 +60,8 @@ public class DockingErrorDisplay implements ErrorDisplay {
private void displayMessage(MessageType messageType, ErrorLogger errorLogger, Object originator,
Component parent, String title, Object message, Throwable throwable) {
int dialogType = OptionDialog.PLAIN_MESSAGE;
int dialogType = OptionDialog.PLAIN_MESSAGE;
String messageString = message != null ? message.toString() : null;
String rawMessage = HTMLUtilities.fromHTML(messageString);
switch (messageType) {
@@ -75,7 +83,7 @@ public class DockingErrorDisplay implements ErrorDisplay {
break;
}
showDialog(title, message, throwable, dialogType, messageString, getWindow(parent));
showDialog(title, throwable, dialogType, messageString, getWindow(parent));
}
private Component getWindow(Component component) {
@@ -85,33 +93,45 @@ public class DockingErrorDisplay implements ErrorDisplay {
return component;
}
private void showDialog(final String title, final Object message, final Throwable throwable,
private void showDialog(final String title, final Throwable throwable,
final int dialogType, final String messageString, final Component parent) {
SystemUtilities.runIfSwingOrPostSwingLater(
() -> doShowDialog(title, message, throwable, dialogType, messageString, parent));
}
private void doShowDialog(final String title, final Object message, final Throwable throwable,
int dialogType, String messageString, Component parent) {
DialogComponentProvider dialog = null;
if (throwable != null) {
dialog = createErrorDialog(title, message, throwable, messageString);
if (dialogType == OptionDialog.ERROR_MESSAGE) {
// Note: all calls to manipulate the error dialog must be on the Swing thread to
// guarantee thread visibility to our state variables
Swing.runIfSwingOrRunLater(
() -> showDialogOnSwing(title, throwable, dialogType, messageString, parent));
}
else {
dialog = new OkDialog(title, messageString, dialogType);
DockingWindowManager.showDialog(parent,
new OkDialog(title, messageString, dialogType));
}
DockingWindowManager.showDialog(parent, dialog);
}
private DialogComponentProvider createErrorDialog(final String title, final Object message,
final Throwable throwable, String messageString) {
private void showDialogOnSwing(String title, Throwable throwable,
int dialogType, String messageString, Component parent) {
if (activeDialog != null) {
activeDialog.addException(messageString, throwable);
return;
}
activeDialog = createErrorDialog(title, throwable, messageString);
activeDialog.setClosedCallback(() -> {
activeDialog.setClosedCallback(null);
activeDialog = null;
});
DockingWindowManager.showDialog(parent, activeDialog);
}
private AbstractErrDialog createErrorDialog(String title, Throwable throwable,
String messageString) {
if (containsMultipleCauses(throwable)) {
return new ErrLogExpandableDialog(title, messageString, throwable);
}
return ErrLogDialog.createExceptionDialog(title, messageString,
buildStackTrace(throwable, message == null ? throwable.getMessage() : messageString));
return ErrLogDialog.createExceptionDialog(title, messageString, throwable);
}
private boolean containsMultipleCauses(Throwable throwable) {
@@ -125,34 +145,4 @@ public class DockingErrorDisplay implements ErrorDisplay {
return containsMultipleCauses(throwable.getCause());
}
/**
* Build a displayable stack trace from a Throwable
*
* @param t the throwable
* @param msg message prefix
* @return multi-line stack trace
*/
private String buildStackTrace(Throwable t, String msg) {
StringBuffer sb = new StringBuffer(TRACE_BUFFER_SIZE);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
if (msg != null) {
ps.println(msg);
}
t.printStackTrace(ps);
sb.append(baos.toString());
ps.close();
try {
baos.close();
}
catch (IOException e) {
// shouldn't happen--not really connected to the system
}
return sb.toString();
}
}
File diff suppressed because it is too large Load Diff
@@ -32,12 +32,12 @@ import docking.widgets.label.GHtmlLabel;
import docking.widgets.tree.*;
import docking.widgets.tree.support.GTreeDragNDropHandler;
import ghidra.util.*;
import ghidra.util.exception.*;
import ghidra.util.exception.MultipleCauses;
import ghidra.util.html.HTMLElement;
import resources.ResourceManager;
import util.CollectionUtils;
public class ErrLogExpandableDialog extends DialogComponentProvider {
public class ErrLogExpandableDialog extends AbstractErrDialog {
public static ImageIcon IMG_REPORT = ResourceManager.loadImage("images/report.png");
public static ImageIcon IMG_EXCEPTION = ResourceManager.loadImage("images/exception.png");
public static ImageIcon IMG_FRAME_ELEMENT =
@@ -53,113 +53,21 @@ public class ErrLogExpandableDialog extends DialogComponentProvider {
private static boolean showingDetails = false;
protected ReportRootNode root;
protected GTree excTree;
protected GTree tree;
private List<Throwable> errors = new ArrayList<>();
/** This spacer addresses the optical impression that the message panel changes size when showing details */
protected Component horizontalSpacer;
protected JButton detailButton;
protected JButton sendButton;
protected boolean hasConsole = false;
protected JPopupMenu popup;
protected static class ExcTreeTransferHandler extends TransferHandler
implements GTreeDragNDropHandler {
protected ErrLogExpandableDialog(String title, String msg, Throwable throwable) {
super(title);
protected ReportRootNode root;
errors.add(throwable);
public ExcTreeTransferHandler(ReportRootNode root) {
this.root = root;
}
@Override
public DataFlavor[] getSupportedDataFlavors(List<GTreeNode> transferNodes) {
return new DataFlavor[] { DataFlavor.stringFlavor };
}
@Override
protected Transferable createTransferable(JComponent c) {
ArrayList<GTreeNode> nodes = new ArrayList<>();
for (TreePath path : ((JTree) c).getSelectionPaths()) {
nodes.add((GTreeNode) path.getLastPathComponent());
}
try {
return new StringSelection(
(String) getTransferData(nodes, DataFlavor.stringFlavor));
}
catch (UnsupportedFlavorException e) {
Msg.debug(this, e.getMessage(), e);
}
return null;
}
@Override
public Object getTransferData(List<GTreeNode> transferNodes, DataFlavor flavor)
throws UnsupportedFlavorException {
if (flavor != DataFlavor.stringFlavor) {
throw new UnsupportedFlavorException(flavor);
}
if (transferNodes.isEmpty()) {
return null;
}
if (transferNodes.size() == 1) {
GTreeNode node = transferNodes.get(0);
if (node instanceof NodeWithText) {
return ((NodeWithText) node).collectReportText(transferNodes, 0).trim();
}
return null;
}
return root.collectReportText(transferNodes, 0).trim();
}
@Override
public boolean isStartDragOk(List<GTreeNode> dragUserData, int dragAction) {
for (GTreeNode node : dragUserData) {
if (node instanceof NodeWithText) {
return true;
}
}
return false;
}
@Override
public int getSupportedDragActions() {
return DnDConstants.ACTION_COPY;
}
@Override
public int getSourceActions(JComponent c) {
return COPY;
}
@Override
public boolean isDropSiteOk(GTreeNode destUserData, DataFlavor[] flavors, int dropAction) {
return false;
}
@Override
public void drop(GTreeNode destUserData, Transferable transferable, int dropAction) {
throw new UnsupportedOperationException();
}
}
public ErrLogExpandableDialog(String title, String msg, MultipleCauses mc) {
this(title, msg, mc.getCauses(), null, true, true);
}
public ErrLogExpandableDialog(String title, String msg, Throwable exc) {
this(title, msg, Collections.singletonList(exc), HasConsoleText.Util.get(exc), true, true);
}
public ErrLogExpandableDialog(String title, String msg, Collection<Throwable> report) {
this(title, msg, report, null, false, false);
}
protected ErrLogExpandableDialog(String title, String msg, Collection<Throwable> report,
String console, boolean modal, boolean hasDismiss) {
super(title, modal);
hasConsole = console != null;
popup = new JPopupMenu();
JMenuItem menuCopy = new JMenuItem("Copy");
menuCopy.setActionCommand((String) TransferHandler.getCopyAction().getValue(Action.NAME));
@@ -173,13 +81,12 @@ public class ErrLogExpandableDialog extends DialogComponentProvider {
msgPanel.setLayout(new BorderLayout(16, 16));
msgPanel.setBorder(new EmptyBorder(16, 16, 16, 16));
{
JLabel msgText = new GHtmlLabel(getHTML(msg, report)) {
JLabel msgText = new GHtmlLabel(getHTML(msg, CollectionUtils.asSet(throwable))) {
@Override
public Dimension getPreferredSize() {
// when rendering HTML the label can expand larger than the screen;
// keep it reasonable
// rendering HTML the label can expand larger than the screen; keep it reasonable
Dimension size = super.getPreferredSize();
size.width = 500;
size.width = 300;
return size;
}
};
@@ -206,7 +113,7 @@ public class ErrLogExpandableDialog extends DialogComponentProvider {
msgPanel.add(buttonBox, BorderLayout.EAST);
horizontalSpacer = Box.createVerticalStrut(10);
horizontalSpacer.setVisible(showingDetails | hasConsole);
horizontalSpacer.setVisible(showingDetails);
msgPanel.add(horizontalSpacer, BorderLayout.SOUTH);
}
workPanel.add(msgPanel, BorderLayout.NORTH);
@@ -214,29 +121,8 @@ public class ErrLogExpandableDialog extends DialogComponentProvider {
Box workBox = Box.createVerticalBox();
{
if (hasConsole) {
JTextArea consoleText = new JTextArea(console);
JScrollPane consoleScroll =
new JScrollPane(consoleText, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED) {
@Override
public Dimension getPreferredSize() {
Dimension dim = super.getPreferredSize();
dim.height = 400;
dim.width = 800; // trial and error?
return dim;
}
};
consoleText.setEditable(false);
consoleText.setBackground(Color.BLACK);
consoleText.setForeground(Color.WHITE);
consoleText.setFont(Font.decode("Monospaced"));
workBox.add(consoleScroll);
}
root = new ReportRootNode(getTitle(), report);
excTree = new GTree(root) {
root = new ReportRootNode(getTitle(), CollectionUtils.asSet(throwable));
tree = new GTree(root) {
@Override
public Dimension getPreferredSize() {
@@ -249,19 +135,19 @@ public class ErrLogExpandableDialog extends DialogComponentProvider {
for (GTreeNode node : CollectionUtils.asIterable(root.iterator(true))) {
if (node instanceof ReportExceptionNode) {
excTree.expandTree(node);
tree.expandTree(node);
}
}
excTree.setSelectedNode(root.getChild(0));
excTree.setVisible(showingDetails);
tree.setSelectedNode(root.getChild(0));
tree.setVisible(showingDetails);
ExcTreeTransferHandler handler = new ExcTreeTransferHandler(root);
excTree.setDragNDropHandler(handler);
excTree.setTransferHandler(handler);
ActionMap map = excTree.getActionMap();
tree.setDragNDropHandler(handler);
tree.setTransferHandler(handler);
ActionMap map = tree.getActionMap();
map.put(TransferHandler.getCopyAction().getValue(Action.NAME),
TransferHandler.getCopyAction());
excTree.addMouseListener(new MouseAdapter() {
tree.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
maybeShowPopup(e);
@@ -279,22 +165,19 @@ public class ErrLogExpandableDialog extends DialogComponentProvider {
}
});
workBox.add(excTree);
workBox.add(tree);
}
workPanel.add(workBox, BorderLayout.CENTER);
repack();
addWorkPanel(workPanel);
if (hasDismiss) {
addDismissButton();
}
addDismissButton();
}
private String getHTML(String msg, Collection<Throwable> report) {
//
// TODO
// Usage question: The content herein will be escaped unless you call addHTMLContenet().
// Further, clients can provide messages that contain HTML. Is there a
// use case where we want to show escaped HTML content?
@@ -332,14 +215,6 @@ public class ErrLogExpandableDialog extends DialogComponentProvider {
String htmlTMsg = addBR(tMsg);
body.addElement("p").addHTMLContent(htmlTMsg);
if (t instanceof CausesImportant) { // I choose not to recurse
HTMLElement ul = body.addElement("ul");
for (Throwable ts : MultipleCauses.Util.iterCauses(t)) {
String tsMsg = getMessage(ts);
String htmlTSMsg = addBR(tsMsg);
ul.addElement("li").addHTMLContent(htmlTSMsg);
}
}
}
return html.toString();
}
@@ -357,15 +232,15 @@ public class ErrLogExpandableDialog extends DialogComponentProvider {
return t.getClass().getSimpleName();
}
void detailCallback() {
private void detailCallback() {
showingDetails = !showingDetails;
excTree.setVisible(showingDetails);
horizontalSpacer.setVisible(showingDetails | hasConsole);
tree.setVisible(showingDetails);
horizontalSpacer.setVisible(showingDetails);
detailButton.setText(showingDetails ? CLOSE : DETAIL);
repack();
}
void sendCallback() {
private void sendCallback() {
String details = root.collectReportText(null, 0).trim();
String title = getTitle();
close();
@@ -379,6 +254,29 @@ public class ErrLogExpandableDialog extends DialogComponentProvider {
return dim;
}
@Override
public void addException(String message, Throwable t) {
int n = errors.size();
if (n > MAX_EXCEPTIONS) {
return;
}
errors.add(t);
root.addNode(new ReportExceptionNode(t));
updateTitle(); // signal the new error
}
@Override
int getExceptionCount() {
return root.getChildCount();
}
@Override
public String getMessage() {
return root.getReportText();
}
static interface NodeWithText {
public String getReportText();
@@ -528,9 +426,6 @@ public class ErrLogExpandableDialog extends DialogComponentProvider {
@Override
public String getReportText() {
if (exc instanceof HasConsoleText) {
return getName() + "\n" + HasConsoleText.Util.get(exc);
}
return getName();
}
@@ -661,6 +556,87 @@ public class ErrLogExpandableDialog extends DialogComponentProvider {
return false;
}
}
private static class ExcTreeTransferHandler extends TransferHandler
implements GTreeDragNDropHandler {
protected ReportRootNode root;
public ExcTreeTransferHandler(ReportRootNode root) {
this.root = root;
}
@Override
public DataFlavor[] getSupportedDataFlavors(List<GTreeNode> transferNodes) {
return new DataFlavor[] { DataFlavor.stringFlavor };
}
@Override
protected Transferable createTransferable(JComponent c) {
ArrayList<GTreeNode> nodes = new ArrayList<>();
for (TreePath path : ((JTree) c).getSelectionPaths()) {
nodes.add((GTreeNode) path.getLastPathComponent());
}
try {
return new StringSelection(
(String) getTransferData(nodes, DataFlavor.stringFlavor));
}
catch (UnsupportedFlavorException e) {
Msg.debug(this, e.getMessage(), e);
}
return null;
}
@Override
public Object getTransferData(List<GTreeNode> transferNodes, DataFlavor flavor)
throws UnsupportedFlavorException {
if (flavor != DataFlavor.stringFlavor) {
throw new UnsupportedFlavorException(flavor);
}
if (transferNodes.isEmpty()) {
return null;
}
if (transferNodes.size() == 1) {
GTreeNode node = transferNodes.get(0);
if (node instanceof NodeWithText) {
return ((NodeWithText) node).collectReportText(transferNodes, 0).trim();
}
return null;
}
return root.collectReportText(transferNodes, 0).trim();
}
@Override
public boolean isStartDragOk(List<GTreeNode> dragUserData, int dragAction) {
for (GTreeNode node : dragUserData) {
if (node instanceof NodeWithText) {
return true;
}
}
return false;
}
@Override
public int getSupportedDragActions() {
return DnDConstants.ACTION_COPY;
}
@Override
public int getSourceActions(JComponent c) {
return COPY;
}
@Override
public boolean isDropSiteOk(GTreeNode destUserData, DataFlavor[] flavors, int dropAction) {
return false;
}
@Override
public void drop(GTreeNode destUserData, Transferable transferable, int dropAction) {
throw new UnsupportedOperationException();
}
}
}
class TransferActionListener implements ActionListener, PropertyChangeListener {
@@ -15,78 +15,29 @@
*/
package docking.test;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import static org.junit.Assert.*;
import java.awt.AWTEvent;
import java.awt.AWTException;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Window;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.*;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
import javax.swing.AbstractButton;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JRadioButton;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.*;
import javax.swing.text.JTextComponent;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.*;
import docking.ActionContext;
import docking.ComponentPlaceholder;
import docking.ComponentProvider;
import docking.DialogComponentProvider;
import docking.DockableComponent;
import docking.DockingDialog;
import docking.DockingErrorDisplay;
import docking.DockingWindowManager;
import docking.EmptyBorderToggleButton;
import docking.Tool;
import docking.*;
import docking.action.DockingActionIf;
import docking.action.ToggleDockingActionIf;
import docking.actions.DockingToolActions;
@@ -104,9 +55,7 @@ import generic.test.ConcurrentTestExceptionHandler;
import generic.util.image.ImageUtils;
import ghidra.GhidraTestApplicationLayout;
import ghidra.framework.ApplicationConfiguration;
import ghidra.util.ConsoleErrorDisplay;
import ghidra.util.ErrorDisplay;
import ghidra.util.Msg;
import ghidra.util.*;
import ghidra.util.exception.AssertException;
import ghidra.util.task.SwingUpdateManager;
import ghidra.util.worker.Worker;
@@ -209,7 +158,7 @@ public abstract class AbstractDockingTest extends AbstractGenericTest {
Iterator<Window> iter = winList.iterator();
while (iter.hasNext()) {
Window w = iter.next();
if (!w.isVisible()) {
if (!w.isShowing()) {
continue;
}
String titleForWindow = getTitleForWindow(w);
@@ -229,7 +178,7 @@ public abstract class AbstractDockingTest extends AbstractGenericTest {
Iterator<Window> iter = winList.iterator();
while (iter.hasNext()) {
Window w = iter.next();
if (!w.isVisible()) {
if (!w.isShowing()) {
continue;
}
String titleForWindow = getTitleForWindow(w);
@@ -240,6 +189,14 @@ public abstract class AbstractDockingTest extends AbstractGenericTest {
return null;
}
/**
* Waits for the system error dialog to appear
* @return the dialog
*/
public static AbstractErrDialog waitForErrorDialog() {
return waitForDialogComponent(AbstractErrDialog.class);
}
public static Window waitForWindow(Class<?> windowClass) {
if ((!Dialog.class.isAssignableFrom(windowClass)) &&
@@ -256,7 +213,7 @@ public abstract class AbstractDockingTest extends AbstractGenericTest {
Iterator<Window> it = winList.iterator();
while (it.hasNext()) {
Window w = it.next();
if (windowClass.isAssignableFrom(w.getClass()) && w.isVisible()) {
if (windowClass.isAssignableFrom(w.getClass()) && w.isShowing()) {
return w;
}
}
@@ -346,7 +303,7 @@ public abstract class AbstractDockingTest extends AbstractGenericTest {
Set<Window> allWindows = getAllWindows();
for (Window window : allWindows) {
String windowName = window.getName();
if (name.equals(windowName) && window.isVisible()) {
if (name.equals(windowName) && window.isShowing()) {
return window;
}
@@ -358,13 +315,12 @@ public abstract class AbstractDockingTest extends AbstractGenericTest {
}
/**
* Check for and display message component text associated with
* ErrLogDialog and OptionDialog windows.
* Check for and display message component text associated with OptionDialog windows
* @param w any window
* @return the message string if one can be found; <code>null</code> otherwise
*/
public static String checkMessageDisplay(Window w) {
Component c = findComponentByName(w, "MESSAGE-COMPONENT");
public static String getMessageText(Window w) {
Component c = findComponentByName(w, OptionDialog.MESSAGE_COMPONENT_NAME);
if (c instanceof JLabel) {
return ((JLabel) c).getText();
}
@@ -466,7 +422,7 @@ public abstract class AbstractDockingTest extends AbstractGenericTest {
// note: we use System.err here to get more obvious errors in the console
String title = getDebugTitleForWindow(window);
System.err.println("DockingTestCase - Forced window closure: " + title);
String errorMessage = checkMessageDisplay(window);
String errorMessage = getMessageText(window);
if (errorMessage != null) {
System.err.println("\tWindow error message: " + errorMessage);
}
@@ -541,7 +497,7 @@ public abstract class AbstractDockingTest extends AbstractGenericTest {
Iterator<Window> iter = winList.iterator();
while (iter.hasNext()) {
Window w = iter.next();
if ((w instanceof JDialog) && w.isVisible()) {
if ((w instanceof JDialog) && w.isShowing()) {
String windowTitle = getTitleForWindow(w);
if (title.equals(windowTitle)) {
return (JDialog) w;
@@ -576,7 +532,7 @@ public abstract class AbstractDockingTest extends AbstractGenericTest {
Iterator<Window> iter = winList.iterator();
while (iter.hasNext()) {
Window w = iter.next();
if ((w instanceof JDialog) && w.isVisible()) {
if ((w instanceof JDialog) && w.isShowing()) {
String windowTitle = getTitleForWindow(w);
if (title.equals(windowTitle)) {
return (JDialog) w;
@@ -722,10 +678,6 @@ public abstract class AbstractDockingTest extends AbstractGenericTest {
return null;
}
if (!window.isVisible()) {
return null;
}
if (!window.isShowing()) {
return null;
}
@@ -1132,8 +1084,10 @@ public abstract class AbstractDockingTest extends AbstractGenericTest {
public static Set<DockingActionIf> getActionsByOwnerAndName(Tool tool, String owner,
String name) {
Set<DockingActionIf> ownerActions = tool.getDockingActionsByOwnerName(owner);
return ownerActions.stream().filter(action -> action.getName().equals(name)).collect(
Collectors.toSet());
return ownerActions.stream()
.filter(action -> action.getName().equals(name))
.collect(
Collectors.toSet());
}
/**
@@ -99,7 +99,7 @@ import ghidra.util.exception.AssertException;
* @see OptionDialogBuilder
*/
public class OptionDialog extends DialogComponentProvider {
private static final String MESSAGE_COMPONENT_NAME = "MESSAGE-COMPONENT";
public static final String MESSAGE_COMPONENT_NAME = "MESSAGE-COMPONENT";
/** Used for error messages. */
public static final int ERROR_MESSAGE = 0;
/** Used for information messages. */
@@ -102,7 +102,7 @@ public class ScrollableTextArea extends JScrollPane {
}
/**
* Appends the text to the text area maintained in this scrollpane
* Appends the text to the text area maintained in this scroll pane
* @param text the text to append.
*/
public void append(String text) {
@@ -111,13 +111,15 @@ public class ScrollableTextArea extends JScrollPane {
/**
* Returns the number of lines current set in the text area
* @return the count
*/
public int getLineCount() {
return textArea.getLineCount();
}
/**
* Returns the tabsize set in the text area
* Returns the tab size set in the text area
* @return the size
*/
public int getTabSize() {
return textArea.getTabSize();
@@ -125,6 +127,7 @@ public class ScrollableTextArea extends JScrollPane {
/**
* Returns the total area height of the text area (row height * line count)
* @return the height
*/
public int getTextAreaHeight() {
return (textArea.getAreaHeight());
@@ -132,6 +135,7 @@ public class ScrollableTextArea extends JScrollPane {
/**
* Returns the visible height of the text area
* @return the height
*/
public int getTextVisibleHeight() {
return textArea.getVisibleHeight();
@@ -200,6 +204,7 @@ public class ScrollableTextArea extends JScrollPane {
/**
* Returns the text contained within the text area
* @return the text
*/
public String getText() {
return textArea.getText();
@@ -0,0 +1,55 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.util.table.column;
import java.awt.Component;
import java.util.Date;
import javax.swing.JLabel;
import docking.widgets.table.GTableCellRenderingData;
import ghidra.docking.settings.Settings;
import ghidra.util.DateUtils;
/**
* A renderer for clients that wish to display a {@link Date} as a timestamp with the
* date and time.
*/
public class DefaultTimestampRenderer extends AbstractGColumnRenderer<Date> {
@Override
public Component getTableCellRendererComponent(GTableCellRenderingData data) {
JLabel label = (JLabel) super.getTableCellRendererComponent(data);
Date value = (Date) data.getValue();
if (value != null) {
label.setText(DateUtils.formatDateTimestamp(value));
}
return label;
}
@Override
public String getFilterString(Date t, Settings settings) {
return DateUtils.formatDateTimestamp(t);
}
@Override
public ColumnConstraintFilterMode getColumnConstraintFilterMode() {
// This allows for text filtering in the table and date filtering on columns
return ColumnConstraintFilterMode.ALLOW_ALL_FILTERS;
}
}
@@ -35,7 +35,7 @@ public class DockingErrorDisplayTest extends AbstractDockingTest {
DockingErrorDisplay display = new DockingErrorDisplay();
DefaultErrorLogger logger = new DefaultErrorLogger();
Exception exception = new Exception("My test exception");
doDisplay(display, logger, exception);
reportException(display, logger, exception);
assertErrLogDialog();
}
@@ -46,11 +46,29 @@ public class DockingErrorDisplayTest extends AbstractDockingTest {
DefaultErrorLogger logger = new DefaultErrorLogger();
Exception nestedException = new Exception("My nested test exception");
Exception exception = new Exception("My test exception", nestedException);
doDisplay(display, logger, exception);
reportException(display, logger, exception);
assertErrLogDialog();
}
@Test
public void testDefaultErrorDisplay_MultipleAsynchronousExceptions() {
DockingErrorDisplay display = new DockingErrorDisplay();
DefaultErrorLogger logger = new DefaultErrorLogger();
Exception exception = new Exception("My test exception");
reportException(display, logger, exception);
ErrLogDialog dialog = getErrLogDialog();
assertExceptionCount(dialog, 1);
reportException(display, logger, new NullPointerException("It is null!"));
assertExceptionCount(dialog, 2);
close(dialog);
}
@Test
public void testMultipleCausesErrorDisplay() {
DockingErrorDisplay display = new DockingErrorDisplay();
@@ -58,43 +76,51 @@ public class DockingErrorDisplayTest extends AbstractDockingTest {
Throwable firstCause = new Exception("My test exception - first cause");
MultipleCauses exception = new MultipleCauses(Collections.singletonList(firstCause));
doDisplay(display, logger, exception);
reportException(display, logger, exception);
assertErrLogExpandableDialog();
ErrLogExpandableDialog dialog = assertErrLogExpandableDialog();
assertExceptionCount(dialog, 1);
reportException(display, logger, new NullPointerException("It is null!"));
assertExceptionCount(dialog, 2);
close(dialog);
}
private void assertErrLogExpandableDialog() {
Window w = waitForWindow(TEST_TITLE, 2000);
assertNotNull(w);
private void assertExceptionCount(AbstractErrDialog errDialog, int n) {
final ErrLogExpandableDialog errDialog =
int actual = errDialog.getExceptionCount();
assertEquals(n, actual);
}
private ErrLogExpandableDialog assertErrLogExpandableDialog() {
Window w = waitForWindow(TEST_TITLE);
ErrLogExpandableDialog errDialog =
getDialogComponentProvider(w, ErrLogExpandableDialog.class);
assertNotNull(errDialog);
runSwing(new Runnable() {
@Override
public void run() {
errDialog.close();
}
});
return errDialog;
}
private void assertErrLogDialog() {
Window w = waitForWindow(TEST_TITLE, 2000);
Window w = waitForWindow(TEST_TITLE);
assertNotNull(w);
final ErrLogDialog errDialog = getDialogComponentProvider(w, ErrLogDialog.class);
ErrLogDialog errDialog = getDialogComponentProvider(w, ErrLogDialog.class);
assertNotNull(errDialog);
runSwing(new Runnable() {
@Override
public void run() {
errDialog.close();
}
});
close(errDialog);
}
private void doDisplay(final DockingErrorDisplay display, final DefaultErrorLogger logger,
private ErrLogDialog getErrLogDialog() {
Window w = waitForWindow(TEST_TITLE);
assertNotNull(w);
ErrLogDialog errDialog = getDialogComponentProvider(w, ErrLogDialog.class);
assertNotNull(errDialog);
return errDialog;
}
private void reportException(final DockingErrorDisplay display, final DefaultErrorLogger logger,
final Throwable throwable) {
runSwing(new Runnable() {
@Override
@@ -1094,8 +1094,24 @@ public abstract class AbstractGenericTest extends AbstractGTest {
return ref.get();
}
public static void runSwing(Runnable runnable) {
runSwing(runnable, true);
/**
* Run the given code snippet on the Swing thread and wait for it to finish
* @param r the runnable code snippet
*/
public static void runSwing(Runnable r) {
runSwing(r, true);
}
/**
* Run the given code snippet on the Swing thread later, not blocking the current thread. Use
* this if the code snippet causes a blocking operation.
*
* <P>This is a shortcut for <code>runSwing(r, false);</code>.
*
* @param r the runnable code snippet
*/
public void runSwingLater(Runnable r) {
runSwing(r, false);
}
/**
@@ -1103,7 +1119,7 @@ public abstract class AbstractGenericTest extends AbstractGTest {
* an exception
* @param runnable the runnable
* @param wait true signals to wait for the Swing operation to finish
* @throws Throwable any excption that is thrown on the Swing thread
* @throws Throwable any exception that is thrown on the Swing thread
*/
public static void runSwingWithExceptions(Runnable runnable, boolean wait) throws Throwable {
@@ -1,36 +0,0 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.util.exception;
import java.util.Arrays;
import org.apache.commons.lang3.StringUtils;
public interface CausesImportant {
public static class Util {
public static String getMessages(Throwable exc) {
if (exc instanceof CausesImportant) {
StringBuilder result = new StringBuilder(exc.getMessage());
for (Throwable cause : MultipleCauses.Util.iterCauses(exc)) {
result.append(
StringUtils.join(Arrays.asList(cause.getMessage().split("\n")), "\n\t"));
}
return result.toString();
}
return exc.getMessage();
}
}
}
@@ -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.util.exception;
public interface HasConsoleText {
public String getConsoleText();
public static class Util {
public static String get(Throwable exc) {
if (exc instanceof HasConsoleText) {
return ((HasConsoleText) exc).getConsoleText();
}
return null;
}
}
}
@@ -89,7 +89,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
protected DBHandle dbHandle;
private AddressMap addrMap;
private ErrorHandler errHandler;
private ErrorHandler errHandler = new DbErrorHandler();
private DataTypeConflictHandler currentHandler;
private CategoryDB root;
@@ -168,12 +168,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
*/
protected DataTypeManagerDB() {
this.lock = new Lock("DataTypeManagerDB");
errHandler = new ErrorHandler() {
@Override
public void dbError(IOException e) {
Msg.showError(this, null, "IO ERROR", e.getMessage(), e);
}
};
try {
dbHandle = new DBHandle();
int id = startTransaction("");
@@ -213,13 +208,6 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
") for read-only Datatype Archive: " + packedDBfile.getAbsolutePath());
}
errHandler = new ErrorHandler() {
@Override
public void dbError(IOException e) {
Msg.showError(this, null, "IO ERROR", e.getMessage(), e);
}
};
// Open packed database archive
boolean openSuccess = false;
PackedDatabase pdb = null;
@@ -4089,6 +4077,20 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
}
}
}
private class DbErrorHandler implements ErrorHandler {
@Override
public void dbError(IOException e) {
String message = e.getMessage();
if (e instanceof ClosedException) {
message = "Data type archive is closed: " + getName();
}
Msg.showError(this, null, "IO ERROR", message, e);
}
}
}
/**
@@ -225,33 +225,6 @@ public class Msg {
}
}
/**
* Used to display a warning message to the user with a pop-up GUI dialog.
* Also records the message to the logging system.
*
* @param originator
* a Logger instance, "this", or YourClass.class
* @param parent
* a parent component used to center the dialog (or null if you
* don't have one)
* @param title
* the title of the pop-up dialog (main subject of message)
* @param message
* the details of the message
* @param throwable
* the Throwable that describes the cause of the warning
*/
public static void showWarn(Object originator, Component parent, String title, Object message,
Throwable throwable) {
if (SystemUtilities.isInHeadlessMode()) {
Msg.warn(originator, message, throwable);
}
else {
errorDisplay.displayWarningMessage(errorLogger, originator, parent, title, message,
throwable);
}
}
/**
* Used to display an error message with no available Throwable to the user
* via the console (no GUI). Also records the message to the logging system.
@@ -499,14 +499,31 @@ public class ReflectionUtilities {
* @return the string
*/
public static String stackTraceToString(Throwable t) {
StringBuffer sb = new StringBuffer();
return stackTraceToString(t.getMessage(), t);
}
/**
* Turns the given {@link Throwable} into a String version of its
* {@link Throwable#printStackTrace()} method.
*
* @param message the preferred message to use. If null, the throwable message will be used
* @param t the throwable
* @return the string
*/
public static String stackTraceToString(String message, Throwable t) {
StringBuilder sb = new StringBuilder();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
String msg = t.getMessage();
if (msg != null) {
ps.println(msg);
if (message != null) {
ps.println(message);
}
else {
String throwableMessage = t.getMessage();
if (throwableMessage != null) {
ps.println(throwableMessage);
}
}
t.printStackTrace(ps);
@@ -55,8 +55,8 @@ public class IntroScreenShots extends GhidraScreenShotGenerator {
@Test
public void testErr_Dialog() {
runSwing(() -> {
ErrLogDialog dialog = ErrLogDialog.createLogMessageDialog("Unexpected Error",
"Oops, this is really bad!", "");
ErrLogDialog dialog = ErrLogDialog.createExceptionDialog("Unexpected Error",
"Oops, this is really bad!", new Throwable());
DockingWindowManager.showDialog(null, dialog);
}, false);
waitForSwing();
@@ -25,6 +25,7 @@ import javax.swing.tree.TreePath;
import org.junit.*;
import docking.AbstractErrDialog;
import docking.ActionContext;
import docking.action.DockingActionIf;
import docking.widgets.MultiLineLabel;
@@ -102,7 +103,7 @@ public class SetLanguageTest extends AbstractGhidraHeadedIntegrationTest {
@Test
public void testActionEnablement() throws Exception {
assertTrue(setLanguageAction.isEnabled());
assertTrue(!setLanguageAction.isEnabledForContext(createProjectDataContext(xyzFolderNode)));
assertFalse(setLanguageAction.isEnabledForContext(createProjectDataContext(xyzFolderNode)));
assertTrue(setLanguageAction.isEnabledForContext(createProjectDataContext(notepadNode)));
}
@@ -110,7 +111,7 @@ public class SetLanguageTest extends AbstractGhidraHeadedIntegrationTest {
return addrFactory.getAddress(address);
}
private void startSetLanguage(final LanguageID languageID, final CompilerSpecID compilerSpecID,
private void startSetLanguage(LanguageID languageID, CompilerSpecID compilerSpecID,
boolean isFailureCase) throws Exception {
if (languageID == null) {
throw new RuntimeException("languageID == null not allowed");
@@ -135,9 +136,9 @@ public class SetLanguageTest extends AbstractGhidraHeadedIntegrationTest {
pressButtonByText(confirmDlg, "Ok");
final SetLanguageDialog dlg = waitForDialogComponent(SetLanguageDialog.class);
SetLanguageDialog dlg = waitForDialogComponent(SetLanguageDialog.class);
assertNotNull(dlg);
final NewLanguagePanel languagePanel =
NewLanguagePanel languagePanel =
(NewLanguagePanel) getInstanceField("selectLangPanel", dlg);
assertNotNull(languagePanel);
@@ -167,16 +168,16 @@ public class SetLanguageTest extends AbstractGhidraHeadedIntegrationTest {
private ActionContext createProjectDataContext(GTreeNode node) {
TreePath[] selectionPaths = { node.getTreePath() };
List<DomainFile> fileList = new ArrayList<>();
List<DomainFolder> folderList = new ArrayList<>();
if (node instanceof DomainFileNode) {
fileList.add(((DomainFileNode) node).getDomainFile());
}
else {
folderList.add(((DomainFolderNode)node).getDomainFolder());
folderList.add(((DomainFolderNode) node).getDomainFolder());
}
return new FrontEndProjectTreeContext(null, null, selectionPaths, folderList, fileList,
(DataTree) node.getTree(), true);
}
@@ -208,13 +209,9 @@ public class SetLanguageTest extends AbstractGhidraHeadedIntegrationTest {
startSetLanguage(new LanguageID("8051:BE:16:default"), new CompilerSpecID("default"), true);
final OptionDialog errDlg = waitForDialogComponent(OptionDialog.class);
assertNotNull(errDlg);
MultiLineLabel msgLabel = findComponent(errDlg, MultiLineLabel.class);
assertNotNull(msgLabel);
assertTrue(msgLabel.getLabel().indexOf("Language translation not supported") >= 0);
pressButtonByText(errDlg, "OK");
AbstractErrDialog d = waitForErrorDialog();
assertTrue(d.getMessage().contains("Language translation not supported"));
close(d);
closeAllWindows();
}
@@ -25,6 +25,7 @@ import javax.swing.*;
import org.junit.*;
import org.junit.experimental.categories.Category;
import docking.AbstractErrDialog;
import docking.action.DockingActionIf;
import docking.widgets.OptionDialog;
import docking.wizard.WizardManager;
@@ -300,10 +301,9 @@ public class ProjectInfoDialogTest extends AbstractGhidraHeadedIntegrationTest {
pressButtonByText(opt, "Update");
waitForTasks();
opt = waitForDialogComponent(OptionDialog.class);
assertNotNull(opt);
assertEquals("Failed to Update Shared Project Info", opt.getTitle());
opt.close();
AbstractErrDialog errorDialog = waitForErrorDialog();
assertEquals("Failed to Update Shared Project Info", errorDialog.getTitle());
close(errorDialog);
}
private void checkProjectInfo(String expectedRepName) {
@@ -24,9 +24,9 @@ import javax.swing.*;
import org.junit.Assert;
import org.junit.Test;
import docking.AbstractErrDialog;
import docking.ActionContext;
import docking.action.DockingActionIf;
import docking.widgets.MultiLineLabel;
import docking.widgets.OptionDialog;
import docking.widgets.table.GTable;
import docking.widgets.tree.GTreeNode;
@@ -146,15 +146,15 @@ public class VersionControlAction2Test extends AbstractVersionControlActionTest
GTreeNode nodeC = getNode(PROGRAM_C);
selectNodes(nodeA, nodeC);
final DockingActionIf action = getAction("Add to Version Control");
DockingActionIf action = getAction("Add to Version Control");
SwingUtilities.invokeLater(
() -> action.actionPerformed(getDomainFileActionContext(nodeA, nodeC)));
waitForSwing();
VersionControlDialog dialog = waitForDialogComponent(VersionControlDialog.class);
assertNotNull(dialog);
final JTextArea textArea = findComponent(dialog, JTextArea.class);
JTextArea textArea = findComponent(dialog, JTextArea.class);
assertNotNull(textArea);
final JCheckBox cb = findComponent(dialog, JCheckBox.class);
JCheckBox cb = findComponent(dialog, JCheckBox.class);
assertNotNull(cb);
runSwing(() -> {
textArea.setText("This is a test");
@@ -176,11 +176,11 @@ public class VersionControlAction2Test extends AbstractVersionControlActionTest
@Test
public void testCheckOut() throws Exception {
// add program to version control
final GTreeNode node = getNode(PROGRAM_A);
GTreeNode node = getNode(PROGRAM_A);
addToVersionControl(node, false);
selectNode(node);
final DockingActionIf action = getAction("CheckOut");
DockingActionIf action = getAction("CheckOut");
SwingUtilities.invokeLater(() -> action.actionPerformed(getDomainFileActionContext(node)));
waitForSwing();
waitForTasks();
@@ -204,11 +204,11 @@ public class VersionControlAction2Test extends AbstractVersionControlActionTest
@Test
public void testCheckIn() throws Exception {
final GTreeNode node = getNode(PROGRAM_A);
GTreeNode node = getNode(PROGRAM_A);
addToVersionControl(node, false);
selectNode(node);
final DockingActionIf action = getAction("CheckOut");
DockingActionIf action = getAction("CheckOut");
runSwing(() -> action.actionPerformed(getDomainFileActionContext(node)), false);
waitForSwing();
waitForTasks();
@@ -227,14 +227,15 @@ public class VersionControlAction2Test extends AbstractVersionControlActionTest
program.save(null, TaskMonitor.DUMMY);
}
program.release(this);
final DockingActionIf checkInAction = getAction("CheckIn");
DockingActionIf checkInAction = getAction("CheckIn");
runSwing(() -> checkInAction.actionPerformed(getDomainFileActionContext(node)), false);
waitForSwing();
VersionControlDialog dialog = waitForDialogComponent(VersionControlDialog.class);
assertNotNull(dialog);
final JTextArea textArea = findComponent(dialog, JTextArea.class);
JTextArea textArea = findComponent(dialog, JTextArea.class);
assertNotNull(textArea);
final JCheckBox cb = findComponent(dialog, JCheckBox.class);
JCheckBox cb = findComponent(dialog, JCheckBox.class);
assertNotNull(cb);
runSwing(() -> {
textArea.setText("This is a test");
@@ -253,10 +254,10 @@ public class VersionControlAction2Test extends AbstractVersionControlActionTest
setErrorGUIEnabled(true);// expect an error dialog
// create 3 versions of the program
doCreateVersions();
final GTreeNode node = getNode(PROGRAM_A);
GTreeNode node = getNode(PROGRAM_A);
selectNode(node);
final DockingActionIf historyAction = getAction("Show History");
DockingActionIf historyAction = getAction("Show History");
runSwing(() -> historyAction.actionPerformed(getDomainFileActionContext(node)));
VersionHistoryDialog dialog = waitForDialogComponent(VersionHistoryDialog.class);
@@ -267,14 +268,9 @@ public class VersionControlAction2Test extends AbstractVersionControlActionTest
performAction(deleteAction, false);
// cannot delete a file that is checked out
OptionDialog d = waitForDialogComponent(OptionDialog.class);
assertNotNull(d);
MultiLineLabel label = findComponent(d.getComponent(), MultiLineLabel.class);
assertNotNull(label);
assertEquals("File version has one or more checkouts.", label.getLabel());
runSwing(() -> d.close());
AbstractErrDialog d = waitForErrorDialog();
assertEquals("File version has one or more checkouts.", d.getMessage());
close(d);
}
@Test
@@ -283,10 +279,10 @@ public class VersionControlAction2Test extends AbstractVersionControlActionTest
setErrorGUIEnabled(true);// expect an error dialog
doCreateVersions();
final GTreeNode node = getNode(PROGRAM_A);
GTreeNode node = getNode(PROGRAM_A);
selectNode(node);
final DockingActionIf historyAction = getAction("Show History");
DockingActionIf historyAction = getAction("Show History");
runSwing(() -> historyAction.actionPerformed(getDomainFileActionContext(node)));
VersionHistoryDialog dialog = waitForDialogComponent(VersionHistoryDialog.class);
@@ -297,17 +293,10 @@ public class VersionControlAction2Test extends AbstractVersionControlActionTest
performAction(deleteAction, false);
// can delete only the first or last version of the file
OptionDialog d = waitForDialogComponent(OptionDialog.class);
assertNotNull(d);
MultiLineLabel label = findComponent(d.getComponent(), MultiLineLabel.class);
assertNotNull(label);
assertEquals("Only first and last version may be deleted.", label.getLabel());
runSwing(() -> {
d.close();
dialog.close();
});
AbstractErrDialog d = waitForErrorDialog();
assertEquals("Only first and last version may be deleted.", d.getMessage());
close(d);
close(dialog);
}
@Test
@@ -341,7 +330,7 @@ public class VersionControlAction2Test extends AbstractVersionControlActionTest
assertEquals(rowCount - 1, table.getRowCount());
runSwing(() -> dialog.close());
close(dialog);
}
@Test
@@ -371,7 +360,7 @@ public class VersionControlAction2Test extends AbstractVersionControlActionTest
FindCheckoutsDialog dialog = waitForDialogComponent(FindCheckoutsDialog.class);
assertNotNull(dialog);
final GTable table = findComponent(dialog.getComponent(), GTable.class);
GTable table = findComponent(dialog.getComponent(), GTable.class);
assertNotNull(table);
waitForBusyTable(table);