mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
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:
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>")) {
|
if (message != null && message.toLowerCase().startsWith("<html>")) {
|
||||||
JEditorPane editorPane = new JEditorPane();
|
JEditorPane editorPane = new JEditorPane();
|
||||||
editorPane.setEditorKit(new HTMLEditorKit());
|
editorPane.setEditorKit(new HTMLEditorKit());
|
||||||
editorPane.setName("MESSAGE-COMPONENT");
|
editorPane.setName(MESSAGE_COMPONENT_NAME);
|
||||||
editorPane.setText(message);
|
editorPane.setText(message);
|
||||||
|
|
||||||
editorPane.setBackground(new GLabel().getBackground());
|
editorPane.setBackground(new GLabel().getBackground());
|
||||||
|
|
|
@ -15,6 +15,10 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.datamgr.actions;
|
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.*;
|
||||||
import ghidra.app.plugin.core.datamgr.archive.DataTypeManagerHandler;
|
import ghidra.app.plugin.core.datamgr.archive.DataTypeManagerHandler;
|
||||||
import ghidra.app.plugin.core.datamgr.tree.ArchiveNode;
|
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.program.model.data.SourceArchive;
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
import ghidra.util.Msg;
|
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 {
|
public class SyncRefreshAction extends DockingAction {
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ public class SyncRefreshAction extends DockingAction {
|
||||||
getClass(),
|
getClass(),
|
||||||
plugin.getTool().getToolFrame(),
|
plugin.getTool().getToolFrame(),
|
||||||
"Refresh Completed",
|
"Refresh Completed",
|
||||||
"Sync indicators refresh for " + dtm.getName() + " to archive \"" +
|
"Sync indicators have been refreshed between " + dtm.getName() + " and archive \"" +
|
||||||
sourceArchive.getName() + "\".");
|
sourceArchive.getName() + "\".");
|
||||||
|
|
||||||
tree.restoreTreeState(treeState);
|
tree.restoreTreeState(treeState);
|
||||||
|
|
|
@ -24,7 +24,6 @@ import java.util.regex.Pattern;
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
|
|
||||||
import docking.*;
|
import docking.*;
|
||||||
import docking.action.DockingAction;
|
|
||||||
import docking.action.builder.ActionBuilder;
|
import docking.action.builder.ActionBuilder;
|
||||||
import docking.tool.ToolConstants;
|
import docking.tool.ToolConstants;
|
||||||
import docking.widgets.fieldpanel.support.Highlight;
|
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 static final String DESCRIPTION = "Search program text for string";
|
||||||
private final static int DEFAULT_SEARCH_LIMIT = 500;
|
private final static int DEFAULT_SEARCH_LIMIT = 500;
|
||||||
private final static Highlight[] NO_HIGHLIGHTS = new Highlight[0];
|
private final static Highlight[] NO_HIGHLIGHTS = new Highlight[0];
|
||||||
private DockingAction searchAction;
|
|
||||||
private DockingAction searchAgainAction;
|
|
||||||
|
|
||||||
private boolean waitingForSearchAll;
|
private boolean waitingForSearchAll;
|
||||||
private SearchTextDialog searchDialog;
|
private SearchTextDialog searchDialog;
|
||||||
|
@ -379,7 +376,7 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
|
||||||
private void createActions() {
|
private void createActions() {
|
||||||
String subGroup = getClass().getName();
|
String subGroup = getClass().getName();
|
||||||
|
|
||||||
searchAction = new ActionBuilder("Search Text", getName())
|
new ActionBuilder("Search Text", getName())
|
||||||
.menuPath("&Search", "Program &Text...")
|
.menuPath("&Search", "Program &Text...")
|
||||||
.menuGroup("search", subGroup)
|
.menuGroup("search", subGroup)
|
||||||
.keyBinding("ctrl shift E")
|
.keyBinding("ctrl shift E")
|
||||||
|
@ -393,7 +390,7 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
|
||||||
})
|
})
|
||||||
.buildAndInstall(tool);
|
.buildAndInstall(tool);
|
||||||
|
|
||||||
searchAgainAction = new ActionBuilder("Repeat Text Search", getName())
|
new ActionBuilder("Repeat Text Search", getName())
|
||||||
.menuPath("&Search", "Repeat Text Search")
|
.menuPath("&Search", "Repeat Text Search")
|
||||||
.menuGroup("search", subGroup)
|
.menuGroup("search", subGroup)
|
||||||
.keyBinding("ctrl shift F3")
|
.keyBinding("ctrl shift F3")
|
||||||
|
|
|
@ -145,7 +145,7 @@ public abstract class AbstractMergeTest extends AbstractGhidraHeadedIntegrationT
|
||||||
|
|
||||||
List<Dialog> modals =
|
List<Dialog> modals =
|
||||||
WindowUtilities.getOpenModalDialogsFor(mergeMgr.getMergeTool().getToolFrame());
|
WindowUtilities.getOpenModalDialogsFor(mergeMgr.getMergeTool().getToolFrame());
|
||||||
Msg.debug(this, "Open modal dialog: ");
|
Msg.debug(this, "Open modal dialogs: ");
|
||||||
for (Dialog dialog : modals) {
|
for (Dialog dialog : modals) {
|
||||||
capture(dialog);
|
capture(dialog);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@ import ghidra.program.model.data.*;
|
||||||
import ghidra.program.model.data.Enum;
|
import ghidra.program.model.data.Enum;
|
||||||
import ghidra.util.exception.DuplicateNameException;
|
import ghidra.util.exception.DuplicateNameException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
import ghidra.util.task.TaskMonitorAdapter;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* More data type merge tests.
|
* More data type merge tests.
|
||||||
|
@ -46,7 +45,7 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
|
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
|
// 2 components should get removed from CoolUnion
|
||||||
commit = true;
|
commit = true;
|
||||||
}
|
}
|
||||||
|
@ -119,7 +118,7 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
|
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
|
// 2 components should get removed from CoolUnion
|
||||||
commit = true;
|
commit = true;
|
||||||
}
|
}
|
||||||
|
@ -192,7 +191,7 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
|
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
|
// 2 components should get removed from CoolUnion
|
||||||
commit = true;
|
commit = true;
|
||||||
}
|
}
|
||||||
|
@ -573,7 +572,7 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
||||||
DataType dt =
|
DataType dt =
|
||||||
dtm.getDataType(new CategoryPath("/Category1/Category2"), "Structure_1");
|
dtm.getDataType(new CategoryPath("/Category1/Category2"), "Structure_1");
|
||||||
try {
|
try {
|
||||||
dtm.remove(dt, TaskMonitorAdapter.DUMMY);
|
dtm.remove(dt, TaskMonitor.DUMMY);
|
||||||
commit = true;
|
commit = true;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
@ -649,7 +648,7 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
||||||
DataType dt =
|
DataType dt =
|
||||||
dtm.getDataType(new CategoryPath("/Category1/Category2"), "Structure_1");
|
dtm.getDataType(new CategoryPath("/Category1/Category2"), "Structure_1");
|
||||||
try {
|
try {
|
||||||
dtm.remove(dt, TaskMonitorAdapter.DUMMY);
|
dtm.remove(dt, TaskMonitor.DUMMY);
|
||||||
// causes Bar to be marked as changed
|
// causes Bar to be marked as changed
|
||||||
commit = true;
|
commit = true;
|
||||||
}
|
}
|
||||||
|
@ -724,7 +723,7 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
||||||
DataType dt =
|
DataType dt =
|
||||||
dtm.getDataType(new CategoryPath("/Category1/Category2"), "Structure_1");
|
dtm.getDataType(new CategoryPath("/Category1/Category2"), "Structure_1");
|
||||||
try {
|
try {
|
||||||
dtm.remove(dt, TaskMonitorAdapter.DUMMY);
|
dtm.remove(dt, TaskMonitor.DUMMY);
|
||||||
// causes Bar to be marked as changed
|
// causes Bar to be marked as changed
|
||||||
commit = true;
|
commit = true;
|
||||||
}
|
}
|
||||||
|
@ -801,7 +800,7 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
||||||
Structure ms = (Structure) dtm.getDataType(new CategoryPath("/Category1/Category2"),
|
Structure ms = (Structure) dtm.getDataType(new CategoryPath("/Category1/Category2"),
|
||||||
"MyStruct");
|
"MyStruct");
|
||||||
try {
|
try {
|
||||||
dtm.remove(dt, TaskMonitorAdapter.DUMMY);
|
dtm.remove(dt, TaskMonitor.DUMMY);
|
||||||
Structure s1 = new StructureDataType(
|
Structure s1 = new StructureDataType(
|
||||||
new CategoryPath("/Category1/Category2/Category5"), "s1", 0);
|
new CategoryPath("/Category1/Category2/Category5"), "s1", 0);
|
||||||
s1.add(ms);
|
s1.add(ms);
|
||||||
|
@ -916,7 +915,7 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
||||||
int transactionID = program.startTransaction("test");
|
int transactionID = program.startTransaction("test");
|
||||||
DataType dt = dtm.getDataType(new CategoryPath("/Category1/Category2"), "BF");
|
DataType dt = dtm.getDataType(new CategoryPath("/Category1/Category2"), "BF");
|
||||||
try {
|
try {
|
||||||
dtm.remove(dt, TaskMonitorAdapter.DUMMY);
|
dtm.remove(dt, TaskMonitor.DUMMY);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
program.endTransaction(transactionID, true);
|
program.endTransaction(transactionID, true);
|
||||||
|
@ -1260,7 +1259,7 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
|
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
|
// 2 components should get removed from CoolUnion
|
||||||
commit = true;
|
commit = true;
|
||||||
}
|
}
|
||||||
|
@ -1353,7 +1352,7 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
|
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
|
// 2 components should get removed from CoolUnion
|
||||||
commit = true;
|
commit = true;
|
||||||
}
|
}
|
||||||
|
@ -1436,10 +1435,10 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
|
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
|
||||||
dtm.remove(s, TaskMonitorAdapter.DUMMY);
|
dtm.remove(s, TaskMonitor.DUMMY);
|
||||||
DataType dt =
|
DataType dt =
|
||||||
dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
||||||
dtm.remove(dt, TaskMonitorAdapter.DUMMY);
|
dtm.remove(dt, TaskMonitor.DUMMY);
|
||||||
commit = true;
|
commit = true;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
@ -1524,10 +1523,10 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
|
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
|
||||||
dtm.remove(s, TaskMonitorAdapter.DUMMY);
|
dtm.remove(s, TaskMonitor.DUMMY);
|
||||||
DataType dt =
|
DataType dt =
|
||||||
dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
||||||
dtm.remove(dt, TaskMonitorAdapter.DUMMY);
|
dtm.remove(dt, TaskMonitor.DUMMY);
|
||||||
commit = true;
|
commit = true;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
@ -1613,10 +1612,10 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
|
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
|
||||||
dtm.remove(s, TaskMonitorAdapter.DUMMY);
|
dtm.remove(s, TaskMonitor.DUMMY);
|
||||||
DataType dt =
|
DataType dt =
|
||||||
dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
||||||
dtm.remove(dt, TaskMonitorAdapter.DUMMY);
|
dtm.remove(dt, TaskMonitor.DUMMY);
|
||||||
commit = true;
|
commit = true;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
@ -1701,10 +1700,10 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
|
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
|
||||||
dtm.remove(s, TaskMonitorAdapter.DUMMY);
|
dtm.remove(s, TaskMonitor.DUMMY);
|
||||||
DataType dt =
|
DataType dt =
|
||||||
dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
||||||
dtm.remove(dt, TaskMonitorAdapter.DUMMY);
|
dtm.remove(dt, TaskMonitor.DUMMY);
|
||||||
commit = true;
|
commit = true;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
@ -1795,10 +1794,10 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
|
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
|
||||||
dtm.remove(s, TaskMonitorAdapter.DUMMY);
|
dtm.remove(s, TaskMonitor.DUMMY);
|
||||||
DataType dt =
|
DataType dt =
|
||||||
dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
||||||
dtm.remove(dt, TaskMonitorAdapter.DUMMY);
|
dtm.remove(dt, TaskMonitor.DUMMY);
|
||||||
commit = true;
|
commit = true;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
@ -1897,10 +1896,10 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
|
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
|
||||||
dtm.remove(s, TaskMonitorAdapter.DUMMY);
|
dtm.remove(s, TaskMonitor.DUMMY);
|
||||||
DataType dt =
|
DataType dt =
|
||||||
dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
||||||
dtm.remove(dt, TaskMonitorAdapter.DUMMY);
|
dtm.remove(dt, TaskMonitor.DUMMY);
|
||||||
commit = true;
|
commit = true;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
|
|
@ -755,8 +755,4 @@ public class StructureEditorProviderTest extends AbstractStructureEditorTest {
|
||||||
assertEquals("325", model.getLengthAsString());
|
assertEquals("325", model.getLengthAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runSwingLater(Runnable r) {
|
|
||||||
runSwing(r, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.datamgr.editor;
|
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.*;
|
||||||
import static ghidra.app.plugin.core.datamgr.editor.EnumTableModel.VALUE_COL;
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
@ -42,7 +41,7 @@ import ghidra.program.model.data.Enum;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.model.symbol.EquateTable;
|
import ghidra.program.model.symbol.EquateTable;
|
||||||
import ghidra.test.*;
|
import ghidra.test.*;
|
||||||
import ghidra.util.task.TaskMonitorAdapter;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for editing an Enumerated data type.
|
* Tests for editing an Enumerated data type.
|
||||||
|
@ -54,10 +53,6 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
private TestEnv env;
|
private TestEnv env;
|
||||||
private DataTypeManagerPlugin plugin;
|
private DataTypeManagerPlugin plugin;
|
||||||
|
|
||||||
public EnumEditor1Test() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
env = new TestEnv();
|
env = new TestEnv();
|
||||||
|
@ -80,7 +75,9 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEnumFields() throws Exception {
|
public void testEnumFields() throws Exception {
|
||||||
Category c = program.getListing().getDataTypeManager().getCategory(
|
Category c = program.getListing()
|
||||||
|
.getDataTypeManager()
|
||||||
|
.getCategory(
|
||||||
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
||||||
Enum enumm = createEnum(c, "TestEnum", 1);
|
Enum enumm = createEnum(c, "TestEnum", 1);
|
||||||
edit(enumm);
|
edit(enumm);
|
||||||
|
@ -133,7 +130,9 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEnumSize1() throws Exception {
|
public void testEnumSize1() throws Exception {
|
||||||
Category category = program.getListing().getDataTypeManager().getCategory(
|
Category category = program.getListing()
|
||||||
|
.getDataTypeManager()
|
||||||
|
.getCategory(
|
||||||
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
||||||
Enum enumm = createEnum(category, "TestEnum", 1);
|
Enum enumm = createEnum(category, "TestEnum", 1);
|
||||||
edit(enumm);
|
edit(enumm);
|
||||||
|
@ -183,7 +182,9 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
@Test
|
@Test
|
||||||
public void testEnumSize1BadInput() throws Exception {
|
public void testEnumSize1BadInput() throws Exception {
|
||||||
// test entering too large a value
|
// test entering too large a value
|
||||||
Category category = program.getListing().getDataTypeManager().getCategory(
|
Category category = program.getListing()
|
||||||
|
.getDataTypeManager()
|
||||||
|
.getCategory(
|
||||||
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
||||||
Enum enumm = createEnum(category, "TestEnum", 1);
|
Enum enumm = createEnum(category, "TestEnum", 1);
|
||||||
edit(enumm);
|
edit(enumm);
|
||||||
|
@ -225,7 +226,9 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEnumSize4BadInput() throws Exception {
|
public void testEnumSize4BadInput() throws Exception {
|
||||||
Category category = program.getListing().getDataTypeManager().getCategory(
|
Category category = program.getListing()
|
||||||
|
.getDataTypeManager()
|
||||||
|
.getCategory(
|
||||||
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
||||||
Enum enumm = createEnum(category, "MyTestEnum", 4);
|
Enum enumm = createEnum(category, "MyTestEnum", 4);
|
||||||
edit(enumm);
|
edit(enumm);
|
||||||
|
@ -275,7 +278,9 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBadInputForValue() throws Exception {
|
public void testBadInputForValue() throws Exception {
|
||||||
Category cat = program.getListing().getDataTypeManager().getCategory(
|
Category cat = program.getListing()
|
||||||
|
.getDataTypeManager()
|
||||||
|
.getCategory(
|
||||||
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
||||||
Enum enumm = createEnum(cat, "TestEnum", 1);
|
Enum enumm = createEnum(cat, "TestEnum", 1);
|
||||||
edit(enumm);
|
edit(enumm);
|
||||||
|
@ -303,7 +308,9 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
@Test
|
@Test
|
||||||
public void testEditExistingEnum1() throws Exception {
|
public void testEditExistingEnum1() throws Exception {
|
||||||
|
|
||||||
Category cat = program.getListing().getDataTypeManager().getCategory(
|
Category cat = program.getListing()
|
||||||
|
.getDataTypeManager()
|
||||||
|
.getCategory(
|
||||||
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
||||||
final Enum enumm = new EnumDataType("Colors", 1);
|
final Enum enumm = new EnumDataType("Colors", 1);
|
||||||
enumm.add("Red", 0);
|
enumm.add("Red", 0);
|
||||||
|
@ -366,7 +373,9 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testValueForNewEntry() throws Exception {
|
public void testValueForNewEntry() throws Exception {
|
||||||
Category cat = program.getListing().getDataTypeManager().getCategory(
|
Category cat = program.getListing()
|
||||||
|
.getDataTypeManager()
|
||||||
|
.getCategory(
|
||||||
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
||||||
final Enum enumm = new EnumDataType("Colors", 1);
|
final Enum enumm = new EnumDataType("Colors", 1);
|
||||||
enumm.add("Red", 0x10);
|
enumm.add("Red", 0x10);
|
||||||
|
@ -521,10 +530,7 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
removeCategory(enummDt);
|
removeCategory(enummDt);
|
||||||
|
|
||||||
OptionDialog dialog =
|
close(waitForErrorDialog());
|
||||||
waitForDialogComponent(null, OptionDialog.class, DEFAULT_WINDOW_TIMEOUT);
|
|
||||||
assertNotNull(dialog);
|
|
||||||
pressButtonByText(dialog.getComponent(), "OK");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -564,10 +570,7 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
replaceDataType(enummDt, newEnummDt);
|
replaceDataType(enummDt, newEnummDt);
|
||||||
|
|
||||||
OptionDialog dialog =
|
close(waitForErrorDialog());
|
||||||
waitForDialogComponent(null, OptionDialog.class, DEFAULT_WINDOW_TIMEOUT);
|
|
||||||
assertNotNull(dialog);
|
|
||||||
pressButtonByText(dialog.getComponent(), "OK");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -612,15 +615,12 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
DataTypeManager dtm = program.getDataTypeManager();
|
DataTypeManager dtm = program.getDataTypeManager();
|
||||||
int transactionID = program.startTransaction("Test");
|
int transactionID = program.startTransaction("Test");
|
||||||
dtm.remove(enummDt, TaskMonitorAdapter.DUMMY_MONITOR);
|
dtm.remove(enummDt, TaskMonitor.DUMMY);
|
||||||
program.endTransaction(transactionID, true);
|
program.endTransaction(transactionID, true);
|
||||||
program.flushEvents();
|
program.flushEvents();
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
|
|
||||||
OptionDialog optionDialog =
|
close(waitForErrorDialog());
|
||||||
waitForDialogComponent(null, OptionDialog.class, DEFAULT_WINDOW_TIMEOUT);
|
|
||||||
assertNotNull("Did not get informed of deleted enum", optionDialog);
|
|
||||||
pressButtonByText(optionDialog.getComponent(), "OK");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -762,7 +762,9 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
@Test
|
@Test
|
||||||
public void testChangeEnumSizeAndInStructure() throws Exception {
|
public void testChangeEnumSizeAndInStructure() throws Exception {
|
||||||
|
|
||||||
Category category = program.getListing().getDataTypeManager().getCategory(
|
Category category = program.getListing()
|
||||||
|
.getDataTypeManager()
|
||||||
|
.getCategory(
|
||||||
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
||||||
Enum enumm = createEnum(category, "EnumX", 2);
|
Enum enumm = createEnum(category, "EnumX", 2);
|
||||||
|
|
||||||
|
@ -803,7 +805,7 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
assertEquals(intValue, 2);
|
assertEquals(intValue, 2);
|
||||||
|
|
||||||
runSwing(() -> {
|
runSwing(() -> {
|
||||||
sizeComboBox.setSelectedItem(new Integer(4));
|
sizeComboBox.setSelectedItem(4);
|
||||||
});
|
});
|
||||||
apply();
|
apply();
|
||||||
|
|
||||||
|
@ -831,7 +833,9 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
@Test
|
@Test
|
||||||
public void testChangeEnumDescriptionEtcAndInStructure() throws Exception {
|
public void testChangeEnumDescriptionEtcAndInStructure() throws Exception {
|
||||||
|
|
||||||
Category category = program.getListing().getDataTypeManager().getCategory(
|
Category category = program.getListing()
|
||||||
|
.getDataTypeManager()
|
||||||
|
.getCategory(
|
||||||
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
||||||
Enum enumm = createEnum(category, "EnumX", 2);
|
Enum enumm = createEnum(category, "EnumX", 2);
|
||||||
|
|
||||||
|
@ -887,7 +891,7 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
runSwing(() -> {
|
runSwing(() -> {
|
||||||
nameField.setText("EnumY");
|
nameField.setText("EnumY");
|
||||||
descField.setText("XYZ");
|
descField.setText("XYZ");
|
||||||
sizeComboBox.setSelectedItem(new Integer(4));
|
sizeComboBox.setSelectedItem(4);
|
||||||
|
|
||||||
table.editCellAt(1, NAME_COL);
|
table.editCellAt(1, NAME_COL);
|
||||||
|
|
||||||
|
@ -1026,7 +1030,7 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
try {
|
try {
|
||||||
Category newCategory = dtm.createCategory(new CategoryPath("/Test/Category"));
|
Category newCategory = dtm.createCategory(new CategoryPath("/Test/Category"));
|
||||||
category = dtm.getCategory(enummDt.getCategoryPath());
|
category = dtm.getCategory(enummDt.getCategoryPath());
|
||||||
newCategory.moveCategory(category, TaskMonitorAdapter.DUMMY_MONITOR);
|
newCategory.moveCategory(category, TaskMonitor.DUMMY);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
program.endTransaction(txID, true);
|
program.endTransaction(txID, true);
|
||||||
|
@ -1046,7 +1050,7 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
Category category = dtm.getCategory(enummDt.getCategoryPath());
|
Category category = dtm.getCategory(enummDt.getCategoryPath());
|
||||||
Category parentCategory = category.getParent();
|
Category parentCategory = category.getParent();
|
||||||
assertTrue("Did not remove category", parentCategory.removeCategory(category.getName(),
|
assertTrue("Did not remove category", parentCategory.removeCategory(category.getName(),
|
||||||
TaskMonitorAdapter.DUMMY_MONITOR));
|
TaskMonitor.DUMMY));
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
program.endTransaction(txID, true);
|
program.endTransaction(txID, true);
|
||||||
|
@ -1138,7 +1142,9 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Enum createRedGreenBlueEnum() {
|
private Enum createRedGreenBlueEnum() {
|
||||||
Category cat = program.getListing().getDataTypeManager().getCategory(
|
Category cat = program.getListing()
|
||||||
|
.getDataTypeManager()
|
||||||
|
.getCategory(
|
||||||
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
||||||
final Enum enumm = new EnumDataType("Colors", 1);
|
final Enum enumm = new EnumDataType("Colors", 1);
|
||||||
enumm.add("Red", 0);
|
enumm.add("Red", 0);
|
||||||
|
@ -1274,7 +1280,7 @@ public class EnumEditor1Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
editValueInTable(0, "2");
|
editValueInTable(0, "2");
|
||||||
|
|
||||||
// This IS the warning dialog
|
// This IS the warning dialog
|
||||||
OptionDialog dialog = env.waitForDialogComponent(OptionDialog.class, 1000);
|
OptionDialog dialog = waitForDialogComponent(OptionDialog.class);
|
||||||
pressButtonByText(dialog, alsoRemove ? "Save and remove" : "Save");
|
pressButtonByText(dialog, alsoRemove ? "Save and remove" : "Save");
|
||||||
waitForTasks();
|
waitForTasks();
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,7 @@ import javax.swing.table.*;
|
||||||
|
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
|
|
||||||
import docking.ActionContext;
|
import docking.*;
|
||||||
import docking.ComponentProvider;
|
|
||||||
import docking.action.DockingActionIf;
|
import docking.action.DockingActionIf;
|
||||||
import docking.widgets.OptionDialog;
|
import docking.widgets.OptionDialog;
|
||||||
import ghidra.app.plugin.core.datamgr.DataTypeManagerPlugin;
|
import ghidra.app.plugin.core.datamgr.DataTypeManagerPlugin;
|
||||||
|
@ -69,7 +68,9 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
@Test
|
@Test
|
||||||
public void testInsertRow() throws Exception {
|
public void testInsertRow() throws Exception {
|
||||||
|
|
||||||
Category cat = program.getListing().getDataTypeManager().getCategory(
|
Category cat = program.getListing()
|
||||||
|
.getDataTypeManager()
|
||||||
|
.getCategory(
|
||||||
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
||||||
final Enum enumm = new EnumDataType("Colors", 1);
|
final Enum enumm = new EnumDataType("Colors", 1);
|
||||||
enumm.add("Red", 0);
|
enumm.add("Red", 0);
|
||||||
|
@ -80,10 +81,10 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
final Enum enumDt = (Enum) cat.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
|
final Enum enumDt = (Enum) cat.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||||
program.endTransaction(transactionID, true);
|
program.endTransaction(transactionID, true);
|
||||||
program.flushEvents();
|
program.flushEvents();
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
SwingUtilities.invokeLater(() -> plugin.edit(enumDt));
|
SwingUtilities.invokeLater(() -> plugin.edit(enumDt));
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
EnumEditorPanel panel = findEditorPanel(tool.getToolFrame());
|
EnumEditorPanel panel = findEditorPanel(tool.getToolFrame());
|
||||||
final JTable table = panel.getTable();
|
final JTable table = panel.getTable();
|
||||||
|
@ -104,7 +105,9 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSortColumns() throws Exception {
|
public void testSortColumns() throws Exception {
|
||||||
Category cat = program.getListing().getDataTypeManager().getCategory(
|
Category cat = program.getListing()
|
||||||
|
.getDataTypeManager()
|
||||||
|
.getCategory(
|
||||||
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
||||||
final Enum enumm = new EnumDataType("Colors", 1);
|
final Enum enumm = new EnumDataType("Colors", 1);
|
||||||
enumm.add("Red", 0);
|
enumm.add("Red", 0);
|
||||||
|
@ -115,10 +118,10 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
final Enum enummDt = (Enum) cat.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
|
final Enum enummDt = (Enum) cat.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||||
program.endTransaction(transactionID, true);
|
program.endTransaction(transactionID, true);
|
||||||
program.flushEvents();
|
program.flushEvents();
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
SwingUtilities.invokeLater(() -> plugin.edit(enummDt));
|
SwingUtilities.invokeLater(() -> plugin.edit(enummDt));
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
EnumEditorPanel panel = findEditorPanel(tool.getToolFrame());
|
EnumEditorPanel panel = findEditorPanel(tool.getToolFrame());
|
||||||
final JTable table = panel.getTable();
|
final JTable table = panel.getTable();
|
||||||
|
@ -128,7 +131,7 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
JTableHeader header = table.getTableHeader();
|
JTableHeader header = table.getTableHeader();
|
||||||
Rectangle rect = header.getHeaderRect(EnumTableModel.NAME_COL);
|
Rectangle rect = header.getHeaderRect(EnumTableModel.NAME_COL);
|
||||||
clickMouse(header, 1, rect.x, rect.y, 1, 0);
|
clickMouse(header, 1, rect.x, rect.y, 1, 0);
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
assertEquals("Blue", model.getValueAt(0, EnumTableModel.NAME_COL));
|
assertEquals("Blue", model.getValueAt(0, EnumTableModel.NAME_COL));
|
||||||
assertEquals("Green", model.getValueAt(1, EnumTableModel.NAME_COL));
|
assertEquals("Green", model.getValueAt(1, EnumTableModel.NAME_COL));
|
||||||
|
@ -137,7 +140,7 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
// sort by Value
|
// sort by Value
|
||||||
rect = header.getHeaderRect(EnumTableModel.VALUE_COL);
|
rect = header.getHeaderRect(EnumTableModel.VALUE_COL);
|
||||||
clickMouse(header, 1, rect.x, rect.y, 1, 0);
|
clickMouse(header, 1, rect.x, rect.y, 1, 0);
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
assertEquals("Red", model.getValueAt(0, EnumTableModel.NAME_COL));
|
assertEquals("Red", model.getValueAt(0, EnumTableModel.NAME_COL));
|
||||||
assertEquals("Green", model.getValueAt(1, EnumTableModel.NAME_COL));
|
assertEquals("Green", model.getValueAt(1, EnumTableModel.NAME_COL));
|
||||||
|
@ -146,7 +149,9 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSortOrder() throws Exception {
|
public void testSortOrder() throws Exception {
|
||||||
Category cat = program.getListing().getDataTypeManager().getCategory(
|
Category cat = program.getListing()
|
||||||
|
.getDataTypeManager()
|
||||||
|
.getCategory(
|
||||||
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
||||||
final Enum enumm = new EnumDataType("Colors", 1);
|
final Enum enumm = new EnumDataType("Colors", 1);
|
||||||
enumm.add("Red", 0);
|
enumm.add("Red", 0);
|
||||||
|
@ -157,10 +162,10 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
final Enum enummDt = (Enum) cat.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
|
final Enum enummDt = (Enum) cat.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||||
program.endTransaction(transactionID, true);
|
program.endTransaction(transactionID, true);
|
||||||
program.flushEvents();
|
program.flushEvents();
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
SwingUtilities.invokeLater(() -> plugin.edit(enummDt));
|
SwingUtilities.invokeLater(() -> plugin.edit(enummDt));
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
EnumEditorPanel panel = findEditorPanel(tool.getToolFrame());
|
EnumEditorPanel panel = findEditorPanel(tool.getToolFrame());
|
||||||
final JTable table = panel.getTable();
|
final JTable table = panel.getTable();
|
||||||
|
@ -170,7 +175,7 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
JTableHeader header = table.getTableHeader();
|
JTableHeader header = table.getTableHeader();
|
||||||
Rectangle rect = header.getHeaderRect(EnumTableModel.VALUE_COL);
|
Rectangle rect = header.getHeaderRect(EnumTableModel.VALUE_COL);
|
||||||
clickMouse(header, 1, rect.x, rect.y, 1, 0);
|
clickMouse(header, 1, rect.x, rect.y, 1, 0);
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
assertEquals("0x20", model.getValueAt(0, EnumTableModel.VALUE_COL));
|
assertEquals("0x20", model.getValueAt(0, EnumTableModel.VALUE_COL));
|
||||||
assertEquals("0x10", model.getValueAt(1, EnumTableModel.VALUE_COL));
|
assertEquals("0x10", model.getValueAt(1, EnumTableModel.VALUE_COL));
|
||||||
|
@ -179,10 +184,10 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
// sort by Name
|
// sort by Name
|
||||||
rect = header.getHeaderRect(EnumTableModel.NAME_COL);
|
rect = header.getHeaderRect(EnumTableModel.NAME_COL);
|
||||||
clickMouse(header, 1, rect.x, rect.y, 1, 0);
|
clickMouse(header, 1, rect.x, rect.y, 1, 0);
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
// sort Descending
|
// sort Descending
|
||||||
clickMouse(header, 1, rect.x, rect.y, 1, 0);
|
clickMouse(header, 1, rect.x, rect.y, 1, 0);
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
assertEquals("Red", model.getValueAt(0, EnumTableModel.NAME_COL));
|
assertEquals("Red", model.getValueAt(0, EnumTableModel.NAME_COL));
|
||||||
assertEquals("Green", model.getValueAt(1, EnumTableModel.NAME_COL));
|
assertEquals("Green", model.getValueAt(1, EnumTableModel.NAME_COL));
|
||||||
assertEquals("Blue", model.getValueAt(2, EnumTableModel.NAME_COL));
|
assertEquals("Blue", model.getValueAt(2, EnumTableModel.NAME_COL));
|
||||||
|
@ -190,7 +195,9 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInsertRowByName() throws Exception {
|
public void testInsertRowByName() throws Exception {
|
||||||
Category cat = program.getListing().getDataTypeManager().getCategory(
|
Category cat = program.getListing()
|
||||||
|
.getDataTypeManager()
|
||||||
|
.getCategory(
|
||||||
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
||||||
final Enum enumm = new EnumDataType("Colors", 1);
|
final Enum enumm = new EnumDataType("Colors", 1);
|
||||||
enumm.add("Red", 0);
|
enumm.add("Red", 0);
|
||||||
|
@ -201,10 +208,10 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
final Enum enummDt = (Enum) cat.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
|
final Enum enummDt = (Enum) cat.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||||
program.endTransaction(transactionID, true);
|
program.endTransaction(transactionID, true);
|
||||||
program.flushEvents();
|
program.flushEvents();
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
SwingUtilities.invokeLater(() -> plugin.edit(enummDt));
|
SwingUtilities.invokeLater(() -> plugin.edit(enummDt));
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
EnumEditorPanel panel = findEditorPanel(tool.getToolFrame());
|
EnumEditorPanel panel = findEditorPanel(tool.getToolFrame());
|
||||||
final JTable table = panel.getTable();
|
final JTable table = panel.getTable();
|
||||||
|
@ -214,7 +221,7 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
JTableHeader header = table.getTableHeader();
|
JTableHeader header = table.getTableHeader();
|
||||||
Rectangle rect = header.getHeaderRect(EnumTableModel.NAME_COL);
|
Rectangle rect = header.getHeaderRect(EnumTableModel.NAME_COL);
|
||||||
clickMouse(header, 1, rect.x, rect.y, 1, 0);
|
clickMouse(header, 1, rect.x, rect.y, 1, 0);
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
// insert "Cyan"
|
// insert "Cyan"
|
||||||
addEntry(table, model, "Cyan", 0x30);
|
addEntry(table, model, "Cyan", 0x30);
|
||||||
|
@ -236,16 +243,16 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
final DockingActionIf deleteAction = getAction(plugin, "Delete Enum Value");
|
final DockingActionIf deleteAction = getAction(plugin, "Delete Enum Value");
|
||||||
assertTrue(deleteAction.isEnabled());
|
assertTrue(deleteAction.isEnabled());
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> deleteAction.actionPerformed(new ActionContext()));
|
runSwing(() -> deleteAction.actionPerformed(new ActionContext()));
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
assertTrue(table.isRowSelected(3));
|
assertTrue(table.isRowSelected(3));
|
||||||
|
|
||||||
final DockingActionIf applyAction = getAction(plugin, "Apply Enum Changes");
|
final DockingActionIf applyAction = getAction(plugin, "Apply Enum Changes");
|
||||||
assertTrue(applyAction.isEnabled());
|
assertTrue(applyAction.isEnabled());
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> applyAction.actionPerformed(new ActionContext()));
|
runSwing(() -> applyAction.actionPerformed(new ActionContext()));
|
||||||
program.flushEvents();
|
program.flushEvents();
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
assertEquals(4, model.getRowCount());
|
assertEquals(4, model.getRowCount());
|
||||||
assertEquals(4, enummDt.getCount());
|
assertEquals(4, enummDt.getCount());
|
||||||
|
@ -265,8 +272,8 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> deleteAction.actionPerformed(new ActionContext()));
|
runSwing(() -> deleteAction.actionPerformed(new ActionContext()));
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
}
|
}
|
||||||
assertEquals(0, model.getRowCount());
|
assertEquals(0, model.getRowCount());
|
||||||
// add an entry so the tear down works properly
|
// add an entry so the tear down works properly
|
||||||
|
@ -287,8 +294,8 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> deleteAction.actionPerformed(new ActionContext()));
|
runSwing(() -> deleteAction.actionPerformed(new ActionContext()));
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
}
|
}
|
||||||
applyChanges(true);
|
applyChanges(true);
|
||||||
Window w = windowForComponent(table);
|
Window w = windowForComponent(table);
|
||||||
|
@ -313,20 +320,20 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> deleteAction.actionPerformed(new ActionContext()));
|
runSwing(() -> deleteAction.actionPerformed(new ActionContext()));
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
}
|
}
|
||||||
|
|
||||||
final ComponentProvider provider =
|
final ComponentProvider provider =
|
||||||
waitForComponentProvider(tool.getToolFrame(), EnumEditorProvider.class, 1500);
|
waitForComponentProvider(EnumEditorProvider.class);
|
||||||
assertNotNull(provider);
|
assertNotNull(provider);
|
||||||
SwingUtilities.invokeLater(() -> provider.closeComponent());
|
SwingUtilities.invokeLater(() -> provider.closeComponent());
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
Window w = windowForComponent(table);
|
Window w = windowForComponent(table);
|
||||||
OptionDialog d = waitForDialogComponent(tool.getToolFrame(), OptionDialog.class, 2000);
|
OptionDialog d = waitForDialogComponent(OptionDialog.class);
|
||||||
assertNotNull(d);
|
assertNotNull(d);
|
||||||
pressButtonByText(d.getComponent(), "Yes");
|
pressButtonByText(d.getComponent(), "Yes");
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
assertTrue(tool.isVisible(provider));
|
assertTrue(tool.isVisible(provider));
|
||||||
String str = findLabelStr(w, "Tool Status");
|
String str = findLabelStr(w, "Tool Status");
|
||||||
|
@ -349,19 +356,19 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> deleteAction.actionPerformed(new ActionContext()));
|
runSwing(() -> deleteAction.actionPerformed(new ActionContext()));
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
}
|
}
|
||||||
|
|
||||||
final ComponentProvider provider =
|
final ComponentProvider provider =
|
||||||
waitForComponentProvider(tool.getToolFrame(), EnumEditorProvider.class, 1500);
|
waitForComponentProvider(EnumEditorProvider.class);
|
||||||
assertNotNull(provider);
|
assertNotNull(provider);
|
||||||
SwingUtilities.invokeLater(() -> provider.closeComponent());
|
SwingUtilities.invokeLater(() -> provider.closeComponent());
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
OptionDialog d = waitForDialogComponent(tool.getToolFrame(), OptionDialog.class, 2000);
|
OptionDialog d = waitForDialogComponent(OptionDialog.class);
|
||||||
assertNotNull(d);
|
assertNotNull(d);
|
||||||
pressButtonByText(d.getComponent(), "No");
|
pressButtonByText(d.getComponent(), "No");
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
assertTrue(!tool.isVisible(provider));
|
assertTrue(!tool.isVisible(provider));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,19 +386,19 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> deleteAction.actionPerformed(new ActionContext()));
|
runSwing(() -> deleteAction.actionPerformed(new ActionContext()));
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
}
|
}
|
||||||
|
|
||||||
final ComponentProvider provider =
|
final ComponentProvider provider =
|
||||||
waitForComponentProvider(tool.getToolFrame(), EnumEditorProvider.class, 1500);
|
waitForComponentProvider(EnumEditorProvider.class);
|
||||||
assertNotNull(provider);
|
assertNotNull(provider);
|
||||||
SwingUtilities.invokeLater(() -> provider.closeComponent());
|
SwingUtilities.invokeLater(() -> provider.closeComponent());
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
OptionDialog d = waitForDialogComponent(tool.getToolFrame(), OptionDialog.class, 2000);
|
OptionDialog d = waitForDialogComponent(OptionDialog.class);
|
||||||
assertNotNull(d);
|
assertNotNull(d);
|
||||||
pressButtonByText(d.getComponent(), "Cancel");
|
pressButtonByText(d.getComponent(), "Cancel");
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
assertTrue(tool.isVisible(provider));
|
assertTrue(tool.isVisible(provider));
|
||||||
|
|
||||||
// add an entry so the tear down works properly
|
// add an entry so the tear down works properly
|
||||||
|
@ -412,17 +419,17 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
final DockingActionIf deleteAction = getAction(plugin, "Delete Enum Value");
|
final DockingActionIf deleteAction = getAction(plugin, "Delete Enum Value");
|
||||||
assertTrue(deleteAction.isEnabled());
|
assertTrue(deleteAction.isEnabled());
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> deleteAction.actionPerformed(new ActionContext()));
|
runSwing(() -> deleteAction.actionPerformed(new ActionContext()));
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
assertTrue(table.isRowSelected(0));
|
assertTrue(table.isRowSelected(0));
|
||||||
|
|
||||||
final DockingActionIf applyAction = getAction(plugin, "Apply Enum Changes");
|
final DockingActionIf applyAction = getAction(plugin, "Apply Enum Changes");
|
||||||
assertTrue(applyAction.isEnabled());
|
assertTrue(applyAction.isEnabled());
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> applyAction.actionPerformed(new ActionContext()));
|
runSwing(() -> applyAction.actionPerformed(new ActionContext()));
|
||||||
program.flushEvents();
|
program.flushEvents();
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
assertEquals(5, model.getRowCount());
|
assertEquals(5, model.getRowCount());
|
||||||
assertEquals(5, enummDt.getCount());
|
assertEquals(5, enummDt.getCount());
|
||||||
|
@ -434,11 +441,11 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
final EnumEditorPanel panel = findEditorPanel(tool.getToolFrame());
|
final EnumEditorPanel panel = findEditorPanel(tool.getToolFrame());
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> {
|
runSwing(() -> {
|
||||||
JTextField nameField = getTextField(panel, "Name");
|
JTextField nameField = getTextField(panel, "Name");
|
||||||
nameField.setText("MyColors");
|
nameField.setText("MyColors");
|
||||||
});
|
});
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
applyChanges(true);
|
applyChanges(true);
|
||||||
assertEquals("MyColors", enummDt.getName());
|
assertEquals("MyColors", enummDt.getName());
|
||||||
}
|
}
|
||||||
|
@ -446,7 +453,9 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
@Test
|
@Test
|
||||||
public void testDuplicateName() throws Exception {
|
public void testDuplicateName() throws Exception {
|
||||||
|
|
||||||
Category cat = program.getListing().getDataTypeManager().getCategory(
|
Category cat = program.getListing()
|
||||||
|
.getDataTypeManager()
|
||||||
|
.getCategory(
|
||||||
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
||||||
final Enum enumm = new EnumDataType("Colors", 1);
|
final Enum enumm = new EnumDataType("Colors", 1);
|
||||||
enumm.add("Red", 0);
|
enumm.add("Red", 0);
|
||||||
|
@ -467,29 +476,28 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
program.endTransaction(transactionID, true);
|
program.endTransaction(transactionID, true);
|
||||||
program.flushEvents();
|
program.flushEvents();
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
SwingUtilities.invokeLater(() -> plugin.edit(enummDt));
|
runSwing(() -> plugin.edit(enummDt), false);
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
final EnumEditorPanel panel = findEditorPanel(tool.getToolFrame());
|
EnumEditorPanel panel = findEditorPanel(tool.getToolFrame());
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> {
|
runSwing(() -> {
|
||||||
JTextField nameField = getTextField(panel, "Name");
|
JTextField nameField = getTextField(panel, "Name");
|
||||||
nameField.setText("FavoriteColors");
|
nameField.setText("FavoriteColors");
|
||||||
});
|
});
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
applyChanges(false);
|
applyChanges(false);
|
||||||
Window window = windowForComponent(panel);
|
DialogComponentProvider dialog = waitForErrorDialog();
|
||||||
final OptionDialog d = waitForDialogComponent(window, OptionDialog.class, 2000);
|
assertNotNull(dialog);
|
||||||
assertNotNull(d);
|
assertEquals("Duplicate Name", dialog.getTitle());
|
||||||
assertEquals("Duplicate Name", d.getTitle());
|
|
||||||
assertEquals("Colors", enummDt.getName());
|
assertEquals("Colors", enummDt.getName());
|
||||||
|
|
||||||
pressButtonByText(d, "OK");
|
close(dialog);
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
assertTrue(!getAction(plugin, "Apply Enum Changes").isEnabled());
|
assertFalse(getAction(plugin, "Apply Enum Changes").isEnabled());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -521,7 +529,7 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
tf.setText("0x0");
|
tf.setText("0x0");
|
||||||
editor.stopCellEditing();
|
editor.stopCellEditing();
|
||||||
});
|
});
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
Window w = windowForComponent(table);
|
Window w = windowForComponent(table);
|
||||||
String str = findLabelStr(w, "Tool Status");
|
String str = findLabelStr(w, "Tool Status");
|
||||||
// assertEquals("Colors enum value 0 already assigned", str);
|
// assertEquals("Colors enum value 0 already assigned", str);
|
||||||
|
@ -538,8 +546,8 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
final JTextField descField = getTextField(panel, "Description");
|
final JTextField descField = getTextField(panel, "Description");
|
||||||
assertEquals("This is a set of Colors", descField.getText());
|
assertEquals("This is a set of Colors", descField.getText());
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> descField.setText("My Favorite colors"));
|
runSwing(() -> descField.setText("My Favorite colors"));
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
applyChanges(true);
|
applyChanges(true);
|
||||||
assertEquals("My Favorite colors", enumDt.getDescription());
|
assertEquals("My Favorite colors", enumDt.getDescription());
|
||||||
|
|
||||||
|
@ -553,8 +561,8 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
final EnumEditorPanel panel = findEditorPanel(tool.getToolFrame());
|
final EnumEditorPanel panel = findEditorPanel(tool.getToolFrame());
|
||||||
final JTextField descField = getTextField(panel, "Description");
|
final JTextField descField = getTextField(panel, "Description");
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> descField.setText(""));
|
runSwing(() -> descField.setText(""));
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
applyChanges(true);
|
applyChanges(true);
|
||||||
assertEquals("", enumDt.getDescription());
|
assertEquals("", enumDt.getDescription());
|
||||||
|
|
||||||
|
@ -568,19 +576,19 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
final EnumEditorPanel panel = findEditorPanel(tool.getToolFrame());
|
final EnumEditorPanel panel = findEditorPanel(tool.getToolFrame());
|
||||||
final JTable table = panel.getTable();
|
final JTable table = panel.getTable();
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> {
|
runSwing(() -> {
|
||||||
TableColumnModel colModel = table.getColumnModel();
|
TableColumnModel colModel = table.getColumnModel();
|
||||||
colModel.moveColumn(1, 0);
|
colModel.moveColumn(1, 0);
|
||||||
});
|
});
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
assertEquals("Value", table.getColumnName(0));
|
assertEquals("Value", table.getColumnName(0));
|
||||||
assertEquals("Name", table.getColumnName(1));
|
assertEquals("Name", table.getColumnName(1));
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> {
|
runSwing(() -> {
|
||||||
TableColumnModel colModel = table.getColumnModel();
|
TableColumnModel colModel = table.getColumnModel();
|
||||||
colModel.moveColumn(0, 1);
|
colModel.moveColumn(0, 1);
|
||||||
});
|
});
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
assertEquals("Name", table.getColumnName(0));
|
assertEquals("Name", table.getColumnName(0));
|
||||||
assertEquals("Value", table.getColumnName(1));
|
assertEquals("Value", table.getColumnName(1));
|
||||||
|
|
||||||
|
@ -597,7 +605,7 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
// delete a row
|
// delete a row
|
||||||
table.setRowSelectionInterval(0, 0);
|
table.setRowSelectionInterval(0, 0);
|
||||||
SwingUtilities.invokeAndWait(() -> {
|
runSwing(() -> {
|
||||||
DockingActionIf action = getAction(plugin, "Delete Enum Value");
|
DockingActionIf action = getAction(plugin, "Delete Enum Value");
|
||||||
action.actionPerformed(new ActionContext());
|
action.actionPerformed(new ActionContext());
|
||||||
});
|
});
|
||||||
|
@ -622,28 +630,28 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
EnumTableModel model = (EnumTableModel) table.getModel();
|
EnumTableModel model = (EnumTableModel) table.getModel();
|
||||||
|
|
||||||
int origRowCount = model.getRowCount();
|
int origRowCount = model.getRowCount();
|
||||||
SwingUtilities.invokeAndWait(() -> {
|
runSwing(() -> {
|
||||||
DockingActionIf action = getAction(plugin, "Add Enum Value");
|
DockingActionIf action = getAction(plugin, "Add Enum Value");
|
||||||
action.actionPerformed(new ActionContext());
|
action.actionPerformed(new ActionContext());
|
||||||
action.actionPerformed(new ActionContext());
|
action.actionPerformed(new ActionContext());
|
||||||
});
|
});
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
applyChanges(true);
|
applyChanges(true);
|
||||||
// make more changes
|
// make more changes
|
||||||
SwingUtilities.invokeAndWait(() -> {
|
runSwing(() -> {
|
||||||
DockingActionIf action = getAction(plugin, "Add Enum Value");
|
DockingActionIf action = getAction(plugin, "Add Enum Value");
|
||||||
action.actionPerformed(new ActionContext());
|
action.actionPerformed(new ActionContext());
|
||||||
action.actionPerformed(new ActionContext());
|
action.actionPerformed(new ActionContext());
|
||||||
});
|
});
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
undo(false);
|
undo(false);
|
||||||
OptionDialog d = waitForDialogComponent(tool.getToolFrame(), OptionDialog.class, 2000);
|
OptionDialog d = waitForDialogComponent(OptionDialog.class);
|
||||||
assertNotNull(d);
|
assertNotNull(d);
|
||||||
// yes to reload the enum data type
|
// yes to reload the enum data type
|
||||||
final JButton button = findButtonByText(d.getComponent(), "Yes");
|
final JButton button = findButtonByText(d.getComponent(), "Yes");
|
||||||
assertNotNull(button);
|
assertNotNull(button);
|
||||||
SwingUtilities.invokeAndWait(() -> button.getActionListeners()[0].actionPerformed(null));
|
runSwing(() -> button.getActionListeners()[0].actionPerformed(null));
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
assertEquals(origRowCount, model.getRowCount());
|
assertEquals(origRowCount, model.getRowCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -656,7 +664,7 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
final JTable table = panel.getTable();
|
final JTable table = panel.getTable();
|
||||||
final EnumTableModel model = (EnumTableModel) table.getModel();
|
final EnumTableModel model = (EnumTableModel) table.getModel();
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> {
|
runSwing(() -> {
|
||||||
int lastRow = model.getRowCount() - 1;
|
int lastRow = model.getRowCount() - 1;
|
||||||
if (lastRow >= 0) {
|
if (lastRow >= 0) {
|
||||||
table.addRowSelectionInterval(lastRow, lastRow);
|
table.addRowSelectionInterval(lastRow, lastRow);
|
||||||
|
@ -665,10 +673,10 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
action.actionPerformed(new ActionContext());
|
action.actionPerformed(new ActionContext());
|
||||||
action.actionPerformed(new ActionContext());
|
action.actionPerformed(new ActionContext());
|
||||||
});
|
});
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
applyChanges(true);
|
applyChanges(true);
|
||||||
// make more changes
|
// make more changes
|
||||||
SwingUtilities.invokeAndWait(() -> {
|
runSwing(() -> {
|
||||||
int lastRow = model.getRowCount() - 1;
|
int lastRow = model.getRowCount() - 1;
|
||||||
if (lastRow >= 0) {
|
if (lastRow >= 0) {
|
||||||
table.addRowSelectionInterval(lastRow, lastRow);
|
table.addRowSelectionInterval(lastRow, lastRow);
|
||||||
|
@ -677,16 +685,16 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
action.actionPerformed(new ActionContext());
|
action.actionPerformed(new ActionContext());
|
||||||
action.actionPerformed(new ActionContext());
|
action.actionPerformed(new ActionContext());
|
||||||
});
|
});
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
int rowCount = model.getRowCount();
|
int rowCount = model.getRowCount();
|
||||||
undo(false);
|
undo(false);
|
||||||
OptionDialog d = waitForDialogComponent(tool.getToolFrame(), OptionDialog.class, 2000);
|
OptionDialog d = waitForDialogComponent(OptionDialog.class);
|
||||||
assertNotNull(d);
|
assertNotNull(d);
|
||||||
// not to not reload the enum data type
|
// not to not reload the enum data type
|
||||||
final JButton button = findButtonByText(d.getComponent(), "No");
|
final JButton button = findButtonByText(d.getComponent(), "No");
|
||||||
assertNotNull(button);
|
assertNotNull(button);
|
||||||
SwingUtilities.invokeAndWait(() -> button.getActionListeners()[0].actionPerformed(null));
|
runSwing(() -> button.getActionListeners()[0].actionPerformed(null));
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
assertEquals(rowCount, model.getRowCount());
|
assertEquals(rowCount, model.getRowCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -742,7 +750,7 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
private void addEntry(final JTable table, final EnumTableModel model, final String name,
|
private void addEntry(final JTable table, final EnumTableModel model, final String name,
|
||||||
final long value) throws Exception {
|
final long value) throws Exception {
|
||||||
SwingUtilities.invokeAndWait(() -> {
|
runSwing(() -> {
|
||||||
int lastRow = model.getRowCount() - 1;
|
int lastRow = model.getRowCount() - 1;
|
||||||
if (lastRow >= 0) {
|
if (lastRow >= 0) {
|
||||||
table.addRowSelectionInterval(lastRow, lastRow);
|
table.addRowSelectionInterval(lastRow, lastRow);
|
||||||
|
@ -750,14 +758,14 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
DockingActionIf addAction = getAction(plugin, "Add Enum Value");
|
DockingActionIf addAction = getAction(plugin, "Add Enum Value");
|
||||||
addAction.actionPerformed(new ActionContext());
|
addAction.actionPerformed(new ActionContext());
|
||||||
});
|
});
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
final int newRow = model.getRowCount() - 1;
|
final int newRow = model.getRowCount() - 1;
|
||||||
// change entry
|
// change entry
|
||||||
SwingUtilities.invokeAndWait(() -> table.addRowSelectionInterval(newRow, newRow));
|
runSwing(() -> table.addRowSelectionInterval(newRow, newRow));
|
||||||
Rectangle rect = table.getCellRect(newRow, EnumTableModel.NAME_COL, true);
|
Rectangle rect = table.getCellRect(newRow, EnumTableModel.NAME_COL, true);
|
||||||
clickMouse(table, 1, rect.x, rect.y, 2, 0);
|
clickMouse(table, 1, rect.x, rect.y, 2, 0);
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> {
|
runSwing(() -> {
|
||||||
TableCellEditor editor = table.getCellEditor(newRow, EnumTableModel.NAME_COL);
|
TableCellEditor editor = table.getCellEditor(newRow, EnumTableModel.NAME_COL);
|
||||||
Component c = editor.getTableCellEditorComponent(table,
|
Component c = editor.getTableCellEditorComponent(table,
|
||||||
model.getValueAt(newRow, EnumTableModel.NAME_COL), true, newRow,
|
model.getValueAt(newRow, EnumTableModel.NAME_COL), true, newRow,
|
||||||
|
@ -766,11 +774,11 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
tf.setText(name);
|
tf.setText(name);
|
||||||
editor.stopCellEditing();
|
editor.stopCellEditing();
|
||||||
});
|
});
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
rect = table.getCellRect(newRow, EnumTableModel.VALUE_COL, true);
|
rect = table.getCellRect(newRow, EnumTableModel.VALUE_COL, true);
|
||||||
clickMouse(table, 1, rect.x + 1, rect.y + 1, 2, 0);
|
clickMouse(table, 1, rect.x + 1, rect.y + 1, 2, 0);
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> {
|
runSwing(() -> {
|
||||||
TableCellEditor editor = table.getCellEditor(newRow, EnumTableModel.VALUE_COL);
|
TableCellEditor editor = table.getCellEditor(newRow, EnumTableModel.VALUE_COL);
|
||||||
|
|
||||||
Component c = editor.getTableCellEditorComponent(table,
|
Component c = editor.getTableCellEditorComponent(table,
|
||||||
|
@ -780,7 +788,7 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
tf.setText("0x" + Long.toHexString(value));
|
tf.setText("0x" + Long.toHexString(value));
|
||||||
editor.stopCellEditing();
|
editor.stopCellEditing();
|
||||||
});
|
});
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyChanges(boolean doWait) throws Exception {
|
private void applyChanges(boolean doWait) throws Exception {
|
||||||
|
@ -789,13 +797,13 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
assertTrue(applyAction.isEnabled());
|
assertTrue(applyAction.isEnabled());
|
||||||
Runnable r = () -> applyAction.actionPerformed(new ActionContext());
|
Runnable r = () -> applyAction.actionPerformed(new ActionContext());
|
||||||
if (doWait) {
|
if (doWait) {
|
||||||
SwingUtilities.invokeAndWait(r);
|
runSwing(r);
|
||||||
program.flushEvents();
|
program.flushEvents();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SwingUtilities.invokeLater(r);
|
SwingUtilities.invokeLater(r);
|
||||||
}
|
}
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -818,7 +826,9 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Enum editSampleEnum() {
|
private Enum editSampleEnum() {
|
||||||
Category cat = program.getListing().getDataTypeManager().getCategory(
|
Category cat = program.getListing()
|
||||||
|
.getDataTypeManager()
|
||||||
|
.getCategory(
|
||||||
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
new CategoryPath(CategoryPath.ROOT, "Category1"));
|
||||||
final Enum enumm = new EnumDataType("Colors", 1);
|
final Enum enumm = new EnumDataType("Colors", 1);
|
||||||
enumm.add("Red", 0);
|
enumm.add("Red", 0);
|
||||||
|
@ -833,10 +843,10 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
final Enum enumDt = (Enum) cat.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
|
final Enum enumDt = (Enum) cat.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||||
program.endTransaction(transactionID, true);
|
program.endTransaction(transactionID, true);
|
||||||
program.flushEvents();
|
program.flushEvents();
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
SwingUtilities.invokeLater(() -> plugin.edit(enumDt));
|
SwingUtilities.invokeLater(() -> plugin.edit(enumDt));
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
return enumDt;
|
return enumDt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -851,12 +861,12 @@ public class EnumEditor2Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (doWait) {
|
if (doWait) {
|
||||||
SwingUtilities.invokeAndWait(r);
|
runSwing(r);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SwingUtilities.invokeLater(r);
|
SwingUtilities.invokeLater(r);
|
||||||
}
|
}
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,14 +17,13 @@ package ghidra.app.plugin.core.function;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import javax.swing.JDialog;
|
|
||||||
import javax.swing.JTextField;
|
import javax.swing.JTextField;
|
||||||
|
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
|
|
||||||
|
import docking.AbstractErrDialog;
|
||||||
import docking.ActionContext;
|
import docking.ActionContext;
|
||||||
import docking.action.DockingActionIf;
|
import docking.action.DockingActionIf;
|
||||||
import docking.widgets.MultiLineLabel;
|
|
||||||
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
||||||
import ghidra.app.util.viewer.field.FunctionSignatureFieldFactory;
|
import ghidra.app.util.viewer.field.FunctionSignatureFieldFactory;
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
|
@ -70,30 +69,25 @@ public class ThunkReferenceAddressDialogTest extends AbstractGhidraHeadedIntegra
|
||||||
@Test
|
@Test
|
||||||
public void testSetThunkedFunction() throws Exception {
|
public void testSetThunkedFunction() throws Exception {
|
||||||
|
|
||||||
ThunkReferenceAddressDialog dialog = popupSetThunkDialog(addr(0x100194b));
|
ThunkReferenceAddressDialog dialog = showThunkDialog(addr(0x100194b));
|
||||||
|
|
||||||
JTextField textEntryField = findComponent(dialog, JTextField.class);
|
JTextField textEntryField = findComponent(dialog, JTextField.class);
|
||||||
assertNotNull(textEntryField);
|
assertNotNull(textEntryField);
|
||||||
|
|
||||||
// Invalid Entry
|
// Invalid Entry
|
||||||
|
|
||||||
setText(textEntryField, "bar");
|
setText(textEntryField, "bar");
|
||||||
|
|
||||||
pressButtonByText(dialog, "OK", false);
|
pressButtonByText(dialog, "OK", false);
|
||||||
|
|
||||||
JDialog errorDialog = waitForJDialog("Invalid Entry Error");
|
AbstractErrDialog errorDialog = waitForErrorDialog();
|
||||||
MultiLineLabel errorLabel =
|
assertEquals("Invalid Entry Error", errorDialog.getTitle());
|
||||||
(MultiLineLabel) findComponentByName(errorDialog, "MESSAGE-COMPONENT");
|
assertEquals(
|
||||||
assertNotNull(errorLabel);
|
"Invalid thunk reference address or name specified: bar",
|
||||||
|
errorDialog.getMessage());
|
||||||
assertEquals("Invalid thunk reference address or name specified: bar",
|
|
||||||
errorLabel.getLabel());
|
|
||||||
pressButtonByText(errorDialog, "OK");
|
pressButtonByText(errorDialog, "OK");
|
||||||
|
|
||||||
// Try again
|
// Try again
|
||||||
|
|
||||||
setText(textEntryField, "IsTextUnicode");
|
setText(textEntryField, "IsTextUnicode");
|
||||||
|
|
||||||
pressButtonByText(dialog, "OK");
|
pressButtonByText(dialog, "OK");
|
||||||
waitForBusyTool(tool);
|
waitForBusyTool(tool);
|
||||||
|
|
||||||
|
@ -110,7 +104,7 @@ public class ThunkReferenceAddressDialogTest extends AbstractGhidraHeadedIntegra
|
||||||
@Test
|
@Test
|
||||||
public void testSetThunkedFunctionWithNamespace() throws Exception {
|
public void testSetThunkedFunctionWithNamespace() throws Exception {
|
||||||
|
|
||||||
ThunkReferenceAddressDialog dialog = popupSetThunkDialog(addr(0x100194b));
|
ThunkReferenceAddressDialog dialog = showThunkDialog(addr(0x100194b));
|
||||||
|
|
||||||
JTextField textEntryField = findComponent(dialog, JTextField.class);
|
JTextField textEntryField = findComponent(dialog, JTextField.class);
|
||||||
assertNotNull(textEntryField);
|
assertNotNull(textEntryField);
|
||||||
|
@ -130,19 +124,10 @@ public class ThunkReferenceAddressDialogTest extends AbstractGhidraHeadedIntegra
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Test
|
|
||||||
// public void testClearThunkedFunction() throws Exception {
|
|
||||||
//
|
|
||||||
// testSetThunkedFunctionWithNamespace(); // sets thunk
|
|
||||||
//
|
|
||||||
// revertThunk.actionPerformed(context);
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSetThunkedFunctionWithOriginalName() throws Exception {
|
public void testSetThunkedFunctionWithOriginalName() throws Exception {
|
||||||
|
|
||||||
ThunkReferenceAddressDialog dialog = popupSetThunkDialog(addr(0x100194b));
|
ThunkReferenceAddressDialog dialog = showThunkDialog(addr(0x100194b));
|
||||||
|
|
||||||
JTextField textEntryField = findComponent(dialog, JTextField.class);
|
JTextField textEntryField = findComponent(dialog, JTextField.class);
|
||||||
assertNotNull(textEntryField);
|
assertNotNull(textEntryField);
|
||||||
|
@ -166,54 +151,38 @@ public class ThunkReferenceAddressDialogTest extends AbstractGhidraHeadedIntegra
|
||||||
@Test
|
@Test
|
||||||
public void testSetThunkedFunctionWithOriginalNameConflict() throws Exception {
|
public void testSetThunkedFunctionWithOriginalNameConflict() throws Exception {
|
||||||
|
|
||||||
int txId = program.startTransaction("add label");
|
tx(program, () -> {
|
||||||
try {
|
|
||||||
program.getSymbolTable().createLabel(addr(0x1001900), "_Zxyz", SourceType.USER_DEFINED);
|
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);
|
JTextField textEntryField = findComponent(dialog, JTextField.class);
|
||||||
assertNotNull(textEntryField);
|
assertNotNull(textEntryField);
|
||||||
|
|
||||||
// Multiple Symbols
|
|
||||||
|
|
||||||
setText(textEntryField, "_Zxyz");
|
setText(textEntryField, "_Zxyz");
|
||||||
|
|
||||||
pressButtonByText(dialog, "OK", false);
|
pressButtonByText(dialog, "OK", false);
|
||||||
|
|
||||||
JDialog errorDialog = waitForJDialog("Ambiguous Symbol Name");
|
AbstractErrDialog errorDialog = waitForErrorDialog();
|
||||||
MultiLineLabel errorLabel =
|
assertEquals("Ambiguous Symbol Name", errorDialog.getTitle());
|
||||||
(MultiLineLabel) findComponentByName(errorDialog, "MESSAGE-COMPONENT");
|
|
||||||
assertNotNull(errorLabel);
|
|
||||||
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"Specified symbol is ambiguous. Try full namespace name, mangled name or address.",
|
"Specified symbol is ambiguous. Try full namespace name, mangled name or address.",
|
||||||
errorLabel.getLabel());
|
errorDialog.getMessage());
|
||||||
pressButtonByText(errorDialog, "OK");
|
pressButtonByText(errorDialog, "OK");
|
||||||
|
|
||||||
waitForBusyTool(tool);
|
waitForBusyTool(tool);
|
||||||
|
|
||||||
Function f = program.getFunctionManager().getFunctionAt(addr(0x100194b));
|
Function f = program.getFunctionManager().getFunctionAt(addr(0x100194b));
|
||||||
assertFalse(f.isThunk());
|
assertFalse(f.isThunk());
|
||||||
|
|
||||||
setText(textEntryField, "LibFoo::xyz");
|
setText(textEntryField, "LibFoo::xyz");
|
||||||
|
|
||||||
pressButtonByText(dialog, "OK", false);
|
pressButtonByText(dialog, "OK", false);
|
||||||
|
|
||||||
waitForBusyTool(tool);
|
waitForBusyTool(tool);
|
||||||
|
|
||||||
Function thunkedFunction = f.getThunkedFunction(false);
|
Function thunkedFunction = f.getThunkedFunction(false);
|
||||||
assertNotNull(thunkedFunction);
|
assertNotNull(thunkedFunction);
|
||||||
assertTrue(thunkedFunction.isExternal());
|
assertTrue(thunkedFunction.isExternal());
|
||||||
assertEquals("LibFoo::xyz", thunkedFunction.getName(true));
|
assertEquals("LibFoo::xyz", thunkedFunction.getName(true));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ThunkReferenceAddressDialog popupSetThunkDialog(Address address) {
|
private ThunkReferenceAddressDialog showThunkDialog(Address address) {
|
||||||
codeBrowserPlugin.goToField(address, FunctionSignatureFieldFactory.FIELD_NAME, 0, 0);
|
codeBrowserPlugin.goToField(address, FunctionSignatureFieldFactory.FIELD_NAME, 0, 0);
|
||||||
waitForBusyTool(tool);
|
waitForBusyTool(tool);
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -39,7 +39,7 @@ import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.model.mem.Memory;
|
import ghidra.program.model.mem.Memory;
|
||||||
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
||||||
import ghidra.test.TestEnv;
|
import ghidra.test.TestEnv;
|
||||||
import ghidra.util.task.TaskMonitorAdapter;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest {
|
public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
|
@ -52,10 +52,6 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
private JTable table;
|
private JTable table;
|
||||||
private TableModel model;
|
private TableModel model;
|
||||||
|
|
||||||
public MemoryMapProvider3Test() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Program buildProgram(String programName) throws Exception {
|
private Program buildProgram(String programName) throws Exception {
|
||||||
ProgramBuilder builder = new ProgramBuilder(programName, ProgramBuilder._TOY);
|
ProgramBuilder builder = new ProgramBuilder(programName, ProgramBuilder._TOY);
|
||||||
builder.createMemory(".text", Long.toHexString(0x1001000), 0x6600);
|
builder.createMemory(".text", Long.toHexString(0x1001000), 0x6600);
|
||||||
|
@ -102,7 +98,7 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
|
|
||||||
// find the dialog for the add
|
// find the dialog for the add
|
||||||
SplitBlockDialog d =
|
SplitBlockDialog d =
|
||||||
waitForDialogComponent(tool.getToolFrame(), SplitBlockDialog.class, 2000);
|
waitForDialogComponent(SplitBlockDialog.class);
|
||||||
assertNotNull(d);
|
assertNotNull(d);
|
||||||
JTextField blockOneName =
|
JTextField blockOneName =
|
||||||
(JTextField) findComponentByName(d.getComponent(), "BlockOneName");
|
(JTextField) findComponentByName(d.getComponent(), "BlockOneName");
|
||||||
|
@ -142,21 +138,21 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
assertEquals("010075ff", blockTwoEnd.getText());
|
assertEquals("010075ff", blockTwoEnd.getText());
|
||||||
assertEquals("-- No Value --", blockTwoLength.getText());
|
assertEquals("-- No Value --", blockTwoLength.getText());
|
||||||
|
|
||||||
assertTrue(!blockOneName.isEnabled());
|
assertFalse(blockOneName.isEnabled());
|
||||||
assertTrue(!blockOneStart.isEnabled());
|
assertFalse(blockOneStart.isEnabled());
|
||||||
assertTrue(blockOneEnd.isEnabled());
|
assertTrue(blockOneEnd.isEnabled());
|
||||||
assertTrue(blockOneLength.isEnabled());
|
assertTrue(blockOneLength.isEnabled());
|
||||||
|
|
||||||
assertTrue(blockTwoName.isEnabled());
|
assertTrue(blockTwoName.isEnabled());
|
||||||
assertTrue(blockTwoStart.isEnabled());
|
assertTrue(blockTwoStart.isEnabled());
|
||||||
assertTrue(!blockTwoEnd.isEnabled());
|
assertFalse(blockTwoEnd.isEnabled());
|
||||||
assertTrue(blockTwoLength.isEnabled());
|
assertTrue(blockTwoLength.isEnabled());
|
||||||
|
|
||||||
assertTrue(!okButton.isEnabled());
|
assertFalse(okButton.isEnabled());
|
||||||
|
|
||||||
final JButton cancelButton = findButton(d.getComponent(), "Cancel");
|
JButton cancelButton = findButton(d.getComponent(), "Cancel");
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(
|
runSwing(
|
||||||
() -> cancelButton.getActionListeners()[0].actionPerformed(null));
|
() -> cancelButton.getActionListeners()[0].actionPerformed(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,40 +166,40 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
|
|
||||||
// find the dialog for the add
|
// find the dialog for the add
|
||||||
SplitBlockDialog d =
|
SplitBlockDialog d =
|
||||||
waitForDialogComponent(tool.getToolFrame(), SplitBlockDialog.class, 2000);
|
waitForDialogComponent(SplitBlockDialog.class);
|
||||||
JTextField blockOneName =
|
JTextField blockOneName =
|
||||||
(JTextField) findComponentByName(d.getComponent(), "BlockOneName");
|
(JTextField) findComponentByName(d.getComponent(), "BlockOneName");
|
||||||
assertNotNull(blockOneName);
|
assertNotNull(blockOneName);
|
||||||
JTextField blockOneStart =
|
JTextField blockOneStart =
|
||||||
(JTextField) findComponentByName(d.getComponent(), "BlockOneStart");
|
(JTextField) findComponentByName(d.getComponent(), "BlockOneStart");
|
||||||
assertNotNull(blockOneStart);
|
assertNotNull(blockOneStart);
|
||||||
final AddressInput blockOneEnd =
|
AddressInput blockOneEnd =
|
||||||
(AddressInput) findComponentByName(d.getComponent(), "BlockOneEnd");
|
(AddressInput) findComponentByName(d.getComponent(), "BlockOneEnd");
|
||||||
final RegisterField blockOneLength =
|
RegisterField blockOneLength =
|
||||||
(RegisterField) findComponentByName(d.getComponent(), "BlockOneLength");
|
(RegisterField) findComponentByName(d.getComponent(), "BlockOneLength");
|
||||||
|
|
||||||
JTextField blockTwoName =
|
JTextField blockTwoName =
|
||||||
(JTextField) findComponentByName(d.getComponent(), "BlockTwoName");
|
(JTextField) findComponentByName(d.getComponent(), "BlockTwoName");
|
||||||
assertNotNull(blockTwoName);
|
assertNotNull(blockTwoName);
|
||||||
final AddressInput blockTwoStart =
|
AddressInput blockTwoStart =
|
||||||
(AddressInput) findComponentByName(d.getComponent(), "BlockTwoStart");
|
(AddressInput) findComponentByName(d.getComponent(), "BlockTwoStart");
|
||||||
final JTextField blockTwoEnd =
|
JTextField blockTwoEnd =
|
||||||
(JTextField) findComponentByName(d.getComponent(), "BlockTwoEnd");
|
(JTextField) findComponentByName(d.getComponent(), "BlockTwoEnd");
|
||||||
final RegisterField blockTwoLength =
|
RegisterField blockTwoLength =
|
||||||
(RegisterField) findComponentByName(d.getComponent(), "BlockTwoLength");
|
(RegisterField) findComponentByName(d.getComponent(), "BlockTwoLength");
|
||||||
final JButton okButton = findButton(d.getComponent(), "OK");
|
JButton okButton = findButton(d.getComponent(), "OK");
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> blockOneLength.setText("0x1000"));
|
runSwing(() -> blockOneLength.setText("0x1000"));
|
||||||
assertEquals(getAddr(0x01001fff), blockOneEnd.getAddress());
|
assertEquals(getAddr(0x01001fff), blockOneEnd.getAddress());
|
||||||
assertEquals(getAddr(0x01002000), blockTwoStart.getAddress());
|
assertEquals(getAddr(0x01002000), blockTwoStart.getAddress());
|
||||||
assertEquals("010075ff", blockTwoEnd.getText());
|
assertEquals("010075ff", blockTwoEnd.getText());
|
||||||
assertEquals(0x5600, blockTwoLength.getValue().longValue());
|
assertEquals(0x5600, blockTwoLength.getValue().longValue());
|
||||||
assertTrue(okButton.isEnabled());
|
assertTrue(okButton.isEnabled());
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> okButton.getActionListeners()[0].actionPerformed(null));
|
runSwing(() -> okButton.getActionListeners()[0].actionPerformed(null));
|
||||||
|
|
||||||
program.flushEvents();
|
program.flushEvents();
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
assertEquals("01001000", model.getValueAt(0, MemoryMapModel.START));
|
assertEquals("01001000", model.getValueAt(0, MemoryMapModel.START));
|
||||||
assertEquals("01001fff", model.getValueAt(0, MemoryMapModel.END));
|
assertEquals("01001fff", model.getValueAt(0, MemoryMapModel.END));
|
||||||
|
@ -225,31 +221,31 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
|
|
||||||
// find the dialog for the add
|
// find the dialog for the add
|
||||||
SplitBlockDialog d =
|
SplitBlockDialog d =
|
||||||
waitForDialogComponent(tool.getToolFrame(), SplitBlockDialog.class, 2000);
|
waitForDialogComponent(SplitBlockDialog.class);
|
||||||
final AddressInput blockOneEnd =
|
AddressInput blockOneEnd =
|
||||||
(AddressInput) findComponentByName(d.getComponent(), "BlockOneEnd");
|
(AddressInput) findComponentByName(d.getComponent(), "BlockOneEnd");
|
||||||
final RegisterField blockOneLength =
|
RegisterField blockOneLength =
|
||||||
(RegisterField) findComponentByName(d.getComponent(), "BlockOneLength");
|
(RegisterField) findComponentByName(d.getComponent(), "BlockOneLength");
|
||||||
|
|
||||||
final AddressInput blockTwoStart =
|
AddressInput blockTwoStart =
|
||||||
(AddressInput) findComponentByName(d.getComponent(), "BlockTwoStart");
|
(AddressInput) findComponentByName(d.getComponent(), "BlockTwoStart");
|
||||||
final JTextField blockTwoEnd =
|
JTextField blockTwoEnd =
|
||||||
(JTextField) findComponentByName(d.getComponent(), "BlockTwoEnd");
|
(JTextField) findComponentByName(d.getComponent(), "BlockTwoEnd");
|
||||||
final RegisterField blockTwoLength =
|
RegisterField blockTwoLength =
|
||||||
(RegisterField) findComponentByName(d.getComponent(), "BlockTwoLength");
|
(RegisterField) findComponentByName(d.getComponent(), "BlockTwoLength");
|
||||||
final JButton okButton = findButton(d.getComponent(), "OK");
|
JButton okButton = findButton(d.getComponent(), "OK");
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> blockOneEnd.setValue("01003000"));
|
runSwing(() -> blockOneEnd.setValue("01003000"));
|
||||||
assertEquals(0x2001, blockOneLength.getValue().longValue());
|
assertEquals(0x2001, blockOneLength.getValue().longValue());
|
||||||
assertEquals(getAddr(0x01003001), blockTwoStart.getAddress());
|
assertEquals(getAddr(0x01003001), blockTwoStart.getAddress());
|
||||||
assertEquals("010075ff", blockTwoEnd.getText());
|
assertEquals("010075ff", blockTwoEnd.getText());
|
||||||
assertEquals(0x45ff, blockTwoLength.getValue().longValue());
|
assertEquals(0x45ff, blockTwoLength.getValue().longValue());
|
||||||
assertTrue(okButton.isEnabled());
|
assertTrue(okButton.isEnabled());
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> okButton.getActionListeners()[0].actionPerformed(null));
|
runSwing(() -> okButton.getActionListeners()[0].actionPerformed(null));
|
||||||
|
|
||||||
program.flushEvents();
|
program.flushEvents();
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
assertEquals("01001000", model.getValueAt(0, MemoryMapModel.START));
|
assertEquals("01001000", model.getValueAt(0, MemoryMapModel.START));
|
||||||
assertEquals("01003000", model.getValueAt(0, MemoryMapModel.END));
|
assertEquals("01003000", model.getValueAt(0, MemoryMapModel.END));
|
||||||
|
@ -272,32 +268,32 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
|
|
||||||
// find the dialog for the add
|
// find the dialog for the add
|
||||||
SplitBlockDialog d =
|
SplitBlockDialog d =
|
||||||
waitForDialogComponent(tool.getToolFrame(), SplitBlockDialog.class, 2000);
|
waitForDialogComponent(SplitBlockDialog.class);
|
||||||
|
|
||||||
final AddressInput blockOneEnd =
|
AddressInput blockOneEnd =
|
||||||
(AddressInput) findComponentByName(d.getComponent(), "BlockOneEnd");
|
(AddressInput) findComponentByName(d.getComponent(), "BlockOneEnd");
|
||||||
final RegisterField blockOneLength =
|
RegisterField blockOneLength =
|
||||||
(RegisterField) findComponentByName(d.getComponent(), "BlockOneLength");
|
(RegisterField) findComponentByName(d.getComponent(), "BlockOneLength");
|
||||||
|
|
||||||
final AddressInput blockTwoStart =
|
AddressInput blockTwoStart =
|
||||||
(AddressInput) findComponentByName(d.getComponent(), "BlockTwoStart");
|
(AddressInput) findComponentByName(d.getComponent(), "BlockTwoStart");
|
||||||
final JTextField blockTwoEnd =
|
JTextField blockTwoEnd =
|
||||||
(JTextField) findComponentByName(d.getComponent(), "BlockTwoEnd");
|
(JTextField) findComponentByName(d.getComponent(), "BlockTwoEnd");
|
||||||
final RegisterField blockTwoLength =
|
RegisterField blockTwoLength =
|
||||||
(RegisterField) findComponentByName(d.getComponent(), "BlockTwoLength");
|
(RegisterField) findComponentByName(d.getComponent(), "BlockTwoLength");
|
||||||
final JButton okButton = findButton(d.getComponent(), "OK");
|
JButton okButton = findButton(d.getComponent(), "OK");
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> blockTwoStart.setValue("01003000"));
|
runSwing(() -> blockTwoStart.setValue("01003000"));
|
||||||
assertEquals(0x2000, blockOneLength.getValue().longValue());
|
assertEquals(0x2000, blockOneLength.getValue().longValue());
|
||||||
assertEquals(getAddr(0x01002fff), blockOneEnd.getAddress());
|
assertEquals(getAddr(0x01002fff), blockOneEnd.getAddress());
|
||||||
assertEquals("010075ff", blockTwoEnd.getText());
|
assertEquals("010075ff", blockTwoEnd.getText());
|
||||||
assertEquals(0x4600, blockTwoLength.getValue().longValue());
|
assertEquals(0x4600, blockTwoLength.getValue().longValue());
|
||||||
assertTrue(okButton.isEnabled());
|
assertTrue(okButton.isEnabled());
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> okButton.getActionListeners()[0].actionPerformed(null));
|
runSwing(() -> okButton.getActionListeners()[0].actionPerformed(null));
|
||||||
|
|
||||||
program.flushEvents();
|
program.flushEvents();
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
assertEquals("01001000", model.getValueAt(0, MemoryMapModel.START));
|
assertEquals("01001000", model.getValueAt(0, MemoryMapModel.START));
|
||||||
assertEquals("01002fff", model.getValueAt(0, MemoryMapModel.END));
|
assertEquals("01002fff", model.getValueAt(0, MemoryMapModel.END));
|
||||||
|
@ -319,29 +315,29 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
|
|
||||||
// find the dialog for the add
|
// find the dialog for the add
|
||||||
SplitBlockDialog d =
|
SplitBlockDialog d =
|
||||||
waitForDialogComponent(tool.getToolFrame(), SplitBlockDialog.class, 2000);
|
waitForDialogComponent(SplitBlockDialog.class);
|
||||||
final AddressInput blockOneEnd =
|
AddressInput blockOneEnd =
|
||||||
(AddressInput) findComponentByName(d.getComponent(), "BlockOneEnd");
|
(AddressInput) findComponentByName(d.getComponent(), "BlockOneEnd");
|
||||||
final RegisterField blockOneLength =
|
RegisterField blockOneLength =
|
||||||
(RegisterField) findComponentByName(d.getComponent(), "BlockOneLength");
|
(RegisterField) findComponentByName(d.getComponent(), "BlockOneLength");
|
||||||
|
|
||||||
final JTextField blockTwoEnd =
|
JTextField blockTwoEnd =
|
||||||
(JTextField) findComponentByName(d.getComponent(), "BlockTwoEnd");
|
(JTextField) findComponentByName(d.getComponent(), "BlockTwoEnd");
|
||||||
final RegisterField blockTwoLength =
|
RegisterField blockTwoLength =
|
||||||
(RegisterField) findComponentByName(d.getComponent(), "BlockTwoLength");
|
(RegisterField) findComponentByName(d.getComponent(), "BlockTwoLength");
|
||||||
final JButton okButton = findButton(d.getComponent(), "OK");
|
JButton okButton = findButton(d.getComponent(), "OK");
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> blockTwoLength.setText("0x2000"));
|
runSwing(() -> blockTwoLength.setText("0x2000"));
|
||||||
assertEquals(0x4600, blockOneLength.getValue().longValue());
|
assertEquals(0x4600, blockOneLength.getValue().longValue());
|
||||||
assertEquals(getAddr(0x010055ff), blockOneEnd.getAddress());
|
assertEquals(getAddr(0x010055ff), blockOneEnd.getAddress());
|
||||||
assertEquals("010075ff", blockTwoEnd.getText());
|
assertEquals("010075ff", blockTwoEnd.getText());
|
||||||
assertEquals(0x2000, blockTwoLength.getValue().longValue());
|
assertEquals(0x2000, blockTwoLength.getValue().longValue());
|
||||||
assertTrue(okButton.isEnabled());
|
assertTrue(okButton.isEnabled());
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> okButton.getActionListeners()[0].actionPerformed(null));
|
runSwing(() -> okButton.getActionListeners()[0].actionPerformed(null));
|
||||||
|
|
||||||
program.flushEvents();
|
program.flushEvents();
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
assertEquals("01001000", model.getValueAt(0, MemoryMapModel.START));
|
assertEquals("01001000", model.getValueAt(0, MemoryMapModel.START));
|
||||||
assertEquals("010055ff", model.getValueAt(0, MemoryMapModel.END));
|
assertEquals("010055ff", model.getValueAt(0, MemoryMapModel.END));
|
||||||
|
@ -364,17 +360,17 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
performAction(action, false);
|
performAction(action, false);
|
||||||
|
|
||||||
// find the dialog for the add
|
// find the dialog for the add
|
||||||
final SplitBlockDialog d =
|
SplitBlockDialog d =
|
||||||
waitForDialogComponent(tool.getToolFrame(), SplitBlockDialog.class, 2000);
|
waitForDialogComponent(SplitBlockDialog.class);
|
||||||
final AddressInput blockOneEnd =
|
AddressInput blockOneEnd =
|
||||||
(AddressInput) findComponentByName(d.getComponent(), "BlockOneEnd");
|
(AddressInput) findComponentByName(d.getComponent(), "BlockOneEnd");
|
||||||
final JButton okButton = findButton(d.getComponent(), "OK");
|
JButton okButton = findButton(d.getComponent(), "OK");
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> blockOneEnd.setValue("01000"));
|
runSwing(() -> blockOneEnd.setValue("01000"));
|
||||||
assertTrue(!okButton.isEnabled());
|
assertFalse(okButton.isEnabled());
|
||||||
assertEquals("End address must be greater than start",
|
assertEquals("End address must be greater than start",
|
||||||
findLabelStr(d.getComponent(), "statusLabel"));
|
findLabelStr(d.getComponent(), "statusLabel"));
|
||||||
runSwing(() -> d.close());
|
close(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -386,17 +382,17 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
performAction(action, false);
|
performAction(action, false);
|
||||||
|
|
||||||
// find the dialog for the add
|
// find the dialog for the add
|
||||||
final SplitBlockDialog d =
|
SplitBlockDialog d =
|
||||||
waitForDialogComponent(tool.getToolFrame(), SplitBlockDialog.class, 2000);
|
waitForDialogComponent(SplitBlockDialog.class);
|
||||||
final AddressInput blockTwoStart =
|
AddressInput blockTwoStart =
|
||||||
(AddressInput) findComponentByName(d.getComponent(), "BlockTwoStart");
|
(AddressInput) findComponentByName(d.getComponent(), "BlockTwoStart");
|
||||||
final JButton okButton = findButton(d.getComponent(), "OK");
|
JButton okButton = findButton(d.getComponent(), "OK");
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> blockTwoStart.setValue("01000"));
|
runSwing(() -> blockTwoStart.setValue("01000"));
|
||||||
assertTrue(!okButton.isEnabled());
|
assertFalse(okButton.isEnabled());
|
||||||
assertEquals("Start address must be greater than original block start (01001000)",
|
assertEquals("Start address must be greater than original block start (01001000)",
|
||||||
findLabelStr(d.getComponent(), "statusLabel"));
|
findLabelStr(d.getComponent(), "statusLabel"));
|
||||||
runSwing(() -> d.close());
|
close(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -408,15 +404,15 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
performAction(action, false);
|
performAction(action, false);
|
||||||
|
|
||||||
// find the dialog for the add
|
// find the dialog for the add
|
||||||
final SplitBlockDialog d =
|
SplitBlockDialog d =
|
||||||
waitForDialogComponent(tool.getToolFrame(), SplitBlockDialog.class, 2000);
|
waitForDialogComponent(SplitBlockDialog.class);
|
||||||
final RegisterField blockOneLength =
|
RegisterField blockOneLength =
|
||||||
(RegisterField) findComponentByName(d.getComponent(), "BlockOneLength");
|
(RegisterField) findComponentByName(d.getComponent(), "BlockOneLength");
|
||||||
final JButton okButton = findButton(d.getComponent(), "OK");
|
JButton okButton = findButton(d.getComponent(), "OK");
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> blockOneLength.setText(""));
|
runSwing(() -> blockOneLength.setText(""));
|
||||||
assertTrue(!okButton.isEnabled());
|
assertFalse(okButton.isEnabled());
|
||||||
runSwing(() -> d.close());
|
close(d);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,24 +426,24 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
performAction(action, false);
|
performAction(action, false);
|
||||||
|
|
||||||
// find the dialog for the add
|
// find the dialog for the add
|
||||||
final SplitBlockDialog d =
|
SplitBlockDialog d =
|
||||||
waitForDialogComponent(tool.getToolFrame(), SplitBlockDialog.class, 2000);
|
waitForDialogComponent(SplitBlockDialog.class);
|
||||||
|
|
||||||
final JTextField blockTwoName =
|
JTextField blockTwoName =
|
||||||
(JTextField) findComponentByName(d.getComponent(), "BlockTwoName");
|
(JTextField) findComponentByName(d.getComponent(), "BlockTwoName");
|
||||||
final RegisterField blockTwoLength =
|
RegisterField blockTwoLength =
|
||||||
(RegisterField) findComponentByName(d.getComponent(), "BlockTwoLength");
|
(RegisterField) findComponentByName(d.getComponent(), "BlockTwoLength");
|
||||||
final JButton okButton = findButton(d.getComponent(), "OK");
|
JButton okButton = findButton(d.getComponent(), "OK");
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> {
|
runSwing(() -> {
|
||||||
blockTwoLength.setText("0x2000");
|
blockTwoLength.setText("0x2000");
|
||||||
blockTwoName.setText("split &%");
|
blockTwoName.setText("split &%");
|
||||||
});
|
});
|
||||||
assertTrue(okButton.isEnabled());
|
assertTrue(okButton.isEnabled());
|
||||||
SwingUtilities.invokeAndWait(() -> okButton.getActionListeners()[0].actionPerformed(null));
|
runSwing(() -> okButton.getActionListeners()[0].actionPerformed(null));
|
||||||
|
|
||||||
assertTrue(findLabelStr(d.getComponent(), "statusLabel").startsWith("Invalid Block Name"));
|
assertTrue(findLabelStr(d.getComponent(), "statusLabel").startsWith("Invalid Block Name"));
|
||||||
runSwing(() -> d.close());
|
close(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -455,19 +451,19 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
// create an overlay block
|
// create an overlay block
|
||||||
int transactionID = program.startTransaction("test");
|
int transactionID = program.startTransaction("test");
|
||||||
memory.createInitializedBlock(".overlay", getAddr(0), 0x100, (byte) 0xa,
|
memory.createInitializedBlock(".overlay", getAddr(0), 0x100, (byte) 0xa,
|
||||||
TaskMonitorAdapter.DUMMY_MONITOR, true);
|
TaskMonitor.DUMMY, true);
|
||||||
program.endTransaction(transactionID, true);
|
program.endTransaction(transactionID, true);
|
||||||
program.flushEvents();
|
program.flushEvents();
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
int row = table.getModel().getRowCount() - 1;
|
int row = table.getModel().getRowCount() - 1;
|
||||||
table.setRowSelectionInterval(row, row);
|
table.setRowSelectionInterval(row, row);
|
||||||
DockingActionIf action = getAction(plugin, "Split Block");
|
DockingActionIf action = getAction(plugin, "Split Block");
|
||||||
performAction(action, false);
|
performAction(action, false);
|
||||||
final OptionDialog d =
|
OptionDialog d =
|
||||||
waitForDialogComponent(tool.getToolFrame(), OptionDialog.class, 2000);
|
waitForDialogComponent(OptionDialog.class);
|
||||||
assertNotNull(d);
|
assertNotNull(d);
|
||||||
assertEquals("Split Overlay Block Not Allowed", d.getTitle());
|
assertEquals("Split Overlay Block Not Allowed", d.getTitle());
|
||||||
runSwing(() -> d.close());
|
close(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -475,29 +471,28 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
// create an overlay block
|
// create an overlay block
|
||||||
int transactionID = program.startTransaction("test");
|
int transactionID = program.startTransaction("test");
|
||||||
memory.createInitializedBlock(".overlay", getAddr(0), 0x100, (byte) 0xa,
|
memory.createInitializedBlock(".overlay", getAddr(0), 0x100, (byte) 0xa,
|
||||||
TaskMonitorAdapter.DUMMY_MONITOR, true);
|
TaskMonitor.DUMMY, true);
|
||||||
program.endTransaction(transactionID, true);
|
program.endTransaction(transactionID, true);
|
||||||
program.flushEvents();
|
program.flushEvents();
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
int row = table.getModel().getRowCount() - 1;
|
int row = table.getModel().getRowCount() - 1;
|
||||||
table.setRowSelectionInterval(row, row);
|
table.setRowSelectionInterval(row, row);
|
||||||
DockingActionIf action = getAction(plugin, "Expand Block Up");
|
DockingActionIf action = getAction(plugin, "Expand Block Up");
|
||||||
performAction(action, false);
|
performAction(action, false);
|
||||||
final OptionDialog d =
|
OptionDialog d =
|
||||||
waitForDialogComponent(tool.getToolFrame(), OptionDialog.class, 2000);
|
waitForDialogComponent(OptionDialog.class);
|
||||||
assertNotNull(d);
|
assertNotNull(d);
|
||||||
assertEquals("Expand Overlay Block Not Allowed", d.getTitle());
|
assertEquals("Expand Overlay Block Not Allowed", d.getTitle());
|
||||||
runSwing(() -> d.close());
|
close(d);
|
||||||
|
|
||||||
action = getAction(plugin, "Expand Block Down");
|
action = getAction(plugin, "Expand Block Down");
|
||||||
performAction(action, false);
|
performAction(action, false);
|
||||||
|
|
||||||
final OptionDialog d2 =
|
OptionDialog d2 =
|
||||||
waitForDialogComponent(tool.getToolFrame(), OptionDialog.class, 2000);
|
waitForDialogComponent(OptionDialog.class);
|
||||||
assertNotNull(d2);
|
assertNotNull(d2);
|
||||||
assertEquals("Expand Overlay Block Not Allowed", d2.getTitle());
|
assertEquals("Expand Overlay Block Not Allowed", d2.getTitle());
|
||||||
runSwing(() -> d2.close());
|
runSwing(() -> d2.close());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -510,29 +505,29 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
assertTrue(action.isEnabled());
|
assertTrue(action.isEnabled());
|
||||||
|
|
||||||
// find the dialog for the add
|
// find the dialog for the add
|
||||||
final ExpandBlockDialog d =
|
ExpandBlockDialog d =
|
||||||
waitForDialogComponent(tool.getToolFrame(), ExpandBlockDialog.class, 2000);
|
waitForDialogComponent(ExpandBlockDialog.class);
|
||||||
assertNotNull(d);
|
assertNotNull(d);
|
||||||
assertEquals("Expand Block Up", d.getTitle());
|
assertEquals("Expand Block Up", d.getTitle());
|
||||||
|
|
||||||
final AddressInput start =
|
AddressInput start =
|
||||||
(AddressInput) findComponentByName(d.getComponent(), "NewStartAddress");
|
(AddressInput) findComponentByName(d.getComponent(), "NewStartAddress");
|
||||||
final JTextField end = (JTextField) findComponentByName(d.getComponent(), "EndAddress");
|
JTextField end = (JTextField) findComponentByName(d.getComponent(), "EndAddress");
|
||||||
final RegisterField length =
|
RegisterField length =
|
||||||
(RegisterField) findComponentByName(d.getComponent(), "BlockLength");
|
(RegisterField) findComponentByName(d.getComponent(), "BlockLength");
|
||||||
final JButton okButton = findButton(d.getComponent(), "OK");
|
JButton okButton = findButton(d.getComponent(), "OK");
|
||||||
|
|
||||||
assertNotNull(start);
|
assertNotNull(start);
|
||||||
assertNotNull(end);
|
assertNotNull(end);
|
||||||
assertNotNull(length);
|
assertNotNull(length);
|
||||||
assertNotNull(okButton);
|
assertNotNull(okButton);
|
||||||
|
|
||||||
assertTrue(!okButton.isEnabled());
|
assertFalse(okButton.isEnabled());
|
||||||
assertTrue(!end.isEnabled());
|
assertFalse(end.isEnabled());
|
||||||
assertEquals(getAddr(0x01001000), start.getAddress());
|
assertEquals(getAddr(0x01001000), start.getAddress());
|
||||||
assertEquals("010075ff", end.getText());
|
assertEquals("010075ff", end.getText());
|
||||||
assertEquals("0x6600", length.getText());
|
assertEquals("0x6600", length.getText());
|
||||||
runSwing(() -> d.close());
|
close(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -547,22 +542,22 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
|
|
||||||
// find the dialog for the add
|
// find the dialog for the add
|
||||||
ExpandBlockDialog d =
|
ExpandBlockDialog d =
|
||||||
waitForDialogComponent(tool.getToolFrame(), ExpandBlockDialog.class, 2000);
|
waitForDialogComponent(ExpandBlockDialog.class);
|
||||||
|
|
||||||
final AddressInput start =
|
AddressInput start =
|
||||||
(AddressInput) findComponentByName(d.getComponent(), "NewStartAddress");
|
(AddressInput) findComponentByName(d.getComponent(), "NewStartAddress");
|
||||||
final JTextField end = (JTextField) findComponentByName(d.getComponent(), "EndAddress");
|
JTextField end = (JTextField) findComponentByName(d.getComponent(), "EndAddress");
|
||||||
assertNotNull(end);
|
assertNotNull(end);
|
||||||
final RegisterField length =
|
RegisterField length =
|
||||||
(RegisterField) findComponentByName(d.getComponent(), "BlockLength");
|
(RegisterField) findComponentByName(d.getComponent(), "BlockLength");
|
||||||
final JButton okButton = findButton(d.getComponent(), "OK");
|
JButton okButton = findButton(d.getComponent(), "OK");
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> start.setValue("00002000"));
|
runSwing(() -> start.setValue("00002000"));
|
||||||
assertEquals("0x1005600", length.getText());
|
assertEquals("0x1005600", length.getText());
|
||||||
|
|
||||||
assertTrue(okButton.isEnabled());
|
assertTrue(okButton.isEnabled());
|
||||||
SwingUtilities.invokeAndWait(() -> okButton.getActionListeners()[0].actionPerformed(null));
|
runSwing(() -> okButton.getActionListeners()[0].actionPerformed(null));
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
assertEquals(".text.exp", model.getValueAt(0, MemoryMapModel.NAME));
|
assertEquals(".text.exp", model.getValueAt(0, MemoryMapModel.NAME));
|
||||||
assertEquals("00002000", model.getValueAt(0, MemoryMapModel.START));
|
assertEquals("00002000", model.getValueAt(0, MemoryMapModel.START));
|
||||||
|
@ -593,21 +588,21 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
assertTrue(action.isEnabled());
|
assertTrue(action.isEnabled());
|
||||||
|
|
||||||
// find the dialog for the add
|
// find the dialog for the add
|
||||||
final ExpandBlockDialog d =
|
ExpandBlockDialog d =
|
||||||
waitForDialogComponent(tool.getToolFrame(), ExpandBlockDialog.class, 2000);
|
waitForDialogComponent(ExpandBlockDialog.class);
|
||||||
|
|
||||||
final AddressInput start =
|
AddressInput start =
|
||||||
(AddressInput) findComponentByName(d.getComponent(), "NewStartAddress");
|
(AddressInput) findComponentByName(d.getComponent(), "NewStartAddress");
|
||||||
final RegisterField length =
|
RegisterField length =
|
||||||
(RegisterField) findComponentByName(d.getComponent(), "BlockLength");
|
(RegisterField) findComponentByName(d.getComponent(), "BlockLength");
|
||||||
assertNotNull(length);
|
assertNotNull(length);
|
||||||
final JButton okButton = findButton(d.getComponent(), "OK");
|
JButton okButton = findButton(d.getComponent(), "OK");
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> start.setValue("01201000"));
|
runSwing(() -> start.setValue("01201000"));
|
||||||
assertTrue(!okButton.isEnabled());
|
assertFalse(okButton.isEnabled());
|
||||||
assertEquals("Start must be less than 01001000",
|
assertEquals("Start must be less than 01001000",
|
||||||
findLabelStr(d.getComponent(), "statusLabel"));
|
findLabelStr(d.getComponent(), "statusLabel"));
|
||||||
runSwing(() -> d.close());
|
close(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -622,21 +617,21 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
|
|
||||||
// find the dialog for the add
|
// find the dialog for the add
|
||||||
ExpandBlockDialog d =
|
ExpandBlockDialog d =
|
||||||
waitForDialogComponent(tool.getToolFrame(), ExpandBlockDialog.class, 2000);
|
waitForDialogComponent(ExpandBlockDialog.class);
|
||||||
final AddressInput start =
|
AddressInput start =
|
||||||
(AddressInput) findComponentByName(d.getComponent(), "NewStartAddress");
|
(AddressInput) findComponentByName(d.getComponent(), "NewStartAddress");
|
||||||
final JTextField end = (JTextField) findComponentByName(d.getComponent(), "EndAddress");
|
JTextField end = (JTextField) findComponentByName(d.getComponent(), "EndAddress");
|
||||||
final RegisterField length =
|
RegisterField length =
|
||||||
(RegisterField) findComponentByName(d.getComponent(), "BlockLength");
|
(RegisterField) findComponentByName(d.getComponent(), "BlockLength");
|
||||||
final JButton okButton = findButton(d.getComponent(), "OK");
|
JButton okButton = findButton(d.getComponent(), "OK");
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> length.setText("0x7600"));
|
runSwing(() -> length.setText("0x7600"));
|
||||||
assertEquals(getAddr(0x01000000), start.getAddress());
|
assertEquals(getAddr(0x01000000), start.getAddress());
|
||||||
assertEquals("010075ff", end.getText());
|
assertEquals("010075ff", end.getText());
|
||||||
|
|
||||||
assertTrue(okButton.isEnabled());
|
assertTrue(okButton.isEnabled());
|
||||||
SwingUtilities.invokeAndWait(() -> okButton.getActionListeners()[0].actionPerformed(null));
|
runSwing(() -> okButton.getActionListeners()[0].actionPerformed(null));
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
assertEquals(".text.exp", model.getValueAt(0, MemoryMapModel.NAME));
|
assertEquals(".text.exp", model.getValueAt(0, MemoryMapModel.NAME));
|
||||||
assertEquals("01000000", model.getValueAt(0, MemoryMapModel.START));
|
assertEquals("01000000", model.getValueAt(0, MemoryMapModel.START));
|
||||||
|
@ -667,22 +662,22 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
assertTrue(action.isEnabled());
|
assertTrue(action.isEnabled());
|
||||||
|
|
||||||
// find the dialog for the add
|
// find the dialog for the add
|
||||||
final ExpandBlockDialog d =
|
ExpandBlockDialog d =
|
||||||
waitForDialogComponent(tool.getToolFrame(), ExpandBlockDialog.class, 2000);
|
waitForDialogComponent(ExpandBlockDialog.class);
|
||||||
|
|
||||||
final AddressInput start =
|
AddressInput start =
|
||||||
(AddressInput) findComponentByName(d.getComponent(), "NewStartAddress");
|
(AddressInput) findComponentByName(d.getComponent(), "NewStartAddress");
|
||||||
assertNotNull(start);
|
assertNotNull(start);
|
||||||
final RegisterField length =
|
RegisterField length =
|
||||||
(RegisterField) findComponentByName(d.getComponent(), "BlockLength");
|
(RegisterField) findComponentByName(d.getComponent(), "BlockLength");
|
||||||
final JButton okButton = findButton(d.getComponent(), "OK");
|
JButton okButton = findButton(d.getComponent(), "OK");
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> length.setText("0x1000"));
|
runSwing(() -> length.setText("0x1000"));
|
||||||
|
|
||||||
assertTrue(!okButton.isEnabled());
|
assertFalse(okButton.isEnabled());
|
||||||
assertEquals("Block size must be greater than 6600",
|
assertEquals("Block size must be greater than 6600",
|
||||||
findLabelStr(d.getComponent(), "statusLabel"));
|
findLabelStr(d.getComponent(), "statusLabel"));
|
||||||
runSwing(() -> d.close());
|
close(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -697,24 +692,24 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
assertTrue(action.isEnabled());
|
assertTrue(action.isEnabled());
|
||||||
|
|
||||||
// find the dialog for the add
|
// find the dialog for the add
|
||||||
final ExpandBlockDialog d =
|
ExpandBlockDialog d =
|
||||||
waitForDialogComponent(tool.getToolFrame(), ExpandBlockDialog.class, 2000);
|
waitForDialogComponent(ExpandBlockDialog.class);
|
||||||
|
|
||||||
final AddressInput start =
|
AddressInput start =
|
||||||
(AddressInput) findComponentByName(d.getComponent(), "NewStartAddress");
|
(AddressInput) findComponentByName(d.getComponent(), "NewStartAddress");
|
||||||
final JTextField end = (JTextField) findComponentByName(d.getComponent(), "EndAddress");
|
JTextField end = (JTextField) findComponentByName(d.getComponent(), "EndAddress");
|
||||||
final JButton okButton = findButton(d.getComponent(), "OK");
|
JButton okButton = findButton(d.getComponent(), "OK");
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> start.setValue("01008000"));
|
runSwing(() -> start.setValue("01008000"));
|
||||||
assertEquals("0100f3ff", end.getText());
|
assertEquals("0100f3ff", end.getText());
|
||||||
assertTrue(okButton.isEnabled());
|
assertTrue(okButton.isEnabled());
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> okButton.getActionListeners()[0].actionPerformed(null));
|
runSwing(() -> okButton.getActionListeners()[0].actionPerformed(null));
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
assertTrue(!okButton.isEnabled());
|
assertFalse(okButton.isEnabled());
|
||||||
assertEquals("Part of range (01008000, 01009fff) already exists in memory.",
|
assertEquals("Part of range (01008000, 01009fff) already exists in memory.",
|
||||||
findLabelStr(d.getComponent(), "statusLabel"));
|
findLabelStr(d.getComponent(), "statusLabel"));
|
||||||
runSwing(() -> d.close());
|
close(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -726,30 +721,30 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
assertTrue(action.isEnabled());
|
assertTrue(action.isEnabled());
|
||||||
|
|
||||||
// find the dialog for the add
|
// find the dialog for the add
|
||||||
final ExpandBlockDialog d =
|
ExpandBlockDialog d =
|
||||||
waitForDialogComponent(tool.getToolFrame(), ExpandBlockDialog.class, 2000);
|
waitForDialogComponent(ExpandBlockDialog.class);
|
||||||
assertNotNull(d);
|
assertNotNull(d);
|
||||||
assertEquals("Expand Block Down", d.getTitle());
|
assertEquals("Expand Block Down", d.getTitle());
|
||||||
|
|
||||||
final JTextField start = (JTextField) findComponentByName(d.getComponent(), "StartAddress");
|
JTextField start = (JTextField) findComponentByName(d.getComponent(), "StartAddress");
|
||||||
final AddressInput end = (AddressInput) findComponentByName(d.getComponent(), "EndAddress");
|
AddressInput end = (AddressInput) findComponentByName(d.getComponent(), "EndAddress");
|
||||||
final RegisterField length =
|
RegisterField length =
|
||||||
(RegisterField) findComponentByName(d.getComponent(), "BlockLength");
|
(RegisterField) findComponentByName(d.getComponent(), "BlockLength");
|
||||||
final JButton okButton = findButton(d.getComponent(), "OK");
|
JButton okButton = findButton(d.getComponent(), "OK");
|
||||||
|
|
||||||
assertNotNull(start);
|
assertNotNull(start);
|
||||||
assertNotNull(end);
|
assertNotNull(end);
|
||||||
assertNotNull(length);
|
assertNotNull(length);
|
||||||
assertNotNull(okButton);
|
assertNotNull(okButton);
|
||||||
|
|
||||||
assertTrue(!okButton.isEnabled());
|
assertFalse(okButton.isEnabled());
|
||||||
assertTrue(!start.isEnabled());
|
assertFalse(start.isEnabled());
|
||||||
assertTrue(end.isEnabled());
|
assertTrue(end.isEnabled());
|
||||||
assertEquals("01001000", start.getText());
|
assertEquals("01001000", start.getText());
|
||||||
assertEquals(getAddr(0x010075ff), end.getAddress());
|
assertEquals(getAddr(0x010075ff), end.getAddress());
|
||||||
assertEquals("0x6600", length.getText());
|
assertEquals("0x6600", length.getText());
|
||||||
|
|
||||||
runSwing(() -> d.close());
|
close(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -761,19 +756,19 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
|
|
||||||
// find the dialog for the add
|
// find the dialog for the add
|
||||||
ExpandBlockDialog d =
|
ExpandBlockDialog d =
|
||||||
waitForDialogComponent(tool.getToolFrame(), ExpandBlockDialog.class, 2000);
|
waitForDialogComponent(ExpandBlockDialog.class);
|
||||||
|
|
||||||
final AddressInput end = (AddressInput) findComponentByName(d.getComponent(), "EndAddress");
|
AddressInput end = (AddressInput) findComponentByName(d.getComponent(), "EndAddress");
|
||||||
final RegisterField length =
|
RegisterField length =
|
||||||
(RegisterField) findComponentByName(d.getComponent(), "BlockLength");
|
(RegisterField) findComponentByName(d.getComponent(), "BlockLength");
|
||||||
final JButton okButton = findButton(d.getComponent(), "OK");
|
JButton okButton = findButton(d.getComponent(), "OK");
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> end.setValue("01007700"));
|
runSwing(() -> end.setValue("01007700"));
|
||||||
assertEquals("0x6701", length.getText());
|
assertEquals("0x6701", length.getText());
|
||||||
assertTrue(okButton.isEnabled());
|
assertTrue(okButton.isEnabled());
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> okButton.getActionListeners()[0].actionPerformed(null));
|
runSwing(() -> okButton.getActionListeners()[0].actionPerformed(null));
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
assertEquals(".text.exp", model.getValueAt(0, MemoryMapModel.NAME));
|
assertEquals(".text.exp", model.getValueAt(0, MemoryMapModel.NAME));
|
||||||
assertEquals("01001000", model.getValueAt(0, MemoryMapModel.START));
|
assertEquals("01001000", model.getValueAt(0, MemoryMapModel.START));
|
||||||
|
@ -790,19 +785,19 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
|
|
||||||
// find the dialog for the add
|
// find the dialog for the add
|
||||||
ExpandBlockDialog d =
|
ExpandBlockDialog d =
|
||||||
waitForDialogComponent(tool.getToolFrame(), ExpandBlockDialog.class, 2000);
|
waitForDialogComponent(ExpandBlockDialog.class);
|
||||||
|
|
||||||
final AddressInput end = (AddressInput) findComponentByName(d.getComponent(), "EndAddress");
|
AddressInput end = (AddressInput) findComponentByName(d.getComponent(), "EndAddress");
|
||||||
final RegisterField length =
|
RegisterField length =
|
||||||
(RegisterField) findComponentByName(d.getComponent(), "BlockLength");
|
(RegisterField) findComponentByName(d.getComponent(), "BlockLength");
|
||||||
final JButton okButton = findButton(d.getComponent(), "OK");
|
JButton okButton = findButton(d.getComponent(), "OK");
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> length.setText("0x6700"));
|
runSwing(() -> length.setText("0x6700"));
|
||||||
assertEquals(getAddr(0x10076ff), end.getAddress());
|
assertEquals(getAddr(0x10076ff), end.getAddress());
|
||||||
assertTrue(okButton.isEnabled());
|
assertTrue(okButton.isEnabled());
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> okButton.getActionListeners()[0].actionPerformed(null));
|
runSwing(() -> okButton.getActionListeners()[0].actionPerformed(null));
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
assertEquals(".text.exp", model.getValueAt(0, MemoryMapModel.NAME));
|
assertEquals(".text.exp", model.getValueAt(0, MemoryMapModel.NAME));
|
||||||
assertEquals("01001000", model.getValueAt(0, MemoryMapModel.START));
|
assertEquals("01001000", model.getValueAt(0, MemoryMapModel.START));
|
||||||
|
@ -820,17 +815,17 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
performAction(action, false);
|
performAction(action, false);
|
||||||
|
|
||||||
// find the dialog for the add
|
// find the dialog for the add
|
||||||
final ExpandBlockDialog d =
|
ExpandBlockDialog d =
|
||||||
waitForDialogComponent(tool.getToolFrame(), ExpandBlockDialog.class, 2000);
|
waitForDialogComponent(ExpandBlockDialog.class);
|
||||||
|
|
||||||
final AddressInput end = (AddressInput) findComponentByName(d.getComponent(), "EndAddress");
|
AddressInput end = (AddressInput) findComponentByName(d.getComponent(), "EndAddress");
|
||||||
final JButton okButton = findButton(d.getComponent(), "OK");
|
JButton okButton = findButton(d.getComponent(), "OK");
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> end.setValue("01007000"));
|
runSwing(() -> end.setValue("01007000"));
|
||||||
assertTrue(!okButton.isEnabled());
|
assertFalse(okButton.isEnabled());
|
||||||
assertEquals("End must be greater than 010075ff",
|
assertEquals("End must be greater than 010075ff",
|
||||||
findLabelStr(d.getComponent(), "statusLabel"));
|
findLabelStr(d.getComponent(), "statusLabel"));
|
||||||
runSwing(() -> d.close());
|
close(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -842,18 +837,18 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
performAction(action, false);
|
performAction(action, false);
|
||||||
|
|
||||||
// find the dialog for the add
|
// find the dialog for the add
|
||||||
final ExpandBlockDialog d =
|
ExpandBlockDialog d =
|
||||||
waitForDialogComponent(tool.getToolFrame(), ExpandBlockDialog.class, 2000);
|
waitForDialogComponent(ExpandBlockDialog.class);
|
||||||
|
|
||||||
final RegisterField length =
|
RegisterField length =
|
||||||
(RegisterField) findComponentByName(d.getComponent(), "BlockLength");
|
(RegisterField) findComponentByName(d.getComponent(), "BlockLength");
|
||||||
final JButton okButton = findButton(d.getComponent(), "OK");
|
JButton okButton = findButton(d.getComponent(), "OK");
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> length.setText("0x670"));
|
runSwing(() -> length.setText("0x670"));
|
||||||
assertTrue(!okButton.isEnabled());
|
assertFalse(okButton.isEnabled());
|
||||||
assertEquals("Block size must be greater than 6600",
|
assertEquals("Block size must be greater than 6600",
|
||||||
findLabelStr(d.getComponent(), "statusLabel"));
|
findLabelStr(d.getComponent(), "statusLabel"));
|
||||||
runSwing(() -> d.close());
|
close(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -865,30 +860,28 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
performAction(action, false);
|
performAction(action, false);
|
||||||
|
|
||||||
// find the dialog for the add
|
// find the dialog for the add
|
||||||
final ExpandBlockDialog d =
|
ExpandBlockDialog d =
|
||||||
waitForDialogComponent(tool.getToolFrame(), ExpandBlockDialog.class, 2000);
|
waitForDialogComponent(ExpandBlockDialog.class);
|
||||||
|
|
||||||
final RegisterField length =
|
RegisterField length =
|
||||||
(RegisterField) findComponentByName(d.getComponent(), "BlockLength");
|
(RegisterField) findComponentByName(d.getComponent(), "BlockLength");
|
||||||
final JButton okButton = findButton(d.getComponent(), "OK");
|
JButton okButton = findButton(d.getComponent(), "OK");
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() -> length.setText("0x7600"));
|
runSwing(() -> length.setText("0x7600"));
|
||||||
assertTrue(okButton.isEnabled());
|
assertTrue(okButton.isEnabled());
|
||||||
SwingUtilities.invokeAndWait(() -> okButton.getActionListeners()[0].actionPerformed(null));
|
runSwing(() -> okButton.getActionListeners()[0].actionPerformed(null));
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
assertTrue(!okButton.isEnabled());
|
assertFalse(okButton.isEnabled());
|
||||||
assertEquals("Part of range (01007600, 010085ff) already exists in memory.",
|
assertEquals("Part of range (01007600, 010085ff) already exists in memory.",
|
||||||
findLabelStr(d.getComponent(), "statusLabel"));
|
findLabelStr(d.getComponent(), "statusLabel"));
|
||||||
runSwing(() -> d.close());
|
close(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
private void showProvider() {
|
private void showProvider() {
|
||||||
DockingActionIf action = getAction(plugin, "Memory Map");
|
DockingActionIf action = getAction(plugin, "Memory Map");
|
||||||
performAction(action, true);
|
performAction(action, true);
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
provider = plugin.getMemoryMapProvider();
|
provider = plugin.getMemoryMapProvider();
|
||||||
table = provider.getTable();
|
table = provider.getTable();
|
||||||
model = table.getModel();
|
model = table.getModel();
|
||||||
|
|
|
@ -20,11 +20,13 @@ import static org.junit.Assert.*;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Container;
|
import java.awt.Container;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JTable;
|
||||||
import javax.swing.table.TableModel;
|
import javax.swing.table.TableModel;
|
||||||
|
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
|
|
||||||
|
import docking.AbstractErrDialog;
|
||||||
import docking.action.DockingActionIf;
|
import docking.action.DockingActionIf;
|
||||||
import docking.widgets.MultiLineLabel;
|
import docking.widgets.MultiLineLabel;
|
||||||
import docking.widgets.OptionDialog;
|
import docking.widgets.OptionDialog;
|
||||||
|
@ -38,7 +40,7 @@ import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.model.mem.Memory;
|
import ghidra.program.model.mem.Memory;
|
||||||
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
||||||
import ghidra.test.TestEnv;
|
import ghidra.test.TestEnv;
|
||||||
import ghidra.util.task.TaskMonitorAdapter;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for merging memory blocks.
|
* Tests for merging memory blocks.
|
||||||
|
@ -86,25 +88,22 @@ public class MemoryMapProvider4Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void tearDown() throws Exception {
|
public void tearDown() throws Exception {
|
||||||
env.release(program);
|
|
||||||
env.dispose();
|
env.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMergeBlocks() throws Exception {
|
public void testMergeBlocks() throws Exception {
|
||||||
// create 4 blocks: 0-0f, 10-1f, 20-20f, 40-4f.
|
// create 4 blocks: 0-0f, 10-1f, 20-20f, 40-4f.
|
||||||
int transactionID = program.startTransaction("test");
|
tx(program, () -> {
|
||||||
memory.createInitializedBlock("block1", getAddr(0), 0x10, (byte) 0,
|
memory.createInitializedBlock("block1", getAddr(0), 0x10, (byte) 0,
|
||||||
TaskMonitorAdapter.DUMMY_MONITOR, false);
|
TaskMonitor.DUMMY, false);
|
||||||
memory.createInitializedBlock("block2", getAddr(0x10), 0x10, (byte) 0,
|
memory.createInitializedBlock("block2", getAddr(0x10), 0x10, (byte) 0,
|
||||||
TaskMonitorAdapter.DUMMY_MONITOR, false);
|
TaskMonitor.DUMMY, false);
|
||||||
memory.createInitializedBlock("block3", getAddr(0x20), 0x10, (byte) 0,
|
memory.createInitializedBlock("block3", getAddr(0x20), 0x10, (byte) 0,
|
||||||
TaskMonitorAdapter.DUMMY_MONITOR, false);
|
TaskMonitor.DUMMY, false);
|
||||||
memory.createInitializedBlock("block4", getAddr(0x40), 0x10, (byte) 0,
|
memory.createInitializedBlock("block4", getAddr(0x40), 0x10, (byte) 0,
|
||||||
TaskMonitorAdapter.DUMMY_MONITOR, false);
|
TaskMonitor.DUMMY, false);
|
||||||
program.endTransaction(transactionID, true);
|
});
|
||||||
program.flushEvents();
|
|
||||||
waitForPostedSwingRunnables();
|
|
||||||
|
|
||||||
assertEquals("0000004f", model.getValueAt(3, MemoryMapModel.END));
|
assertEquals("0000004f", model.getValueAt(3, MemoryMapModel.END));
|
||||||
// select rows 0 through 3
|
// select rows 0 through 3
|
||||||
|
@ -112,7 +111,7 @@ public class MemoryMapProvider4Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
DockingActionIf action = getAction(plugin, "Merge Blocks");
|
DockingActionIf action = getAction(plugin, "Merge Blocks");
|
||||||
assertTrue(action.isEnabled());
|
assertTrue(action.isEnabled());
|
||||||
performAction(action, false);
|
performAction(action, false);
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
assertEquals("block1", model.getValueAt(0, MemoryMapModel.NAME));
|
assertEquals("block1", model.getValueAt(0, MemoryMapModel.NAME));
|
||||||
assertEquals("00000000", model.getValueAt(0, MemoryMapModel.START));
|
assertEquals("00000000", model.getValueAt(0, MemoryMapModel.START));
|
||||||
|
@ -127,18 +126,17 @@ public class MemoryMapProvider4Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
@Test
|
@Test
|
||||||
public void testMergeBlocksDisjoint() throws Exception {
|
public void testMergeBlocksDisjoint() throws Exception {
|
||||||
// create 4 blocks: 0-0f, 10-1f, 20-20f, 40-4f.
|
// create 4 blocks: 0-0f, 10-1f, 20-20f, 40-4f.
|
||||||
int transactionID = program.startTransaction("test");
|
tx(program, () -> {
|
||||||
memory.createInitializedBlock("block1", getAddr(0), 0x10, (byte) 0,
|
memory.createInitializedBlock("block1", getAddr(0), 0x10, (byte) 0,
|
||||||
TaskMonitorAdapter.DUMMY_MONITOR, false);
|
|
||||||
|
TaskMonitor.DUMMY, false);
|
||||||
memory.createInitializedBlock("block2", getAddr(0x10), 0x10, (byte) 0,
|
memory.createInitializedBlock("block2", getAddr(0x10), 0x10, (byte) 0,
|
||||||
TaskMonitorAdapter.DUMMY_MONITOR, false);
|
TaskMonitor.DUMMY, false);
|
||||||
memory.createInitializedBlock("block3", getAddr(0x20), 0x10, (byte) 0,
|
memory.createInitializedBlock("block3", getAddr(0x20), 0x10, (byte) 0,
|
||||||
TaskMonitorAdapter.DUMMY_MONITOR, false);
|
TaskMonitor.DUMMY, false);
|
||||||
memory.createInitializedBlock("block4", getAddr(0x40), 0x10, (byte) 0,
|
memory.createInitializedBlock("block4", getAddr(0x40), 0x10, (byte) 0,
|
||||||
TaskMonitorAdapter.DUMMY_MONITOR, false);
|
TaskMonitor.DUMMY, false);
|
||||||
program.endTransaction(transactionID, true);
|
});
|
||||||
program.flushEvents();
|
|
||||||
waitForPostedSwingRunnables();
|
|
||||||
|
|
||||||
assertEquals("block1", model.getValueAt(0, MemoryMapModel.NAME));
|
assertEquals("block1", model.getValueAt(0, MemoryMapModel.NAME));
|
||||||
assertEquals("block2", model.getValueAt(1, MemoryMapModel.NAME));
|
assertEquals("block2", model.getValueAt(1, MemoryMapModel.NAME));
|
||||||
|
@ -153,26 +151,20 @@ public class MemoryMapProvider4Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
DockingActionIf action = getAction(plugin, "Merge Blocks");
|
DockingActionIf action = getAction(plugin, "Merge Blocks");
|
||||||
assertTrue(action.isEnabled());
|
assertTrue(action.isEnabled());
|
||||||
performAction(action, false);
|
performAction(action, false);
|
||||||
waitForPostedSwingRunnables();
|
AbstractErrDialog d = waitForErrorDialog();
|
||||||
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()));
|
|
||||||
|
|
||||||
runSwing(() -> d.close());
|
assertEquals("Merge Blocks Failed", d.getTitle());
|
||||||
|
assertEquals("Can't merge blocks because they are not contiguous", d.getMessage());
|
||||||
|
close(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMergeBlocksFarApart() throws Exception {
|
public void testMergeBlocksFarApart() throws Exception {
|
||||||
|
|
||||||
int transactionID = program.startTransaction("test");
|
tx(program, () -> {
|
||||||
memory.createInitializedBlock("block1", getAddr(0), 0x50, (byte) 0,
|
memory.createInitializedBlock("block1", getAddr(0), 0x50, (byte) 0,
|
||||||
TaskMonitorAdapter.DUMMY_MONITOR, false);
|
TaskMonitor.DUMMY, false);
|
||||||
program.endTransaction(transactionID, true);
|
});
|
||||||
program.flushEvents();
|
|
||||||
waitForPostedSwingRunnables();
|
|
||||||
|
|
||||||
// select rows 0 and 1
|
// select rows 0 and 1
|
||||||
table.setRowSelectionInterval(0, 1);
|
table.setRowSelectionInterval(0, 1);
|
||||||
|
@ -180,20 +172,19 @@ public class MemoryMapProvider4Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
DockingActionIf action = getAction(plugin, "Merge Blocks");
|
DockingActionIf action = getAction(plugin, "Merge Blocks");
|
||||||
assertTrue(action.isEnabled());
|
assertTrue(action.isEnabled());
|
||||||
performAction(action, false);
|
performAction(action, false);
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
OptionDialog d = waitForDialogComponent(tool.getToolFrame(), OptionDialog.class, 2000);
|
OptionDialog d = waitForDialogComponent(OptionDialog.class);
|
||||||
assertNotNull(d);
|
|
||||||
|
|
||||||
assertEquals("Merge Memory Blocks", d.getTitle());
|
assertEquals("Merge Memory Blocks", d.getTitle());
|
||||||
String message = findMessage(d.getComponent());
|
String message = findMessage(d.getComponent());
|
||||||
assertTrue(
|
assertTrue(
|
||||||
message.startsWith("Merging these blocks will create 16387K extra bytes in memory"));
|
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);
|
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("block1", model.getValueAt(0, MemoryMapModel.NAME));
|
||||||
assertEquals("00000000", model.getValueAt(0, MemoryMapModel.START));
|
assertEquals("00000000", model.getValueAt(0, MemoryMapModel.START));
|
||||||
assertEquals("010075ff", model.getValueAt(0, MemoryMapModel.END));
|
assertEquals("010075ff", model.getValueAt(0, MemoryMapModel.END));
|
||||||
|
@ -217,10 +208,10 @@ public class MemoryMapProvider4Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
|
|
||||||
int transactionID = program.startTransaction("test");
|
int transactionID = program.startTransaction("test");
|
||||||
memory.createInitializedBlock("block1", getAddr(0), 0x50, (byte) 0,
|
memory.createInitializedBlock("block1", getAddr(0), 0x50, (byte) 0,
|
||||||
TaskMonitorAdapter.DUMMY_MONITOR, false);
|
TaskMonitor.DUMMY, false);
|
||||||
program.endTransaction(transactionID, true);
|
program.endTransaction(transactionID, true);
|
||||||
program.flushEvents();
|
program.flushEvents();
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
// select rows 0 and 1
|
// select rows 0 and 1
|
||||||
table.setRowSelectionInterval(0, 1);
|
table.setRowSelectionInterval(0, 1);
|
||||||
|
@ -228,24 +219,21 @@ public class MemoryMapProvider4Test extends AbstractGhidraHeadedIntegrationTest
|
||||||
DockingActionIf action = getAction(plugin, "Merge Blocks");
|
DockingActionIf action = getAction(plugin, "Merge Blocks");
|
||||||
assertTrue(action.isEnabled());
|
assertTrue(action.isEnabled());
|
||||||
performAction(action, false);
|
performAction(action, false);
|
||||||
waitForPostedSwingRunnables();
|
OptionDialog d = waitForDialogComponent(OptionDialog.class);
|
||||||
OptionDialog d = waitForDialogComponent(tool.getToolFrame(), OptionDialog.class, 2000);
|
|
||||||
assertNotNull(d);
|
|
||||||
|
|
||||||
assertEquals("Merge Memory Blocks", d.getTitle());
|
assertEquals("Merge Memory Blocks", d.getTitle());
|
||||||
assertTrue(findMessage(d.getComponent()).startsWith(
|
assertTrue(findMessage(d.getComponent()).startsWith(
|
||||||
"Merging these blocks will create 16387K extra bytes in memory"));
|
"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);
|
assertNotNull(b);
|
||||||
SwingUtilities.invokeAndWait(() -> b.getActionListeners()[0].actionPerformed(null));
|
runSwing(() -> b.getActionListeners()[0].actionPerformed(null));
|
||||||
assertEquals("0000004f", model.getValueAt(0, MemoryMapModel.END));
|
assertEquals("0000004f", model.getValueAt(0, MemoryMapModel.END));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showProvider() {
|
private void showProvider() {
|
||||||
DockingActionIf action = getAction(plugin, "Memory Map");
|
DockingActionIf action = getAction(plugin, "Memory Map");
|
||||||
performAction(action, true);
|
performAction(action, true);
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
provider = plugin.getMemoryMapProvider();
|
provider = plugin.getMemoryMapProvider();
|
||||||
table = provider.getTable();
|
table = provider.getTable();
|
||||||
model = table.getModel();
|
model = table.getModel();
|
||||||
|
|
|
@ -28,11 +28,10 @@ import javax.swing.*;
|
||||||
|
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
|
|
||||||
|
import docking.AbstractErrDialog;
|
||||||
import docking.ActionContext;
|
import docking.ActionContext;
|
||||||
import docking.action.DockingActionIf;
|
import docking.action.DockingActionIf;
|
||||||
import docking.tool.ToolConstants;
|
import docking.tool.ToolConstants;
|
||||||
import docking.widgets.MultiLineLabel;
|
|
||||||
import docking.widgets.OptionDialog;
|
|
||||||
import docking.widgets.table.GTable;
|
import docking.widgets.table.GTable;
|
||||||
import docking.widgets.table.threaded.GThreadedTablePanel;
|
import docking.widgets.table.threaded.GThreadedTablePanel;
|
||||||
import ghidra.app.events.ProgramSelectionPluginEvent;
|
import ghidra.app.events.ProgramSelectionPluginEvent;
|
||||||
|
@ -954,12 +953,9 @@ public class SearchTextPlugin1Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void closeMaxSearchResultsDialog() throws Exception {
|
private void closeMaxSearchResultsDialog() throws Exception {
|
||||||
final OptionDialog d = waitForDialogComponent(OptionDialog.class);
|
AbstractErrDialog d = waitForErrorDialog();
|
||||||
assertNotNull(d);
|
assertTrue(d.getMessage().contains("Stopped search"));
|
||||||
String msg = findMessage(d.getComponent());
|
close(d);
|
||||||
assertNotNull(msg);
|
|
||||||
assertTrue(msg.indexOf("Stopped search") >= 0);
|
|
||||||
runSwing(() -> d.close());
|
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1071,22 +1067,6 @@ public class SearchTextPlugin1Test extends AbstractGhidraHeadedIntegrationTest {
|
||||||
return null;
|
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 {
|
private SearchTextDialog getDialog() throws Exception {
|
||||||
runSwing(() -> searchAction.actionPerformed(provider.getActionContext(null)));
|
runSwing(() -> searchAction.actionPerformed(provider.getActionContext(null)));
|
||||||
return plugin.getSearchDialog();
|
return plugin.getSearchDialog();
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.string;
|
package ghidra.app.plugin.core.string;
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.containsString;
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
@ -83,7 +83,7 @@ public class StringTableProviderTest extends AbstractGhidraHeadedIntegrationTest
|
||||||
CodeViewerProvider cbProvider = cb.getProvider();
|
CodeViewerProvider cbProvider = cb.getProvider();
|
||||||
SwingUtilities.invokeLater(
|
SwingUtilities.invokeLater(
|
||||||
() -> searchAction.actionPerformed(cbProvider.getActionContext(null)));
|
() -> searchAction.actionPerformed(cbProvider.getActionContext(null)));
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
return getDialogComponent(SearchStringDialog.class);
|
return getDialogComponent(SearchStringDialog.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,7 +317,7 @@ public class StringTableProviderTest extends AbstractGhidraHeadedIntegrationTest
|
||||||
selectRows(address); // string abcefg is here
|
selectRows(address); // string abcefg is here
|
||||||
|
|
||||||
performAction(makeStringAction, false);
|
performAction(makeStringAction, false);
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
OptionDialog dialogProvider = getDialogComponent(OptionDialog.class);
|
OptionDialog dialogProvider = getDialogComponent(OptionDialog.class);
|
||||||
assertNotNull(dialogProvider);
|
assertNotNull(dialogProvider);
|
||||||
|
@ -435,13 +435,9 @@ public class StringTableProviderTest extends AbstractGhidraHeadedIntegrationTest
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createDataAt(Address addr) throws Exception {
|
private void createDataAt(Address addr) throws Exception {
|
||||||
int id = program.startTransaction("test");
|
tx(program, () -> {
|
||||||
try {
|
|
||||||
program.getListing().createData(addr, new ByteDataType());
|
program.getListing().createData(addr, new ByteDataType());
|
||||||
}
|
});
|
||||||
finally {
|
|
||||||
program.endTransaction(id, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setCheckbox(final JCheckBox checkbox, final boolean selected) {
|
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,
|
private void toggleDefinedStateButtons(final boolean defined, final boolean undefined,
|
||||||
final boolean partial, final boolean conflicting) {
|
final boolean partial, final boolean conflicting) {
|
||||||
runSwing(() -> {
|
runSwing(() -> {
|
||||||
|
|
|
@ -24,9 +24,9 @@ import javax.swing.*;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
|
||||||
|
import docking.AbstractErrDialog;
|
||||||
import docking.action.DockingActionIf;
|
import docking.action.DockingActionIf;
|
||||||
import docking.test.AbstractDockingTest;
|
import docking.test.AbstractDockingTest;
|
||||||
import docking.widgets.OptionDialog;
|
|
||||||
import docking.widgets.combobox.GhidraComboBox;
|
import docking.widgets.combobox.GhidraComboBox;
|
||||||
import docking.widgets.tree.GTree;
|
import docking.widgets.tree.GTree;
|
||||||
import docking.widgets.tree.GTreeNode;
|
import docking.widgets.tree.GTreeNode;
|
||||||
|
@ -55,16 +55,17 @@ import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
||||||
import ghidra.test.TestEnv;
|
import ghidra.test.TestEnv;
|
||||||
import ghidra.util.SystemUtilities;
|
import ghidra.util.SystemUtilities;
|
||||||
import ghidra.util.exception.*;
|
import ghidra.util.exception.*;
|
||||||
import ghidra.util.task.TaskMonitorAdapter;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for the symbol tree plugin.
|
* 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 String GZF_NAME = "WinHelloCPP.exe";
|
||||||
protected static final String PROGRAM_NAME = "WinHelloCPP";
|
protected static String PROGRAM_NAME = "WinHelloCPP";
|
||||||
protected static final String EXTERNAL_PROGRAM_PATHNAME = "/" + PROGRAM_NAME;
|
protected static String EXTERNAL_PROGRAM_PATHNAME = "/" + PROGRAM_NAME;
|
||||||
|
|
||||||
protected TestEnv env;
|
protected TestEnv env;
|
||||||
protected PluginTool tool;
|
protected PluginTool tool;
|
||||||
|
@ -107,9 +108,6 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
|
||||||
env.showTool();
|
env.showTool();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @see TestCase#tearDown()
|
|
||||||
*/
|
|
||||||
@After
|
@After
|
||||||
public void tearDown() throws Exception {
|
public void tearDown() throws Exception {
|
||||||
closeProgram();
|
closeProgram();
|
||||||
|
@ -120,10 +118,10 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
|
||||||
throws Exception {
|
throws Exception {
|
||||||
selectExternalLocation(libraryName, name);
|
selectExternalLocation(libraryName, name);
|
||||||
performAction(editExternalLocationAction, util.getProvider(), false);
|
performAction(editExternalLocationAction, util.getProvider(), false);
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
|
|
||||||
EditExternalLocationDialog createDialog = AbstractDockingTest.waitForDialogComponent(
|
EditExternalLocationDialog createDialog = AbstractDockingTest.waitForDialogComponent(
|
||||||
plugin.getTool().getToolFrame(), EditExternalLocationDialog.class, 2000);
|
EditExternalLocationDialog.class);
|
||||||
waitForBusyTool(tool);
|
waitForBusyTool(tool);
|
||||||
return createDialog;
|
return createDialog;
|
||||||
}
|
}
|
||||||
|
@ -151,11 +149,7 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//==================================================================================================
|
protected void changeToFunction(EditExternalLocationDialog createDialog,
|
||||||
// Private Methods
|
|
||||||
//==================================================================================================
|
|
||||||
|
|
||||||
protected void changeToFunction(final EditExternalLocationDialog createDialog,
|
|
||||||
boolean isFunction) {
|
boolean isFunction) {
|
||||||
EditExternalLocationPanel extLocPanel = findComponent(
|
EditExternalLocationPanel extLocPanel = findComponent(
|
||||||
createDialog.getComponent().getRootPane(), EditExternalLocationPanel.class);
|
createDialog.getComponent().getRootPane(), EditExternalLocationPanel.class);
|
||||||
|
@ -163,8 +157,8 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
|
||||||
functionCheckBox.setSelected(isFunction);
|
functionCheckBox.setSelected(isFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ExternalLocation setupExternalLocation(final String library, final String label,
|
protected ExternalLocation setupExternalLocation(String library, String label,
|
||||||
final Address address, final SourceType sourceType, boolean isFunction)
|
Address address, SourceType sourceType, boolean isFunction)
|
||||||
throws InvalidInputException, DuplicateNameException {
|
throws InvalidInputException, DuplicateNameException {
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
int transactionID =
|
int transactionID =
|
||||||
|
@ -187,19 +181,19 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ExternalLocation setupExternalLocation(final String library, final String label,
|
protected ExternalLocation setupExternalLocation(String library, String label,
|
||||||
final Address address, final SourceType sourceType)
|
Address address, SourceType sourceType)
|
||||||
throws InvalidInputException, DuplicateNameException {
|
throws InvalidInputException, DuplicateNameException {
|
||||||
return setupExternalLocation(library, label, address, sourceType, false);
|
return setupExternalLocation(library, label, address, sourceType, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ExternalLocation setupExternalFunction(final String library, final String label,
|
protected ExternalLocation setupExternalFunction(String library, String label,
|
||||||
final Address address, final SourceType sourceType)
|
Address address, SourceType sourceType)
|
||||||
throws InvalidInputException, DuplicateNameException {
|
throws InvalidInputException, DuplicateNameException {
|
||||||
return setupExternalLocation(library, label, address, sourceType, true);
|
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 {
|
throws InvalidInputException {
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
int transactionID = program.startTransaction(
|
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);
|
Symbol s = program.getSymbolTable().getLibrarySymbol(libaryName);
|
||||||
if (s instanceof LibrarySymbol) {
|
if (s instanceof LibrarySymbol) {
|
||||||
return (Namespace) s.getObject();
|
return (Namespace) s.getObject();
|
||||||
|
@ -225,27 +219,27 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void closeExternalLocation(final EditExternalLocationDialog createDialog,
|
protected void closeExternalLocation(EditExternalLocationDialog createDialog,
|
||||||
final String buttonText) {
|
String buttonText) {
|
||||||
pressButtonByText(createDialog.getComponent(), buttonText);
|
pressButtonByText(createDialog.getComponent(), buttonText);
|
||||||
assertFalse(createDialog.isShowing());
|
assertFalse(createDialog.isShowing());
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected GTreeNode selectLibraryNode(final String libraryName) throws Exception {
|
protected GTreeNode selectLibraryNode(String libraryName) throws Exception {
|
||||||
|
|
||||||
flushAndWaitForTree();
|
flushAndWaitForTree();
|
||||||
|
|
||||||
GTreeNode importsNode = rootNode.getChild("Imports");
|
GTreeNode importsNode = rootNode.getChild("Imports");
|
||||||
assertNotNull(importsNode);
|
assertNotNull(importsNode);
|
||||||
util.expandNode(importsNode);
|
util.expandNode(importsNode);
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
flushAndWaitForTree();
|
flushAndWaitForTree();
|
||||||
GTreeNode advapiNode = importsNode.getChild(libraryName);
|
GTreeNode advapiNode = importsNode.getChild(libraryName);
|
||||||
assertNotNull(advapiNode);
|
assertNotNull(advapiNode);
|
||||||
tree.expandPath(advapiNode);
|
tree.expandPath(advapiNode);
|
||||||
tree.setSelectedNode(advapiNode);
|
tree.setSelectedNode(advapiNode);
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
flushAndWaitForTree();
|
flushAndWaitForTree();
|
||||||
GTreeNode selectedNode = util.getSelectedNode();
|
GTreeNode selectedNode = util.getSelectedNode();
|
||||||
assertEquals(advapiNode, selectedNode);
|
assertEquals(advapiNode, selectedNode);
|
||||||
|
@ -254,26 +248,26 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
|
||||||
return advapiNode;
|
return advapiNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected GTreeNode selectExternalLocation(final String libraryName,
|
protected GTreeNode selectExternalLocation(String libraryName,
|
||||||
final String externalLocation) throws Exception {
|
String externalLocation) throws Exception {
|
||||||
flushAndWaitForTree();
|
flushAndWaitForTree();
|
||||||
|
|
||||||
GTreeNode importsNode = rootNode.getChild("Imports");
|
GTreeNode importsNode = rootNode.getChild("Imports");
|
||||||
assertNotNull(importsNode);
|
assertNotNull(importsNode);
|
||||||
util.expandNode(importsNode);
|
util.expandNode(importsNode);
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
flushAndWaitForTree();
|
flushAndWaitForTree();
|
||||||
|
|
||||||
GTreeNode advapiNode = importsNode.getChild(libraryName);
|
GTreeNode advapiNode = importsNode.getChild(libraryName);
|
||||||
assertNotNull(advapiNode);
|
assertNotNull(advapiNode);
|
||||||
util.expandNode(advapiNode);
|
util.expandNode(advapiNode);
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
flushAndWaitForTree();
|
flushAndWaitForTree();
|
||||||
|
|
||||||
GTreeNode locationNode = advapiNode.getChild(externalLocation);
|
GTreeNode locationNode = advapiNode.getChild(externalLocation);
|
||||||
assertNotNull(locationNode);
|
assertNotNull(locationNode);
|
||||||
tree.setSelectedNode(locationNode);
|
tree.setSelectedNode(locationNode);
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
flushAndWaitForTree();
|
flushAndWaitForTree();
|
||||||
GTreeNode selectedNode = util.getSelectedNode();
|
GTreeNode selectedNode = util.getSelectedNode();
|
||||||
assertEquals(locationNode, selectedNode);
|
assertEquals(locationNode, selectedNode);
|
||||||
|
@ -282,8 +276,8 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
|
||||||
return locationNode;
|
return locationNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void checkExternalLocationPath(final EditExternalLocationDialog createDialog,
|
protected void checkExternalLocationPath(EditExternalLocationDialog createDialog,
|
||||||
final String externalProgramPath) {
|
String externalProgramPath) {
|
||||||
SystemUtilities.runSwingNow(() -> {
|
SystemUtilities.runSwingNow(() -> {
|
||||||
EditExternalLocationPanel panel = findComponent(
|
EditExternalLocationPanel panel = findComponent(
|
||||||
createDialog.getComponent().getRootPane(), EditExternalLocationPanel.class);
|
createDialog.getComponent().getRootPane(), EditExternalLocationPanel.class);
|
||||||
|
@ -294,8 +288,8 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void checkExternalLibraryName(final EditExternalLocationDialog createDialog,
|
protected void checkExternalLibraryName(EditExternalLocationDialog createDialog,
|
||||||
final String expectedName) {
|
String expectedName) {
|
||||||
SystemUtilities.runSwingNow(() -> {
|
SystemUtilities.runSwingNow(() -> {
|
||||||
EditExternalLocationPanel panel = findComponent(
|
EditExternalLocationPanel panel = findComponent(
|
||||||
createDialog.getComponent().getRootPane(), EditExternalLocationPanel.class);
|
createDialog.getComponent().getRootPane(), EditExternalLocationPanel.class);
|
||||||
|
@ -306,8 +300,8 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void chooseExternalLibraryName(final EditExternalLocationDialog createDialog,
|
protected void chooseExternalLibraryName(EditExternalLocationDialog createDialog,
|
||||||
final String libraryName) {
|
String libraryName) {
|
||||||
SystemUtilities.runSwingNow(() -> {
|
SystemUtilities.runSwingNow(() -> {
|
||||||
EditExternalLocationPanel panel = findComponent(
|
EditExternalLocationPanel panel = findComponent(
|
||||||
createDialog.getComponent().getRootPane(), EditExternalLocationPanel.class);
|
createDialog.getComponent().getRootPane(), EditExternalLocationPanel.class);
|
||||||
|
@ -317,8 +311,8 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void typeExternalLibraryName(final EditExternalLocationDialog createDialog,
|
protected void typeExternalLibraryName(EditExternalLocationDialog createDialog,
|
||||||
final String libraryName) {
|
String libraryName) {
|
||||||
|
|
||||||
runSwing(() -> {
|
runSwing(() -> {
|
||||||
EditExternalLocationPanel panel = findComponent(
|
EditExternalLocationPanel panel = findComponent(
|
||||||
|
@ -335,8 +329,8 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void checkExternalLocationPathEndsWith(final EditExternalLocationDialog createDialog,
|
protected void checkExternalLocationPathEndsWith(EditExternalLocationDialog createDialog,
|
||||||
final String externalProgramPathEndsWith) {
|
String externalProgramPathEndsWith) {
|
||||||
EditExternalLocationPanel panel = findComponent(createDialog.getComponent().getRootPane(),
|
EditExternalLocationPanel panel = findComponent(createDialog.getComponent().getRootPane(),
|
||||||
EditExternalLocationPanel.class);
|
EditExternalLocationPanel.class);
|
||||||
Object pathTextObj = getInstanceField("extLibPathTextField", panel);
|
Object pathTextObj = getInstanceField("extLibPathTextField", panel);
|
||||||
|
@ -347,16 +341,16 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
|
||||||
text.endsWith(externalProgramPathEndsWith));
|
text.endsWith(externalProgramPathEndsWith));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void chooseProgram(final Project project, final String programName) {
|
protected void chooseProgram(Project project, String programName) {
|
||||||
|
|
||||||
final DataTreeDialog chooseDialog = AbstractDockingTest.waitForDialogComponent(
|
DataTreeDialog chooseDialog = AbstractDockingTest.waitForDialogComponent(
|
||||||
plugin.getTool().getToolFrame(), DataTreeDialog.class, 2000);
|
DataTreeDialog.class);
|
||||||
|
|
||||||
ProjectData projectData = project.getProjectData();
|
ProjectData projectData = project.getProjectData();
|
||||||
DomainFolder folder = projectData.getFolder("/");
|
DomainFolder folder = projectData.getFolder("/");
|
||||||
assertNotNull(folder);
|
assertNotNull(folder);
|
||||||
|
|
||||||
final DomainFile file = folder.getFile(programName);
|
DomainFile file = folder.getFile(programName);
|
||||||
assertNotNull(file);
|
assertNotNull(file);
|
||||||
|
|
||||||
setFileInDataTreeDialog(chooseDialog, file);
|
setFileInDataTreeDialog(chooseDialog, file);
|
||||||
|
@ -368,15 +362,15 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
|
||||||
flushAndWaitForTree();
|
flushAndWaitForTree();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void chooseProgramButCancel(final Project project, final String programName) {
|
protected void chooseProgramButCancel(Project project, String programName) {
|
||||||
|
|
||||||
final DataTreeDialog chooseDialog = AbstractDockingTest.waitForDialogComponent(
|
DataTreeDialog chooseDialog = AbstractDockingTest.waitForDialogComponent(
|
||||||
plugin.getTool().getToolFrame(), DataTreeDialog.class, 2000);
|
DataTreeDialog.class);
|
||||||
|
|
||||||
ProjectData projectData = project.getProjectData();
|
ProjectData projectData = project.getProjectData();
|
||||||
DomainFolder folder = projectData.getFolder("/");
|
DomainFolder folder = projectData.getFolder("/");
|
||||||
assertNotNull(folder);
|
assertNotNull(folder);
|
||||||
final DomainFile file = folder.getFile(programName);
|
DomainFile file = folder.getFile(programName);
|
||||||
assertNotNull(file);
|
assertNotNull(file);
|
||||||
|
|
||||||
setFileInDataTreeDialog(chooseDialog, file);
|
setFileInDataTreeDialog(chooseDialog, file);
|
||||||
|
@ -390,13 +384,9 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
|
||||||
|
|
||||||
protected void closeErrorDialog(String expectedTitle) {
|
protected void closeErrorDialog(String expectedTitle) {
|
||||||
|
|
||||||
final OptionDialog errorDialog = AbstractDockingTest.waitForDialogComponent(
|
AbstractErrDialog d = waitForErrorDialog();
|
||||||
plugin.getTool().getToolFrame(), OptionDialog.class, 2000);
|
String actualTitle = d.getTitle();
|
||||||
|
close(d);
|
||||||
String actualTitle = errorDialog.getTitle();
|
|
||||||
|
|
||||||
pressButtonByText(errorDialog.getComponent().getRootPane(), "OK", false);
|
|
||||||
|
|
||||||
assertEquals(expectedTitle, actualTitle);
|
assertEquals(expectedTitle, actualTitle);
|
||||||
|
|
||||||
waitForBusyTool(tool);
|
waitForBusyTool(tool);
|
||||||
|
@ -404,7 +394,7 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
|
||||||
flushAndWaitForTree();
|
flushAndWaitForTree();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void checkExternalLocationLabel(final EditExternalLocationDialog createDialog,
|
protected void checkExternalLocationLabel(EditExternalLocationDialog createDialog,
|
||||||
String label) {
|
String label) {
|
||||||
EditExternalLocationPanel extLocPanel = findComponent(
|
EditExternalLocationPanel extLocPanel = findComponent(
|
||||||
createDialog.getComponent().getRootPane(), EditExternalLocationPanel.class);
|
createDialog.getComponent().getRootPane(), EditExternalLocationPanel.class);
|
||||||
|
@ -414,7 +404,7 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
|
||||||
assertEquals(label, text);
|
assertEquals(label, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setExternalLocationLabel(final EditExternalLocationDialog createDialog,
|
protected void setExternalLocationLabel(EditExternalLocationDialog createDialog,
|
||||||
String label) {
|
String label) {
|
||||||
runSwing(() -> {
|
runSwing(() -> {
|
||||||
EditExternalLocationPanel extLocPanel = findComponent(
|
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) {
|
String space, String address) {
|
||||||
EditExternalLocationPanel extLocPanel = findComponent(
|
EditExternalLocationPanel extLocPanel = findComponent(
|
||||||
createDialog.getComponent().getRootPane(), EditExternalLocationPanel.class);
|
createDialog.getComponent().getRootPane(), EditExternalLocationPanel.class);
|
||||||
|
@ -443,7 +433,7 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
|
||||||
assertEquals(address, currentAddress);
|
assertEquals(address, currentAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setExternalLocationAddressInput(final EditExternalLocationDialog createDialog,
|
protected void setExternalLocationAddressInput(EditExternalLocationDialog createDialog,
|
||||||
AddressSpace addressSpace, String address) {
|
AddressSpace addressSpace, String address) {
|
||||||
runSwing(() -> {
|
runSwing(() -> {
|
||||||
EditExternalLocationPanel extLocPanel = findComponent(
|
EditExternalLocationPanel extLocPanel = findComponent(
|
||||||
|
@ -468,13 +458,13 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
|
||||||
Address address = program.getAddressFactory().getAddress(startAddress);
|
Address address = program.getAddressFactory().getAddress(startAddress);
|
||||||
Memory memory = program.getMemory();
|
Memory memory = program.getMemory();
|
||||||
memory.createInitializedBlock(name, address, length, (byte) 0,
|
memory.createInitializedBlock(name, address, length, (byte) 0,
|
||||||
TaskMonitorAdapter.DUMMY_MONITOR, true);
|
TaskMonitor.DUMMY, true);
|
||||||
program.endTransaction(transactionID, true);
|
program.endTransaction(transactionID, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void closeProgram() throws Exception {
|
protected void closeProgram() throws Exception {
|
||||||
final ProgramManager pm = tool.getService(ProgramManager.class);
|
ProgramManager pm = tool.getService(ProgramManager.class);
|
||||||
SwingUtilities.invokeAndWait(() -> pm.closeProgram());
|
runSwing(() -> pm.closeProgram());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void showSymbolTree() throws Exception {
|
protected void showSymbolTree() throws Exception {
|
||||||
|
@ -514,26 +504,26 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
|
||||||
assertNotNull(goToExtLocAction);
|
assertNotNull(goToExtLocAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void pressDataTreeDialogOK(final DataTreeDialog dialog) {
|
protected void pressDataTreeDialogOK(DataTreeDialog dialog) {
|
||||||
pressButtonByText(dialog.getComponent(), "OK");
|
pressButtonByText(dialog.getComponent(), "OK");
|
||||||
assertFalse(dialog.isShowing());
|
assertFalse(dialog.isShowing());
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void pressDataTreeDialogCancel(final DataTreeDialog dialog) {
|
protected void pressDataTreeDialogCancel(DataTreeDialog dialog) {
|
||||||
pressButtonByText(dialog.getComponent(), "Cancel");
|
pressButtonByText(dialog.getComponent(), "Cancel");
|
||||||
assertFalse(dialog.isShowing());
|
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);
|
runSwing(() -> dialog.selectDomainFile(file), true);
|
||||||
|
|
||||||
waitForDialogTree(dialog);
|
waitForDialogTree(dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void waitForDialogTree(DataTreeDialog dialog) {
|
protected void waitForDialogTree(DataTreeDialog dialog) {
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
ProjectDataTreePanel treePanel =
|
ProjectDataTreePanel treePanel =
|
||||||
(ProjectDataTreePanel) getInstanceField("treePanel", dialog);
|
(ProjectDataTreePanel) getInstanceField("treePanel", dialog);
|
||||||
DataTree dataTree = treePanel.getDataTree();
|
DataTree dataTree = treePanel.getDataTree();
|
||||||
|
@ -542,7 +532,7 @@ public abstract class AbstractSymbolTreePluginExternalsTest extends AbstractGhid
|
||||||
|
|
||||||
protected void flushAndWaitForTree() {
|
protected void flushAndWaitForTree() {
|
||||||
program.flushEvents();
|
program.flushEvents();
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
util.waitForTree();
|
util.waitForTree();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.util.viewer.field;
|
package ghidra.app.util.viewer.field;
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
@ -32,6 +32,7 @@ import ghidra.app.nav.Navigatable;
|
||||||
import ghidra.app.nav.TestDummyNavigatable;
|
import ghidra.app.nav.TestDummyNavigatable;
|
||||||
import ghidra.app.services.*;
|
import ghidra.app.services.*;
|
||||||
import ghidra.framework.model.*;
|
import ghidra.framework.model.*;
|
||||||
|
import ghidra.framework.plugintool.ServiceProvider;
|
||||||
import ghidra.framework.plugintool.TestDummyServiceProvider;
|
import ghidra.framework.plugintool.TestDummyServiceProvider;
|
||||||
import ghidra.framework.project.ProjectDataService;
|
import ghidra.framework.project.ProjectDataService;
|
||||||
import ghidra.program.database.ProgramBuilder;
|
import ghidra.program.database.ProgramBuilder;
|
||||||
|
@ -247,7 +248,7 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
SpyNavigatable spyNavigatable = new SpyNavigatable();
|
SpyNavigatable spyNavigatable = new SpyNavigatable();
|
||||||
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
|
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
|
||||||
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
|
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
|
||||||
annotatedElement.handleMouseClicked(spyNavigatable, spyServiceProvider);
|
click(spyNavigatable, spyServiceProvider, annotatedElement);
|
||||||
|
|
||||||
assertTrue(spyServiceProvider.programOpened(programName));
|
assertTrue(spyServiceProvider.programOpened(programName));
|
||||||
assertTrue(spyNavigatable.navigatedTo(programName));
|
assertTrue(spyNavigatable.navigatedTo(programName));
|
||||||
|
@ -257,7 +258,7 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
public void testProgramAnnotation_ProgramNameAndAddress() {
|
public void testProgramAnnotation_ProgramNameAndAddress() {
|
||||||
|
|
||||||
String programName = OTHER_PROGRAM_NAME;
|
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 annotationText = "{@program " + programName + "@" + address + "}";
|
||||||
String rawComment = "My comment - " + annotationText;
|
String rawComment = "My comment - " + annotationText;
|
||||||
AttributedString prototype = prototype();
|
AttributedString prototype = prototype();
|
||||||
|
@ -274,7 +275,7 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
SpyNavigatable spyNavigatable = new SpyNavigatable();
|
SpyNavigatable spyNavigatable = new SpyNavigatable();
|
||||||
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
|
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
|
||||||
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
|
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
|
||||||
annotatedElement.handleMouseClicked(spyNavigatable, spyServiceProvider);
|
click(spyNavigatable, spyServiceProvider, annotatedElement);
|
||||||
|
|
||||||
assertTrue(spyServiceProvider.programOpened(programName));
|
assertTrue(spyServiceProvider.programOpened(programName));
|
||||||
assertTrue(spyNavigatable.navigatedTo(programName, address));
|
assertTrue(spyNavigatable.navigatedTo(programName, address));
|
||||||
|
@ -284,7 +285,7 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
public void testProgramAnnotation_ProgramNameAndAddress_InvalidAddress() {
|
public void testProgramAnnotation_ProgramNameAndAddress_InvalidAddress() {
|
||||||
|
|
||||||
String programName = OTHER_PROGRAM_NAME;
|
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 annotationText = "{@program " + programName + "@" + address + "}";
|
||||||
String rawComment = "My comment - " + annotationText;
|
String rawComment = "My comment - " + annotationText;
|
||||||
AttributedString prototype = prototype();
|
AttributedString prototype = prototype();
|
||||||
|
@ -301,14 +302,13 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
SpyNavigatable spyNavigatable = new SpyNavigatable();
|
SpyNavigatable spyNavigatable = new SpyNavigatable();
|
||||||
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
|
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
|
||||||
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
|
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
|
||||||
annotatedElement.handleMouseClicked(spyNavigatable, spyServiceProvider);
|
click(spyNavigatable, spyServiceProvider, annotatedElement);
|
||||||
|
|
||||||
|
assertErrorDialog("No Symbol");
|
||||||
|
|
||||||
assertTrue(spyServiceProvider.programOpened(programName));
|
assertTrue(spyServiceProvider.programOpened(programName));
|
||||||
assertTrue(spyServiceProvider.programClosed(programName));
|
assertTrue(spyServiceProvider.programClosed(programName));
|
||||||
assertFalse(spyNavigatable.navigatedTo(programName, address));
|
assertFalse(spyNavigatable.navigatedTo(programName, address));
|
||||||
|
|
||||||
Window window = waitForWindowByTitleContaining("No Symbol");
|
|
||||||
window.setVisible(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -332,7 +332,7 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
SpyNavigatable spyNavigatable = new SpyNavigatable();
|
SpyNavigatable spyNavigatable = new SpyNavigatable();
|
||||||
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
|
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
|
||||||
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
|
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
|
||||||
annotatedElement.handleMouseClicked(spyNavigatable, spyServiceProvider);
|
click(spyNavigatable, spyServiceProvider, annotatedElement);
|
||||||
|
|
||||||
assertTrue(spyServiceProvider.programOpened(programName));
|
assertTrue(spyServiceProvider.programOpened(programName));
|
||||||
assertTrue(spyNavigatable.navigatedTo(programName, symbol));
|
assertTrue(spyNavigatable.navigatedTo(programName, symbol));
|
||||||
|
@ -359,14 +359,13 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
SpyNavigatable spyNavigatable = new SpyNavigatable();
|
SpyNavigatable spyNavigatable = new SpyNavigatable();
|
||||||
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
|
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
|
||||||
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
|
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
|
||||||
annotatedElement.handleMouseClicked(spyNavigatable, spyServiceProvider);
|
click(spyNavigatable, spyServiceProvider, annotatedElement);
|
||||||
|
|
||||||
|
assertErrorDialog("No Symbol");
|
||||||
|
|
||||||
assertTrue(spyServiceProvider.programOpened(programName));
|
assertTrue(spyServiceProvider.programOpened(programName));
|
||||||
assertTrue(spyServiceProvider.programClosed(programName));
|
assertTrue(spyServiceProvider.programClosed(programName));
|
||||||
assertFalse(spyNavigatable.navigatedTo(programName, symbol));
|
assertFalse(spyNavigatable.navigatedTo(programName, symbol));
|
||||||
|
|
||||||
Window window = waitForWindowByTitleContaining("No Symbol");
|
|
||||||
window.setVisible(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -390,7 +389,7 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
SpyNavigatable spyNavigatable = new SpyNavigatable();
|
SpyNavigatable spyNavigatable = new SpyNavigatable();
|
||||||
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
|
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
|
||||||
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
|
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
|
||||||
annotatedElement.handleMouseClicked(spyNavigatable, spyServiceProvider);
|
click(spyNavigatable, spyServiceProvider, annotatedElement);
|
||||||
|
|
||||||
assertTrue(spyServiceProvider.programOpened(programName));
|
assertTrue(spyServiceProvider.programOpened(programName));
|
||||||
assertTrue(spyNavigatable.navigatedTo(programName, symbol));
|
assertTrue(spyNavigatable.navigatedTo(programName, symbol));
|
||||||
|
@ -416,12 +415,11 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
SpyNavigatable spyNavigatable = new SpyNavigatable();
|
SpyNavigatable spyNavigatable = new SpyNavigatable();
|
||||||
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
|
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
|
||||||
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
|
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
|
||||||
annotatedElement.handleMouseClicked(spyNavigatable, spyServiceProvider);
|
click(spyNavigatable, spyServiceProvider, annotatedElement);
|
||||||
|
|
||||||
|
assertErrorDialog("No Program");
|
||||||
|
|
||||||
assertFalse(spyServiceProvider.programOpened(programName));
|
assertFalse(spyServiceProvider.programOpened(programName));
|
||||||
|
|
||||||
Window window = waitForWindowByTitleContaining("No Program");
|
|
||||||
window.setVisible(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -430,8 +428,7 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
SpyNavigatable spyNavigatable = new SpyNavigatable();
|
SpyNavigatable spyNavigatable = new SpyNavigatable();
|
||||||
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
|
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
|
||||||
|
|
||||||
String addressString = "1001000";
|
String addresstring = "1001000";
|
||||||
Address address = program.getAddressFactory().getAddress(addressString);
|
|
||||||
|
|
||||||
// path in comment
|
// path in comment
|
||||||
String otherProgramPath = "folder1/folder2/program_f1_f2.exe";
|
String otherProgramPath = "folder1/folder2/program_f1_f2.exe";
|
||||||
|
@ -440,25 +437,24 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
String realPath = "folder1/program_f1_f2.exe";
|
String realPath = "folder1/program_f1_f2.exe";
|
||||||
addFakeProgramByPath(spyServiceProvider, realPath);
|
addFakeProgramByPath(spyServiceProvider, realPath);
|
||||||
|
|
||||||
String annotationText = "{@program " + otherProgramPath + "@" + addressString + "}";
|
String annotationText = "{@program " + otherProgramPath + "@" + addresstring + "}";
|
||||||
String rawComment = "My comment - " + annotationText;
|
String rawComment = "My comment - " + annotationText;
|
||||||
AttributedString prototype = prototype();
|
AttributedString prototype = prototype();
|
||||||
FieldElement element =
|
FieldElement element =
|
||||||
CommentUtils.parseTextForAnnotations(rawComment, program, prototype, 0);
|
CommentUtils.parseTextForAnnotations(rawComment, program, prototype, 0);
|
||||||
|
|
||||||
String displayString = element.getText();
|
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
|
// When clicking an element with bad path program should not open
|
||||||
//
|
//
|
||||||
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
|
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
|
||||||
annotatedElement.handleMouseClicked(spyNavigatable, spyServiceProvider);
|
click(spyNavigatable, spyServiceProvider, annotatedElement);
|
||||||
|
|
||||||
|
assertErrorDialog("No Folder");
|
||||||
|
|
||||||
assertFalse(spyServiceProvider.programOpened(otherProgramPath));
|
assertFalse(spyServiceProvider.programOpened(otherProgramPath));
|
||||||
Window window = waitForWindowByTitleContaining("No Folder");
|
|
||||||
window.setVisible(false);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -484,7 +480,7 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
// should be opened
|
// should be opened
|
||||||
//
|
//
|
||||||
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
|
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
|
||||||
annotatedElement.handleMouseClicked(spyNavigatable, spyServiceProvider);
|
click(spyNavigatable, spyServiceProvider, annotatedElement);
|
||||||
|
|
||||||
assertTrue(spyServiceProvider.programOpened(otherProgramPath));
|
assertTrue(spyServiceProvider.programOpened(otherProgramPath));
|
||||||
assertTrue(spyNavigatable.navigatedTo(otherProgramPath));
|
assertTrue(spyNavigatable.navigatedTo(otherProgramPath));
|
||||||
|
@ -496,27 +492,27 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
SpyNavigatable spyNavigatable = new SpyNavigatable();
|
SpyNavigatable spyNavigatable = new SpyNavigatable();
|
||||||
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
|
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
|
||||||
|
|
||||||
String addressString = "1001000";
|
String addresstring = "1001000";
|
||||||
Address address = program.getAddressFactory().getAddress(addressString);
|
Address address = program.getAddressFactory().getAddress(addresstring);
|
||||||
|
|
||||||
String otherProgramPath = "/folder1/folder2/program_f1_f2.exe";
|
String otherProgramPath = "/folder1/folder2/program_f1_f2.exe";
|
||||||
addFakeProgramByPath(spyServiceProvider, otherProgramPath);
|
addFakeProgramByPath(spyServiceProvider, otherProgramPath);
|
||||||
|
|
||||||
String annotationText = "{@program " + otherProgramPath + "@" + addressString + "}";
|
String annotationText = "{@program " + otherProgramPath + "@" + addresstring + "}";
|
||||||
String rawComment = "My comment - " + annotationText;
|
String rawComment = "My comment - " + annotationText;
|
||||||
AttributedString prototype = prototype();
|
AttributedString prototype = prototype();
|
||||||
FieldElement element =
|
FieldElement element =
|
||||||
CommentUtils.parseTextForAnnotations(rawComment, program, prototype, 0);
|
CommentUtils.parseTextForAnnotations(rawComment, program, prototype, 0);
|
||||||
|
|
||||||
String displayString = element.getText();
|
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
|
// When clicking an element with only a program name, the result is that the program
|
||||||
// should be opened
|
// should be opened
|
||||||
//
|
//
|
||||||
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
|
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
|
||||||
annotatedElement.handleMouseClicked(spyNavigatable, spyServiceProvider);
|
click(spyNavigatable, spyServiceProvider, annotatedElement);
|
||||||
|
|
||||||
assertTrue(spyServiceProvider.programOpened(otherProgramPath));
|
assertTrue(spyServiceProvider.programOpened(otherProgramPath));
|
||||||
assertTrue(spyNavigatable.navigatedTo(otherProgramPath, address));
|
assertTrue(spyNavigatable.navigatedTo(otherProgramPath, address));
|
||||||
|
@ -529,28 +525,28 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
SpyNavigatable spyNavigatable = new SpyNavigatable();
|
SpyNavigatable spyNavigatable = new SpyNavigatable();
|
||||||
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
|
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
|
||||||
|
|
||||||
String addressString = "1001000";
|
String addresstring = "1001000";
|
||||||
Address address = program.getAddressFactory().getAddress(addressString);
|
Address address = program.getAddressFactory().getAddress(addresstring);
|
||||||
|
|
||||||
String otherProgramPath = "/folder1/folder2/program_f1_f2.exe";
|
String otherProgramPath = "/folder1/folder2/program_f1_f2.exe";
|
||||||
String annotationPath = "\\folder1\\folder2\\program_f1_f2.exe";
|
String annotationPath = "\\folder1\\folder2\\program_f1_f2.exe";
|
||||||
addFakeProgramByPath(spyServiceProvider, otherProgramPath);
|
addFakeProgramByPath(spyServiceProvider, otherProgramPath);
|
||||||
|
|
||||||
String annotationText = "{@program " + annotationPath + "@" + addressString + "}";
|
String annotationText = "{@program " + annotationPath + "@" + addresstring + "}";
|
||||||
String rawComment = "My comment - " + annotationText;
|
String rawComment = "My comment - " + annotationText;
|
||||||
AttributedString prototype = prototype();
|
AttributedString prototype = prototype();
|
||||||
FieldElement element =
|
FieldElement element =
|
||||||
CommentUtils.parseTextForAnnotations(rawComment, program, prototype, 0);
|
CommentUtils.parseTextForAnnotations(rawComment, program, prototype, 0);
|
||||||
|
|
||||||
String displayString = element.getText();
|
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
|
// When clicking an element with only a program name, the result is that the program
|
||||||
// should be opened
|
// should be opened
|
||||||
//
|
//
|
||||||
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
|
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
|
||||||
annotatedElement.handleMouseClicked(spyNavigatable, spyServiceProvider);
|
click(spyNavigatable, spyServiceProvider, annotatedElement);
|
||||||
|
|
||||||
assertTrue(spyServiceProvider.programOpened(otherProgramPath));
|
assertTrue(spyServiceProvider.programOpened(otherProgramPath));
|
||||||
assertTrue(spyNavigatable.navigatedTo(otherProgramPath, address));
|
assertTrue(spyNavigatable.navigatedTo(otherProgramPath, address));
|
||||||
|
@ -562,28 +558,28 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
SpyNavigatable spyNavigatable = new SpyNavigatable();
|
SpyNavigatable spyNavigatable = new SpyNavigatable();
|
||||||
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
|
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
|
||||||
|
|
||||||
String addressString = "1001000";
|
String addresstring = "1001000";
|
||||||
Address address = program.getAddressFactory().getAddress(addressString);
|
Address address = program.getAddressFactory().getAddress(addresstring);
|
||||||
|
|
||||||
String otherProgramPath = "folder1/folder2/program_f1_f2.exe";
|
String otherProgramPath = "folder1/folder2/program_f1_f2.exe";
|
||||||
String annotationPath = "folder1\\folder2\\program_f1_f2.exe";
|
String annotationPath = "folder1\\folder2\\program_f1_f2.exe";
|
||||||
addFakeProgramByPath(spyServiceProvider, otherProgramPath);
|
addFakeProgramByPath(spyServiceProvider, otherProgramPath);
|
||||||
|
|
||||||
String annotationText = "{@program " + annotationPath + "@" + addressString + "}";
|
String annotationText = "{@program " + annotationPath + "@" + addresstring + "}";
|
||||||
String rawComment = "My comment - " + annotationText;
|
String rawComment = "My comment - " + annotationText;
|
||||||
AttributedString prototype = prototype();
|
AttributedString prototype = prototype();
|
||||||
FieldElement element =
|
FieldElement element =
|
||||||
CommentUtils.parseTextForAnnotations(rawComment, program, prototype, 0);
|
CommentUtils.parseTextForAnnotations(rawComment, program, prototype, 0);
|
||||||
|
|
||||||
String displayString = element.getText();
|
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
|
// When clicking an element with only a program name, the result is that the program
|
||||||
// should be opened
|
// should be opened
|
||||||
//
|
//
|
||||||
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
|
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
|
||||||
annotatedElement.handleMouseClicked(spyNavigatable, spyServiceProvider);
|
click(spyNavigatable, spyServiceProvider, annotatedElement);
|
||||||
|
|
||||||
assertTrue(spyServiceProvider.programOpened(otherProgramPath));
|
assertTrue(spyServiceProvider.programOpened(otherProgramPath));
|
||||||
assertTrue(spyNavigatable.navigatedTo(otherProgramPath, address));
|
assertTrue(spyNavigatable.navigatedTo(otherProgramPath, address));
|
||||||
|
@ -596,31 +592,30 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
SpyNavigatable spyNavigatable = new SpyNavigatable();
|
SpyNavigatable spyNavigatable = new SpyNavigatable();
|
||||||
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
|
SpyServiceProvider spyServiceProvider = new SpyServiceProvider();
|
||||||
|
|
||||||
String addressString = "1001000";
|
String addresstring = "1001000";
|
||||||
Address address = program.getAddressFactory().getAddress(addressString);
|
Address address = program.getAddressFactory().getAddress(addresstring);
|
||||||
|
|
||||||
String otherProgramPath = "folder1/folder2/program_f1_f2.exe";
|
String otherProgramPath = "folder1/folder2/program_f1_f2.exe";
|
||||||
addFakeProgramByPath(spyServiceProvider, otherProgramPath);
|
addFakeProgramByPath(spyServiceProvider, otherProgramPath);
|
||||||
|
|
||||||
String annotationText = "{@program " + otherProgramPath + "@" + addressString + "}";
|
String annotationText = "{@program " + otherProgramPath + "@" + addresstring + "}";
|
||||||
String rawComment = "My comment - " + annotationText;
|
String rawComment = "My comment - " + annotationText;
|
||||||
AttributedString prototype = prototype();
|
AttributedString prototype = prototype();
|
||||||
FieldElement element =
|
FieldElement element =
|
||||||
CommentUtils.parseTextForAnnotations(rawComment, program, prototype, 0);
|
CommentUtils.parseTextForAnnotations(rawComment, program, prototype, 0);
|
||||||
|
|
||||||
String displayString = element.getText();
|
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
|
// When clicking an element with only a program name, the result is that the program
|
||||||
// should be opened
|
// should be opened
|
||||||
//
|
//
|
||||||
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
|
AnnotatedTextFieldElement annotatedElement = getAnnotatedTextFieldElement(element);
|
||||||
annotatedElement.handleMouseClicked(spyNavigatable, spyServiceProvider);
|
click(spyNavigatable, spyServiceProvider, annotatedElement);
|
||||||
|
|
||||||
assertTrue(spyServiceProvider.programOpened(otherProgramPath));
|
assertTrue(spyServiceProvider.programOpened(otherProgramPath));
|
||||||
assertTrue(spyNavigatable.navigatedTo(otherProgramPath, address));
|
assertTrue(spyNavigatable.navigatedTo(otherProgramPath, address));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -728,6 +723,14 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
// Private Methods
|
// 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) {
|
private AnnotatedTextFieldElement getAnnotatedTextFieldElement(FieldElement element) {
|
||||||
|
|
||||||
assertThat(element, instanceOf(CompositeFieldElement.class));
|
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
|
// Fake/Spy Classes
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
|
@ -858,24 +867,20 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
private List<TestDummyDomainFolder> folders = CollectionUtils.asList(this);
|
private List<TestDummyDomainFolder> folders = CollectionUtils.asList(this);
|
||||||
|
|
||||||
private List<TestDummyDomainFile> files =
|
private List<TestDummyDomainFile> folderFiles =
|
||||||
CollectionUtils.asList(new TestDummyDomainFile(this, OTHER_PROGRAM_NAME));
|
CollectionUtils.asList(new TestDummyDomainFile(this, OTHER_PROGRAM_NAME));
|
||||||
|
|
||||||
public FakeRootFolder() {
|
public FakeRootFolder() {
|
||||||
super(null, "Fake Root Folder");
|
super(null, "Fake Root Folder");
|
||||||
}
|
}
|
||||||
|
|
||||||
void addFile(TestDummyDomainFile f) {
|
|
||||||
files.add(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void addFolder(TestDummyDomainFolder f) {
|
void addFolder(TestDummyDomainFolder f) {
|
||||||
folders.add(f);
|
folders.add(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized DomainFile[] getFiles() {
|
public synchronized DomainFile[] getFiles() {
|
||||||
return files.toArray(new TestDummyDomainFile[files.size()]);
|
return folderFiles.toArray(new TestDummyDomainFile[folderFiles.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -28,7 +28,7 @@ import javax.swing.tree.TreePath;
|
||||||
|
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
|
|
||||||
import docking.ActionContext;
|
import docking.*;
|
||||||
import docking.action.DockingActionIf;
|
import docking.action.DockingActionIf;
|
||||||
import docking.action.ToggleDockingAction;
|
import docking.action.ToggleDockingAction;
|
||||||
import docking.test.AbstractDockingTest;
|
import docking.test.AbstractDockingTest;
|
||||||
|
@ -92,11 +92,11 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNewFolder() throws Exception {
|
public void testNewFolder() throws Exception {
|
||||||
final DockingActionIf newFolderAction = getAction("New Folder");
|
DockingActionIf newFolderAction = getAction("New Folder");
|
||||||
setSelectionPaths(new TreePath[] { rootNode.getTreePath() });
|
setSelectionPaths(new TreePath[] { rootNode.getTreePath() });
|
||||||
int count = rootNode.getChildCount();
|
int count = rootNode.getChildCount();
|
||||||
performAction(newFolderAction, getDomainFileActionContext(), true);
|
performAction(newFolderAction, getDomainFileActionContext(), true);
|
||||||
SwingUtilities.invokeAndWait(() -> tree.stopEditing());
|
runSwing(() -> tree.stopEditing());
|
||||||
assertEquals(count + 1, rootNode.getChildCount());
|
assertEquals(count + 1, rootNode.getChildCount());
|
||||||
assertNotNull(getChild(rootNode, "NewFolder"));
|
assertNotNull(getChild(rootNode, "NewFolder"));
|
||||||
}
|
}
|
||||||
|
@ -104,11 +104,11 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
|
||||||
@Test
|
@Test
|
||||||
public void testNewFolderBlankName() throws Exception {
|
public void testNewFolderBlankName() throws Exception {
|
||||||
// try entering a blank name
|
// try entering a blank name
|
||||||
final DockingActionIf newFolderAction = getAction("New Folder");
|
DockingActionIf newFolderAction = getAction("New Folder");
|
||||||
setSelectionPaths(new TreePath[] { rootNode.getTreePath() });
|
setSelectionPaths(new TreePath[] { rootNode.getTreePath() });
|
||||||
performAction(newFolderAction, getDomainFileActionContext(), true);
|
performAction(newFolderAction, getDomainFileActionContext(), true);
|
||||||
waitForTree();
|
waitForTree();
|
||||||
SwingUtilities.invokeLater(() -> {
|
runSwingLater(() -> {
|
||||||
GTreeNode node = rootNode.getChild("NewFolder");
|
GTreeNode node = rootNode.getChild("NewFolder");
|
||||||
int row = tree.getRowForPath(node.getTreePath());
|
int row = tree.getRowForPath(node.getTreePath());
|
||||||
DefaultTreeCellEditor cellEditor = (DefaultTreeCellEditor) tree.getCellEditor();
|
DefaultTreeCellEditor cellEditor = (DefaultTreeCellEditor) tree.getCellEditor();
|
||||||
|
@ -123,10 +123,9 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
|
||||||
});
|
});
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
|
|
||||||
OptionDialog d = waitForDialogComponent(OptionDialog.class);
|
AbstractErrDialog d = waitForErrorDialog();
|
||||||
assertNotNull(d);
|
|
||||||
assertEquals("Rename Failed", d.getTitle());
|
assertEquals("Rename Failed", d.getTitle());
|
||||||
pressButtonByText(d.getComponent(), "OK");
|
close(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -137,7 +136,7 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
|
||||||
setSelectionPaths(new TreePath[] { rootNode.getTreePath() });
|
setSelectionPaths(new TreePath[] { rootNode.getTreePath() });
|
||||||
performAction(newFolderAction, getDomainFileActionContext(), true);
|
performAction(newFolderAction, getDomainFileActionContext(), true);
|
||||||
waitForTree();
|
waitForTree();
|
||||||
SwingUtilities.invokeAndWait(() -> tree.stopEditing());
|
runSwing(() -> tree.stopEditing());
|
||||||
waitForTree();
|
waitForTree();
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
assertNotNull(getChild(rootNode, "NewFolder" + (i + 1)));
|
assertNotNull(getChild(rootNode, "NewFolder" + (i + 1)));
|
||||||
|
@ -371,9 +370,9 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
|
||||||
|
|
||||||
rootFolder.createFolder("otherFolder");
|
rootFolder.createFolder("otherFolder");
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
final GTreeNode otherNode = getChild(rootNode, "otherFolder");
|
GTreeNode otherNode = getChild(rootNode, "otherFolder");
|
||||||
// drag myFolder to otherFolder
|
// drag myFolder to otherFolder
|
||||||
final GTreeNode myNode = getChild(rootNode, "myFolder");
|
GTreeNode myNode = getChild(rootNode, "myFolder");
|
||||||
|
|
||||||
doDrag(otherNode, DnDConstants.ACTION_MOVE, myNode);
|
doDrag(otherNode, DnDConstants.ACTION_MOVE, myNode);
|
||||||
|
|
||||||
|
@ -460,10 +459,9 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
|
||||||
doDrag(myNode, DnDConstants.ACTION_MOVE, npNode);
|
doDrag(myNode, DnDConstants.ACTION_MOVE, npNode);
|
||||||
waitForTree();
|
waitForTree();
|
||||||
|
|
||||||
OptionDialog d = waitForDialogComponent(OptionDialog.class);
|
AbstractErrDialog d = waitForErrorDialog();
|
||||||
assertNotNull(d);
|
|
||||||
assertEquals("Cannot Move File", d.getTitle());
|
assertEquals("Cannot Move File", d.getTitle());
|
||||||
pressButtonByText(d.getComponent(), "OK");
|
close(d);
|
||||||
|
|
||||||
expandTreePath(myNode.getTreePath());
|
expandTreePath(myNode.getTreePath());
|
||||||
assertEquals(0, myNode.getChildCount());
|
assertEquals(0, myNode.getChildCount());
|
||||||
|
@ -535,7 +533,7 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
|
||||||
rootFolder.createFolder("myFolder");
|
rootFolder.createFolder("myFolder");
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
|
|
||||||
final GTreeNode myNode = rootNode.getChild("myFolder");
|
GTreeNode myNode = rootNode.getChild("myFolder");
|
||||||
setSelectionPath(myNode.getTreePath());
|
setSelectionPath(myNode.getTreePath());
|
||||||
|
|
||||||
DockingActionIf renameAction = getAction("Rename");
|
DockingActionIf renameAction = getAction("Rename");
|
||||||
|
@ -543,7 +541,7 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
|
||||||
waitForTree();
|
waitForTree();
|
||||||
|
|
||||||
// select "Rename" action
|
// select "Rename" action
|
||||||
SwingUtilities.invokeAndWait(() -> {
|
runSwing(() -> {
|
||||||
int row = tree.getRowForPath(myNode.getTreePath());
|
int row = tree.getRowForPath(myNode.getTreePath());
|
||||||
JTree jTree = (JTree) getInstanceField("tree", tree);
|
JTree jTree = (JTree) getInstanceField("tree", tree);
|
||||||
DefaultTreeCellEditor cellEditor = (DefaultTreeCellEditor) tree.getCellEditor();
|
DefaultTreeCellEditor cellEditor = (DefaultTreeCellEditor) tree.getCellEditor();
|
||||||
|
@ -561,7 +559,7 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRenameFile() throws Exception {
|
public void testRenameFile() throws Exception {
|
||||||
final GTreeNode npNode = rootNode.getChild("notepad");
|
GTreeNode npNode = rootNode.getChild("notepad");
|
||||||
setSelectionPath(npNode.getTreePath());
|
setSelectionPath(npNode.getTreePath());
|
||||||
|
|
||||||
DockingActionIf renameAction = getAction("Rename");
|
DockingActionIf renameAction = getAction("Rename");
|
||||||
|
@ -569,7 +567,7 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
|
||||||
waitForTree();
|
waitForTree();
|
||||||
|
|
||||||
// select "Rename" action
|
// select "Rename" action
|
||||||
SwingUtilities.invokeAndWait(() -> {
|
runSwing(() -> {
|
||||||
int row = tree.getRowForPath(npNode.getTreePath());
|
int row = tree.getRowForPath(npNode.getTreePath());
|
||||||
DefaultTreeCellEditor cellEditor = (DefaultTreeCellEditor) tree.getCellEditor();
|
DefaultTreeCellEditor cellEditor = (DefaultTreeCellEditor) tree.getCellEditor();
|
||||||
JTree jTree = (JTree) getInstanceField("tree", tree);
|
JTree jTree = (JTree) getInstanceField("tree", tree);
|
||||||
|
@ -588,7 +586,7 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRenameFileInUse() throws Exception {
|
public void testRenameFileInUse() throws Exception {
|
||||||
final GTreeNode npNode = rootNode.getChild("notepad");
|
GTreeNode npNode = rootNode.getChild("notepad");
|
||||||
DomainFile df = ((DomainFileNode) npNode).getDomainFile();
|
DomainFile df = ((DomainFileNode) npNode).getDomainFile();
|
||||||
|
|
||||||
setInUse(df);
|
setInUse(df);
|
||||||
|
@ -599,9 +597,9 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
|
||||||
executeOnSwingWithoutBlocking(
|
executeOnSwingWithoutBlocking(
|
||||||
() -> performAction(renameAction, getDomainFileActionContext(), true));
|
() -> performAction(renameAction, getDomainFileActionContext(), true));
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
OptionDialog dlg = waitForDialogComponent(OptionDialog.class);
|
|
||||||
assertEquals("Rename Not Allowed", dlg.getTitle());
|
DialogComponentProvider d = waitForDialogComponent("Rename Not Allowed");
|
||||||
pressButtonByText(dlg.getComponent(), "OK");
|
pressButtonByText(d.getComponent(), "OK");
|
||||||
assertNotNull(rootNode.getChild("notepad"));
|
assertNotNull(rootNode.getChild("notepad"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -618,7 +616,7 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
|
||||||
DomainFile df = f.createFile("notepad", p, TaskMonitor.DUMMY);
|
DomainFile df = f.createFile("notepad", p, TaskMonitor.DUMMY);
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
|
|
||||||
final GTreeNode myNode = rootNode.getChild("myFolder");
|
GTreeNode myNode = rootNode.getChild("myFolder");
|
||||||
((DomainFolderNode) myNode).getDomainFolder().createFile("notepad", p, TaskMonitor.DUMMY);
|
((DomainFolderNode) myNode).getDomainFolder().createFile("notepad", p, TaskMonitor.DUMMY);
|
||||||
p.release(this);
|
p.release(this);
|
||||||
|
|
||||||
|
@ -630,12 +628,12 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
|
||||||
|
|
||||||
setSelectionPath(myNode.getTreePath());
|
setSelectionPath(myNode.getTreePath());
|
||||||
|
|
||||||
final DockingActionIf renameAction = getAction("Rename");
|
DockingActionIf renameAction = getAction("Rename");
|
||||||
performAction(renameAction, getDomainFileActionContext(), true);
|
performAction(renameAction, getDomainFileActionContext(), true);
|
||||||
waitForTree();
|
waitForTree();
|
||||||
|
|
||||||
// attempt to rename "myFolder"
|
// attempt to rename "myFolder"
|
||||||
SwingUtilities.invokeLater(() -> {
|
runSwingLater(() -> {
|
||||||
int row = tree.getRowForPath(myNode.getTreePath());
|
int row = tree.getRowForPath(myNode.getTreePath());
|
||||||
DefaultTreeCellEditor cellEditor = (DefaultTreeCellEditor) tree.getCellEditor();
|
DefaultTreeCellEditor cellEditor = (DefaultTreeCellEditor) tree.getCellEditor();
|
||||||
JTree jTree = (JTree) getInstanceField("tree", tree);
|
JTree jTree = (JTree) getInstanceField("tree", tree);
|
||||||
|
@ -649,10 +647,9 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
|
||||||
|
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
|
|
||||||
OptionDialog d = waitForDialogComponent(OptionDialog.class);
|
AbstractErrDialog d = waitForErrorDialog();
|
||||||
assertNotNull(d);
|
|
||||||
assertEquals("Rename Failed", d.getTitle());
|
assertEquals("Rename Failed", d.getTitle());
|
||||||
pressButtonByText(d.getComponent(), "OK");
|
close(d);
|
||||||
assertNotNull(rootNode.getChild("myFolder"));
|
assertNotNull(rootNode.getChild("myFolder"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -756,7 +753,7 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
|
||||||
// Private Methods
|
// Private Methods
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
|
|
||||||
private void setSelectionPath(final TreePath path) throws Exception {
|
private void setSelectionPath(TreePath path) throws Exception {
|
||||||
tree.setSelectionPath(path);
|
tree.setSelectionPath(path);
|
||||||
waitForTree();
|
waitForTree();
|
||||||
}
|
}
|
||||||
|
@ -802,7 +799,7 @@ public class FrontEndPluginActionsTest extends AbstractGhidraHeadedIntegrationTe
|
||||||
setInUse(df, "/notepad");
|
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);
|
ProgramDB program = createDefaultProgram("test1", ProgramBuilder._TOY, this);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -41,10 +41,6 @@ public class CloseToolTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
private TestEnv env;
|
private TestEnv env;
|
||||||
|
|
||||||
public CloseToolTest() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,7 @@ public final class CryptoKeyFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
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);
|
"Unable to process crypto keys files.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,17 +29,14 @@ import ghidra.program.model.symbol.*;
|
||||||
import ghidra.program.util.ProgramSelection;
|
import ghidra.program.util.ProgramSelection;
|
||||||
|
|
||||||
public class DiffApplyIgnoreTest extends DiffApplyTestAdapter {
|
public class DiffApplyIgnoreTest extends DiffApplyTestAdapter {
|
||||||
public DiffApplyIgnoreTest() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testProgramContextIgnore() throws Exception {
|
public void testProgramContextIgnore() throws Exception {
|
||||||
openDiff(diffTestP1, diffTestP2);
|
openDiff(diffTestP1, diffTestP2);
|
||||||
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Memory Differs", 2000);
|
JDialog dialog = waitForJDialog("Memory Differs");
|
||||||
assertNotNull(dialog);
|
assertNotNull(dialog);
|
||||||
pressButtonByText(dialog, "OK");
|
pressButtonByText(dialog, "OK");
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
showApplySettings();
|
showApplySettings();
|
||||||
|
|
||||||
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
|
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
|
||||||
|
@ -54,10 +51,10 @@ public class DiffApplyIgnoreTest extends DiffApplyTestAdapter {
|
||||||
public void testByteIgnore() throws Exception {
|
public void testByteIgnore() throws Exception {
|
||||||
|
|
||||||
openDiff(diffTestP1, diffTestP2);
|
openDiff(diffTestP1, diffTestP2);
|
||||||
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Memory Differs", 2000);
|
JDialog dialog = waitForJDialog("Memory Differs");
|
||||||
assertNotNull(dialog);
|
assertNotNull(dialog);
|
||||||
pressButtonByText(dialog, "OK");
|
pressButtonByText(dialog, "OK");
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
showApplySettings();
|
showApplySettings();
|
||||||
|
|
||||||
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
|
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
|
||||||
|
@ -71,10 +68,10 @@ public class DiffApplyIgnoreTest extends DiffApplyTestAdapter {
|
||||||
@Test
|
@Test
|
||||||
public void testCodeUnitIgnore() throws Exception {
|
public void testCodeUnitIgnore() throws Exception {
|
||||||
openDiff(diffTestP1, diffTestP2);
|
openDiff(diffTestP1, diffTestP2);
|
||||||
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Memory Differs", 2000);
|
JDialog dialog = waitForJDialog("Memory Differs");
|
||||||
assertNotNull(dialog);
|
assertNotNull(dialog);
|
||||||
pressButtonByText(dialog, "OK");
|
pressButtonByText(dialog, "OK");
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
showApplySettings();
|
showApplySettings();
|
||||||
|
|
||||||
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
|
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
|
||||||
|
@ -88,10 +85,10 @@ public class DiffApplyIgnoreTest extends DiffApplyTestAdapter {
|
||||||
@Test
|
@Test
|
||||||
public void testReferenceIgnore() throws Exception {
|
public void testReferenceIgnore() throws Exception {
|
||||||
openDiff(diffTestP1, diffTestP2);
|
openDiff(diffTestP1, diffTestP2);
|
||||||
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Memory Differs", 2000);
|
JDialog dialog = waitForJDialog("Memory Differs");
|
||||||
assertNotNull(dialog);
|
assertNotNull(dialog);
|
||||||
pressButtonByText(dialog, "OK");
|
pressButtonByText(dialog, "OK");
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
showApplySettings();
|
showApplySettings();
|
||||||
|
|
||||||
memRefIgnore();
|
memRefIgnore();
|
||||||
|
@ -208,10 +205,10 @@ public class DiffApplyIgnoreTest extends DiffApplyTestAdapter {
|
||||||
@Test
|
@Test
|
||||||
public void testBookmarkIgnore() throws Exception {
|
public void testBookmarkIgnore() throws Exception {
|
||||||
openDiff(diffTestP1, diffTestP2);
|
openDiff(diffTestP1, diffTestP2);
|
||||||
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Memory Differs", 2000);
|
JDialog dialog = waitForJDialog("Memory Differs");
|
||||||
assertNotNull(dialog);
|
assertNotNull(dialog);
|
||||||
pressButtonByText(dialog, "OK");
|
pressButtonByText(dialog, "OK");
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
showApplySettings();
|
showApplySettings();
|
||||||
|
|
||||||
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
|
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
|
||||||
|
@ -225,10 +222,10 @@ public class DiffApplyIgnoreTest extends DiffApplyTestAdapter {
|
||||||
@Test
|
@Test
|
||||||
public void testPropertyIgnore() throws Exception {
|
public void testPropertyIgnore() throws Exception {
|
||||||
openDiff(diffTestP1, diffTestP2);
|
openDiff(diffTestP1, diffTestP2);
|
||||||
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Memory Differs", 2000);
|
JDialog dialog = waitForJDialog("Memory Differs");
|
||||||
assertNotNull(dialog);
|
assertNotNull(dialog);
|
||||||
pressButtonByText(dialog, "OK");
|
pressButtonByText(dialog, "OK");
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
showApplySettings();
|
showApplySettings();
|
||||||
|
|
||||||
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
|
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
|
||||||
|
@ -242,10 +239,10 @@ public class DiffApplyIgnoreTest extends DiffApplyTestAdapter {
|
||||||
@Test
|
@Test
|
||||||
public void testFunctionIgnore() throws Exception {
|
public void testFunctionIgnore() throws Exception {
|
||||||
openDiff(diffTestP1, diffTestP2);
|
openDiff(diffTestP1, diffTestP2);
|
||||||
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Memory Differs", 2000);
|
JDialog dialog = waitForJDialog("Memory Differs");
|
||||||
assertNotNull(dialog);
|
assertNotNull(dialog);
|
||||||
pressButtonByText(dialog, "OK");
|
pressButtonByText(dialog, "OK");
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
showApplySettings();
|
showApplySettings();
|
||||||
|
|
||||||
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
|
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
|
||||||
|
|
|
@ -15,8 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.core.diff;
|
package ghidra.app.plugin.core.diff;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.*;
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
@ -36,14 +35,10 @@ import ghidra.util.exception.InvalidInputException;
|
||||||
|
|
||||||
public class DiffApplyReplaceTest extends DiffApplyTestAdapter {
|
public class DiffApplyReplaceTest extends DiffApplyTestAdapter {
|
||||||
|
|
||||||
public DiffApplyReplaceTest() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testProgramContextReplace() throws Exception {
|
public void testProgramContextReplace() throws Exception {
|
||||||
openDiff(diffTestP1, diffTestP2);
|
openDiff(diffTestP1, diffTestP2);
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
showApplySettings();
|
showApplySettings();
|
||||||
|
|
||||||
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
|
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
|
||||||
|
@ -57,9 +52,9 @@ public class DiffApplyReplaceTest extends DiffApplyTestAdapter {
|
||||||
@Test
|
@Test
|
||||||
public void testByteReplace() throws Exception {
|
public void testByteReplace() throws Exception {
|
||||||
openDiff(diffTestP1, diffTestP2);
|
openDiff(diffTestP1, diffTestP2);
|
||||||
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Memory Differs", 2000);
|
JDialog dialog = waitForJDialog("Memory Differs");
|
||||||
pressButtonByText(dialog, "OK");
|
pressButtonByText(dialog, "OK");
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
showApplySettings();
|
showApplySettings();
|
||||||
|
|
||||||
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
|
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
|
||||||
|
@ -73,9 +68,9 @@ public class DiffApplyReplaceTest extends DiffApplyTestAdapter {
|
||||||
@Test
|
@Test
|
||||||
public void testCodeUnitReplace() throws Exception {
|
public void testCodeUnitReplace() throws Exception {
|
||||||
openDiff(diffTestP1, diffTestP2);
|
openDiff(diffTestP1, diffTestP2);
|
||||||
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Memory Differs", 2000);
|
JDialog dialog = waitForJDialog("Memory Differs");
|
||||||
pressButtonByText(dialog, "OK");
|
pressButtonByText(dialog, "OK");
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
showApplySettings();
|
showApplySettings();
|
||||||
|
|
||||||
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
|
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
|
||||||
|
@ -89,9 +84,9 @@ public class DiffApplyReplaceTest extends DiffApplyTestAdapter {
|
||||||
@Test
|
@Test
|
||||||
public void testReferenceReplace() throws Exception {
|
public void testReferenceReplace() throws Exception {
|
||||||
openDiff(diffTestP1, diffTestP2);
|
openDiff(diffTestP1, diffTestP2);
|
||||||
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Memory Differs", 2000);
|
JDialog dialog = waitForJDialog("Memory Differs");
|
||||||
pressButtonByText(dialog, "OK");
|
pressButtonByText(dialog, "OK");
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
showApplySettings();
|
showApplySettings();
|
||||||
memRefReplace();
|
memRefReplace();
|
||||||
extRefReplace();
|
extRefReplace();
|
||||||
|
@ -284,9 +279,9 @@ public class DiffApplyReplaceTest extends DiffApplyTestAdapter {
|
||||||
@Test
|
@Test
|
||||||
public void testBookmarkReplace() throws Exception {
|
public void testBookmarkReplace() throws Exception {
|
||||||
openDiff(diffTestP1, diffTestP2);
|
openDiff(diffTestP1, diffTestP2);
|
||||||
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Memory Differs", 2000);
|
JDialog dialog = waitForJDialog("Memory Differs");
|
||||||
pressButtonByText(dialog, "OK");
|
pressButtonByText(dialog, "OK");
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
showApplySettings();
|
showApplySettings();
|
||||||
|
|
||||||
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
|
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
|
||||||
|
@ -300,9 +295,9 @@ public class DiffApplyReplaceTest extends DiffApplyTestAdapter {
|
||||||
@Test
|
@Test
|
||||||
public void testPropertyReplace() throws Exception {
|
public void testPropertyReplace() throws Exception {
|
||||||
openDiff(diffTestP1, diffTestP2);
|
openDiff(diffTestP1, diffTestP2);
|
||||||
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Memory Differs", 2000);
|
JDialog dialog = waitForJDialog("Memory Differs");
|
||||||
pressButtonByText(dialog, "OK");
|
pressButtonByText(dialog, "OK");
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
showApplySettings();
|
showApplySettings();
|
||||||
|
|
||||||
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
|
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
|
||||||
|
@ -316,9 +311,9 @@ public class DiffApplyReplaceTest extends DiffApplyTestAdapter {
|
||||||
@Test
|
@Test
|
||||||
public void testFunctionReplace() throws Exception {
|
public void testFunctionReplace() throws Exception {
|
||||||
openDiff(diffTestP1, diffTestP2);
|
openDiff(diffTestP1, diffTestP2);
|
||||||
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Memory Differs", 2000);
|
JDialog dialog = waitForJDialog("Memory Differs");
|
||||||
pressButtonByText(dialog, "OK");
|
pressButtonByText(dialog, "OK");
|
||||||
waitForPostedSwingRunnables();
|
waitForSwing();
|
||||||
showApplySettings();
|
showApplySettings();
|
||||||
|
|
||||||
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
|
ProgramSelection origDiffs = diffPlugin.getDiffHighlightSelection();
|
||||||
|
|
|
@ -24,7 +24,6 @@ import javax.swing.*;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import docking.widgets.MultiLineLabel;
|
|
||||||
import ghidra.app.events.ProgramSelectionPluginEvent;
|
import ghidra.app.events.ProgramSelectionPluginEvent;
|
||||||
import ghidra.program.database.ProgramBuilder;
|
import ghidra.program.database.ProgramBuilder;
|
||||||
import ghidra.program.model.address.AddressSet;
|
import ghidra.program.model.address.AddressSet;
|
||||||
|
@ -353,9 +352,6 @@ public class DiffGetTest extends DiffTestAdapter {
|
||||||
|
|
||||||
assertNull(fp2.getTopLevelAncestor());
|
assertNull(fp2.getTopLevelAncestor());
|
||||||
Window win = waitForWindow("Can't Open Selected Program");
|
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");
|
pressButton(win, "OK");
|
||||||
win = waitForWindow("Select Other Program");
|
win = waitForWindow("Select Other Program");
|
||||||
assertNotNull(win);
|
assertNotNull(win);
|
||||||
|
|
|
@ -147,9 +147,6 @@ public class DualProgramTest extends DiffTestAdapter {
|
||||||
|
|
||||||
waitForTasks();
|
waitForTasks();
|
||||||
win = waitForWindow("Can't Open Selected Program");
|
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");
|
pressButton(win, "OK");
|
||||||
|
|
||||||
win = waitForWindow("Select Other Program");
|
win = waitForWindow("Select Other Program");
|
||||||
|
|
|
@ -24,7 +24,6 @@ import javax.swing.table.TableModel;
|
||||||
|
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
|
|
||||||
import docking.widgets.MultiLineLabel;
|
|
||||||
import docking.wizard.WizardManager;
|
import docking.wizard.WizardManager;
|
||||||
import docking.wizard.WizardPanel;
|
import docking.wizard.WizardPanel;
|
||||||
import generic.test.TestUtils;
|
import generic.test.TestUtils;
|
||||||
|
@ -46,8 +45,8 @@ import ghidra.util.table.GhidraTable;
|
||||||
|
|
||||||
public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
|
public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
private static final String TEST_SOURCE_PROGRAM_NAME = "VersionTracking/WallaceSrc";
|
private static String TEST_SOURCE_PROGRAM_NAME = "VersionTracking/WallaceSrc";
|
||||||
private static final String TEST_DESTINATION_PROGRAM_NAME = "VersionTracking/WallaceVersion2";
|
private static String TEST_DESTINATION_PROGRAM_NAME = "VersionTracking/WallaceVersion2";
|
||||||
|
|
||||||
private enum VTWizardPanelAction {
|
private enum VTWizardPanelAction {
|
||||||
BACK, NEXT, FINISH, CANCEL;
|
BACK, NEXT, FINISH, CANCEL;
|
||||||
|
@ -130,7 +129,7 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
createWizardManager();
|
createWizardManager();
|
||||||
|
|
||||||
SystemUtilities.runSwingLater(
|
runSwingLater(
|
||||||
() -> wizardManager.showWizard(controller.getParentComponent()));
|
() -> wizardManager.showWizard(controller.getParentComponent()));
|
||||||
|
|
||||||
waitForDialogComponent(WizardManager.class);
|
waitForDialogComponent(WizardManager.class);
|
||||||
|
@ -186,7 +185,7 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
createWizardManager();
|
createWizardManager();
|
||||||
|
|
||||||
SystemUtilities.runSwingLater(
|
runSwingLater(
|
||||||
() -> wizardManager.showWizard(controller.getParentComponent()));
|
() -> wizardManager.showWizard(controller.getParentComponent()));
|
||||||
|
|
||||||
waitForDialogComponent(WizardManager.class);
|
waitForDialogComponent(WizardManager.class);
|
||||||
|
@ -248,7 +247,7 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
createWizardManager();
|
createWizardManager();
|
||||||
|
|
||||||
SystemUtilities.runSwingLater(
|
runSwingLater(
|
||||||
() -> wizardManager.showWizard(controller.getParentComponent()));
|
() -> wizardManager.showWizard(controller.getParentComponent()));
|
||||||
|
|
||||||
waitForDialogComponent(WizardManager.class);
|
waitForDialogComponent(WizardManager.class);
|
||||||
|
@ -310,7 +309,7 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
createWizardManager();
|
createWizardManager();
|
||||||
|
|
||||||
SystemUtilities.runSwingLater(
|
runSwingLater(
|
||||||
() -> wizardManager.showWizard(controller.getParentComponent()));
|
() -> wizardManager.showWizard(controller.getParentComponent()));
|
||||||
|
|
||||||
waitForDialogComponent(WizardManager.class);
|
waitForDialogComponent(WizardManager.class);
|
||||||
|
@ -387,7 +386,7 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
createWizardManager();
|
createWizardManager();
|
||||||
|
|
||||||
SystemUtilities.runSwingLater(
|
runSwingLater(
|
||||||
() -> wizardManager.showWizard(controller.getParentComponent()));
|
() -> wizardManager.showWizard(controller.getParentComponent()));
|
||||||
|
|
||||||
waitForDialogComponent(WizardManager.class);
|
waitForDialogComponent(WizardManager.class);
|
||||||
|
@ -451,7 +450,7 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
createWizardManager();
|
createWizardManager();
|
||||||
|
|
||||||
SystemUtilities.runSwingLater(
|
runSwingLater(
|
||||||
() -> wizardManager.showWizard(controller.getParentComponent()));
|
() -> wizardManager.showWizard(controller.getParentComponent()));
|
||||||
|
|
||||||
waitForDialogComponent(WizardManager.class);
|
waitForDialogComponent(WizardManager.class);
|
||||||
|
@ -515,7 +514,7 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
createWizardManager();
|
createWizardManager();
|
||||||
|
|
||||||
SystemUtilities.runSwingLater(
|
runSwingLater(
|
||||||
() -> wizardManager.showWizard(controller.getParentComponent()));
|
() -> wizardManager.showWizard(controller.getParentComponent()));
|
||||||
|
|
||||||
waitForDialogComponent(WizardManager.class);
|
waitForDialogComponent(WizardManager.class);
|
||||||
|
@ -592,7 +591,7 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
createWizardManager();
|
createWizardManager();
|
||||||
|
|
||||||
SystemUtilities.runSwingLater(
|
runSwingLater(
|
||||||
() -> wizardManager.showWizard(controller.getParentComponent()));
|
() -> wizardManager.showWizard(controller.getParentComponent()));
|
||||||
|
|
||||||
waitForDialogComponent(WizardManager.class);
|
waitForDialogComponent(WizardManager.class);
|
||||||
|
@ -694,7 +693,7 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
createWizardManager();
|
createWizardManager();
|
||||||
|
|
||||||
SystemUtilities.runSwingLater(
|
runSwingLater(
|
||||||
() -> wizardManager.showWizard(controller.getParentComponent()));
|
() -> wizardManager.showWizard(controller.getParentComponent()));
|
||||||
|
|
||||||
waitForDialogComponent(WizardManager.class);
|
waitForDialogComponent(WizardManager.class);
|
||||||
|
@ -725,12 +724,12 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
String msgContains = "Data Reference Match";
|
String msgContains = "Data Reference Match";
|
||||||
JDialog dialog = waitForJDialog("Version Tracking: Add To Session");
|
JDialog dialog = waitForJDialog("Version Tracking: Add To Session");
|
||||||
assertNotNull("Info dialog not found", dialog);
|
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,
|
assertTrue("Expected Server Error message starting with: " + msgStart,
|
||||||
label.getLabel().startsWith(msgStart));
|
message.startsWith(msgStart));
|
||||||
assertTrue("Expected Server Error message containing: " + msgContains,
|
assertTrue("Expected Server Error message containing: " + msgContains,
|
||||||
label.getLabel().contains(msgContains));
|
message.contains(msgContains));
|
||||||
pressButtonByText(dialog, "OK");
|
pressButtonByText(dialog, "OK");
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
|
|
||||||
|
@ -747,17 +746,13 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
assertEquals("Number of matches", 0, vtMatchSet2.getMatchCount());
|
assertEquals("Number of matches", 0, vtMatchSet2.getMatchCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
//********************************************
|
private void chooseFromCorrelationPanel(String correlatorName,
|
||||||
// Private Work/Validation methods.
|
VTWizardPanelAction wizardAction) {
|
||||||
//********************************************
|
|
||||||
|
|
||||||
private void chooseFromCorrelationPanel(final String correlatorName,
|
|
||||||
final VTWizardPanelAction wizardAction) {
|
|
||||||
|
|
||||||
WizardPanel currentWizardPanel = wizardManager.getCurrentWizardPanel();
|
WizardPanel currentWizardPanel = wizardManager.getCurrentWizardPanel();
|
||||||
assertNotNull(currentWizardPanel);
|
assertNotNull(currentWizardPanel);
|
||||||
assertTrue(currentWizardPanel instanceof CorrelatorPanel);
|
assertTrue(currentWizardPanel instanceof CorrelatorPanel);
|
||||||
final CorrelatorPanel correlatorPanel = (CorrelatorPanel) currentWizardPanel;
|
CorrelatorPanel correlatorPanel = (CorrelatorPanel) currentWizardPanel;
|
||||||
SystemUtilities.runSwingNow(() -> {
|
SystemUtilities.runSwingNow(() -> {
|
||||||
GhidraTable table = (GhidraTable) TestUtils.getInstanceField("table", correlatorPanel);
|
GhidraTable table = (GhidraTable) TestUtils.getInstanceField("table", correlatorPanel);
|
||||||
TableModel model = table.getModel();
|
TableModel model = table.getModel();
|
||||||
|
@ -771,7 +766,7 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void changeCorrelatorOptionsPanel(Object correlatorOptionsObject,
|
private void changeCorrelatorOptionsPanel(Object correlatorOptionsObject,
|
||||||
final VTWizardPanelAction wizardAction) {
|
VTWizardPanelAction wizardAction) {
|
||||||
|
|
||||||
// Options Panel
|
// Options Panel
|
||||||
WizardPanel currentWizardPanel = wizardManager.getCurrentWizardPanel();
|
WizardPanel currentWizardPanel = wizardManager.getCurrentWizardPanel();
|
||||||
|
@ -837,7 +832,7 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void changeAddressSetOptionsPanel(boolean excludeAccepted, boolean limitAddressSets,
|
private void changeAddressSetOptionsPanel(boolean excludeAccepted, boolean limitAddressSets,
|
||||||
final VTWizardPanelAction wizardAction) {
|
VTWizardPanelAction wizardAction) {
|
||||||
|
|
||||||
// Address Set Options Panel
|
// Address Set Options Panel
|
||||||
WizardPanel currentWizardPanel = wizardManager.getCurrentWizardPanel();
|
WizardPanel currentWizardPanel = wizardManager.getCurrentWizardPanel();
|
||||||
|
@ -1002,22 +997,22 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void changeAddressSetViaListRemoveRange(final boolean isSource,
|
private void changeAddressSetViaListRemoveRange(boolean isSource,
|
||||||
final AddressSetPanel addressSetPanel, final AddressSetView desiredAddressSet) {
|
AddressSetPanel addressSetPanel, AddressSetView desiredAddressSet) {
|
||||||
ChooseAddressSetEditorPanel panel =
|
ChooseAddressSetEditorPanel panel =
|
||||||
(ChooseAddressSetEditorPanel) TestUtils.getInstanceField("panel", addressSetPanel);
|
(ChooseAddressSetEditorPanel) TestUtils.getInstanceField("panel", addressSetPanel);
|
||||||
assertNotNull(panel);
|
assertNotNull(panel);
|
||||||
|
|
||||||
final JButton addRangeButton =
|
JButton addRangeButton =
|
||||||
(JButton) TestUtils.getInstanceField("addRangeButton", panel);
|
(JButton) TestUtils.getInstanceField("addRangeButton", panel);
|
||||||
assertNotNull("Couldn't get button for adding address range.", addRangeButton);
|
assertNotNull("Couldn't get button for adding address range.", addRangeButton);
|
||||||
JButton listRemoveRangeButton =
|
JButton listRemoveRangeButton =
|
||||||
(JButton) TestUtils.getInstanceField("removeRangeButton", panel);
|
(JButton) TestUtils.getInstanceField("removeRangeButton", panel);
|
||||||
assertNotNull("Couldn't get button for removing address range for list selection.",
|
assertNotNull("Couldn't get button for removing address range for list selection.",
|
||||||
listRemoveRangeButton);
|
listRemoveRangeButton);
|
||||||
final JList list = (JList) TestUtils.getInstanceField("list", panel);
|
JList<?> list = (JList<?>) TestUtils.getInstanceField("list", panel);
|
||||||
SystemUtilities.runSwingNow(() -> {
|
SystemUtilities.runSwingNow(() -> {
|
||||||
ListModel model = list.getModel();
|
ListModel<?> model = list.getModel();
|
||||||
int size = model.getSize();
|
int size = model.getSize();
|
||||||
list.setSelectionInterval(0, size - 1);// Select all items in the list.
|
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,
|
private void changeAddressSetViaSubtractDialog(boolean isSource,
|
||||||
final AddressSetPanel addressSetPanel, final AddressSetView desiredAddressSet) {
|
AddressSetPanel addressSetPanel, AddressSetView desiredAddressSet) {
|
||||||
ChooseAddressSetEditorPanel panel =
|
ChooseAddressSetEditorPanel panel =
|
||||||
(ChooseAddressSetEditorPanel) TestUtils.getInstanceField("panel", addressSetPanel);
|
(ChooseAddressSetEditorPanel) TestUtils.getInstanceField("panel", addressSetPanel);
|
||||||
assertNotNull(panel);
|
assertNotNull(panel);
|
||||||
|
|
||||||
final JButton addRangeButton =
|
JButton addRangeButton =
|
||||||
(JButton) TestUtils.getInstanceField("addRangeButton", panel);
|
(JButton) TestUtils.getInstanceField("addRangeButton", panel);
|
||||||
final JButton subtractRangeButton =
|
JButton subtractRangeButton =
|
||||||
(JButton) TestUtils.getInstanceField("subtractRangeButton", panel);
|
(JButton) TestUtils.getInstanceField("subtractRangeButton", panel);
|
||||||
JList list = (JList) TestUtils.getInstanceField("list", panel);
|
|
||||||
|
|
||||||
Runnable r = () -> subtractRangeButton.doClick();
|
Runnable r = () -> subtractRangeButton.doClick();
|
||||||
runSwing(r, false);
|
runSwing(r, false);
|
||||||
|
@ -1057,11 +1051,11 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void enterAddressRange(final boolean isSource, final String buttonText,
|
private void enterAddressRange(boolean isSource, String buttonText,
|
||||||
final String minAddress, final String maxAddress) {
|
String minAddress, String maxAddress) {
|
||||||
|
|
||||||
final AddRemoveAddressRangeDialog addRemoveDialog =
|
AddRemoveAddressRangeDialog addRemoveDialog =
|
||||||
env.waitForDialogComponent(AddRemoveAddressRangeDialog.class, 2000);
|
waitForDialogComponent(AddRemoveAddressRangeDialog.class);
|
||||||
assertNotNull(addRemoveDialog);
|
assertNotNull(addRemoveDialog);
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
|
|
||||||
|
@ -1069,20 +1063,20 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
assertEquals((isSource ? "Source" : "Destination") + " Address Range",
|
assertEquals((isSource ? "Source" : "Destination") + " Address Range",
|
||||||
addRemoveDialog.getTitle());
|
addRemoveDialog.getTitle());
|
||||||
|
|
||||||
final AddressInput minAddressField =
|
AddressInput minAddressField =
|
||||||
(AddressInput) TestUtils.getInstanceField("minAddressField", addRemoveDialog);
|
(AddressInput) TestUtils.getInstanceField("minAddressField", addRemoveDialog);
|
||||||
assertNotNull(minAddressField);
|
assertNotNull(minAddressField);
|
||||||
|
|
||||||
SystemUtilities.runSwingLater(() -> {
|
runSwingLater(() -> {
|
||||||
Address address = isSource ? sourceAddress(minAddress) : destinationAddress(minAddress);
|
Address address = isSource ? sourceAddress(minAddress) : destinationAddress(minAddress);
|
||||||
minAddressField.setAddress(address);
|
minAddressField.setAddress(address);
|
||||||
});
|
});
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
|
|
||||||
final AddressInput maxAddressField =
|
AddressInput maxAddressField =
|
||||||
(AddressInput) TestUtils.getInstanceField("maxAddressField", addRemoveDialog);
|
(AddressInput) TestUtils.getInstanceField("maxAddressField", addRemoveDialog);
|
||||||
assertNotNull(maxAddressField);
|
assertNotNull(maxAddressField);
|
||||||
SystemUtilities.runSwingLater(() -> {
|
runSwingLater(() -> {
|
||||||
Address address = isSource ? sourceAddress(maxAddress) : destinationAddress(maxAddress);
|
Address address = isSource ? sourceAddress(maxAddress) : destinationAddress(maxAddress);
|
||||||
maxAddressField.setAddress(address);
|
maxAddressField.setAddress(address);
|
||||||
});
|
});
|
||||||
|
@ -1093,11 +1087,11 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
assertTrue("Dialog not closed after pressing: " + buttonText, !addRemoveDialog.isShowing());
|
assertTrue("Dialog not closed after pressing: " + buttonText, !addRemoveDialog.isShowing());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void enterAddressRange(final boolean isSource, final String buttonText,
|
private void enterAddressRange(boolean isSource, String buttonText,
|
||||||
final Address minAddress, final Address maxAddress) {
|
Address minAddress, Address maxAddress) {
|
||||||
|
|
||||||
final AddRemoveAddressRangeDialog addRemoveDialog =
|
AddRemoveAddressRangeDialog addRemoveDialog =
|
||||||
env.waitForDialogComponent(AddRemoveAddressRangeDialog.class, 2000);
|
waitForDialogComponent(AddRemoveAddressRangeDialog.class);
|
||||||
assertNotNull(addRemoveDialog);
|
assertNotNull(addRemoveDialog);
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
|
|
||||||
|
@ -1105,18 +1099,18 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
assertEquals((isSource ? "Source" : "Destination") + " Address Range",
|
assertEquals((isSource ? "Source" : "Destination") + " Address Range",
|
||||||
addRemoveDialog.getTitle());
|
addRemoveDialog.getTitle());
|
||||||
|
|
||||||
final AddressInput minAddressField =
|
AddressInput minAddressField =
|
||||||
(AddressInput) TestUtils.getInstanceField("minAddressField", addRemoveDialog);
|
(AddressInput) TestUtils.getInstanceField("minAddressField", addRemoveDialog);
|
||||||
assertNotNull(minAddressField);
|
assertNotNull(minAddressField);
|
||||||
|
|
||||||
SystemUtilities.runSwingLater(() -> minAddressField.setAddress(minAddress));
|
runSwingLater(() -> minAddressField.setAddress(minAddress));
|
||||||
|
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
|
|
||||||
final AddressInput maxAddressField =
|
AddressInput maxAddressField =
|
||||||
(AddressInput) TestUtils.getInstanceField("maxAddressField", addRemoveDialog);
|
(AddressInput) TestUtils.getInstanceField("maxAddressField", addRemoveDialog);
|
||||||
assertNotNull(maxAddressField);
|
assertNotNull(maxAddressField);
|
||||||
SystemUtilities.runSwingLater(() -> {
|
runSwingLater(() -> {
|
||||||
maxAddressField.setAddress(maxAddress);
|
maxAddressField.setAddress(maxAddress);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1133,7 +1127,7 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void changeAddressSetsPanel(AddressSetChoice sourceChoice,
|
private void changeAddressSetsPanel(AddressSetChoice sourceChoice,
|
||||||
AddressSetChoice destinationChoice, final VTWizardPanelAction wizardAction) {
|
AddressSetChoice destinationChoice, VTWizardPanelAction wizardAction) {
|
||||||
|
|
||||||
changeAddressSetChoices(sourceChoice, destinationChoice);
|
changeAddressSetChoices(sourceChoice, destinationChoice);
|
||||||
|
|
||||||
|
@ -1154,8 +1148,8 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
setSelectionInTool(destinationTool, destinationSelection);
|
setSelectionInTool(destinationTool, destinationSelection);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkSummaryPanel(final String labelString, final String summaryString,
|
private void checkSummaryPanel(String labelString, String summaryString,
|
||||||
final VTWizardPanelAction wizardAction) {
|
VTWizardPanelAction wizardAction) {
|
||||||
|
|
||||||
// Address Set Options Panel
|
// Address Set Options Panel
|
||||||
WizardPanel currentWizardPanel = wizardManager.getCurrentWizardPanel();
|
WizardPanel currentWizardPanel = wizardManager.getCurrentWizardPanel();
|
||||||
|
@ -1174,7 +1168,8 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
assertEquals(labelString, labelText);
|
assertEquals(labelString, labelText);
|
||||||
assertEquals(summaryString, summaryText);
|
assertEquals(summaryString, summaryText);
|
||||||
|
|
||||||
SystemUtilities.runSwingNow(() -> invoke(wizardAction));
|
runSwingLater(() -> invoke(wizardAction));
|
||||||
|
waitForSwing();
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getRowWithFieldValueInColumn(String string, TableModel model, int column) {
|
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();
|
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);
|
this.addWindowListener(windowAdapter);
|
||||||
modalFixWindowAdapter = new WindowAdapter() {
|
modalFixWindowAdapter = new WindowAdapter() {
|
||||||
|
@ -249,6 +255,10 @@ public class DockingDialog extends JDialog implements HelpDescriptor {
|
||||||
}
|
}
|
||||||
|
|
||||||
void close() {
|
void close() {
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cleanup() {
|
||||||
if (component.getRemberSize() || component.getRememberLocation()) {
|
if (component.getRemberSize() || component.getRememberLocation()) {
|
||||||
String key = getKey();
|
String key = getKey();
|
||||||
Rectangle rect = getBounds();
|
Rectangle rect = getBounds();
|
||||||
|
@ -258,7 +268,10 @@ public class DockingDialog extends JDialog implements HelpDescriptor {
|
||||||
|
|
||||||
component.setDialog(null);
|
component.setDialog(null);
|
||||||
removeWindowListener(windowAdapter);
|
removeWindowListener(windowAdapter);
|
||||||
|
|
||||||
|
// this will do nothing if already closed
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
|
|
||||||
component.dialogClosed();
|
component.dialogClosed();
|
||||||
component = null;
|
component = null;
|
||||||
getContentPane().removeAll();
|
getContentPane().removeAll();
|
||||||
|
|
|
@ -17,7 +17,6 @@ package docking;
|
||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Window;
|
import java.awt.Window;
|
||||||
import java.io.*;
|
|
||||||
|
|
||||||
import docking.widgets.OkDialog;
|
import docking.widgets.OkDialog;
|
||||||
import docking.widgets.OptionDialog;
|
import docking.widgets.OptionDialog;
|
||||||
|
@ -26,7 +25,16 @@ import ghidra.util.exception.MultipleCauses;
|
||||||
|
|
||||||
public class DockingErrorDisplay implements ErrorDisplay {
|
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();
|
ConsoleErrorDisplay consoleDisplay = new ConsoleErrorDisplay();
|
||||||
|
|
||||||
|
@ -52,8 +60,8 @@ public class DockingErrorDisplay implements ErrorDisplay {
|
||||||
|
|
||||||
private void displayMessage(MessageType messageType, ErrorLogger errorLogger, Object originator,
|
private void displayMessage(MessageType messageType, ErrorLogger errorLogger, Object originator,
|
||||||
Component parent, String title, Object message, Throwable throwable) {
|
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 messageString = message != null ? message.toString() : null;
|
||||||
String rawMessage = HTMLUtilities.fromHTML(messageString);
|
String rawMessage = HTMLUtilities.fromHTML(messageString);
|
||||||
switch (messageType) {
|
switch (messageType) {
|
||||||
|
@ -75,7 +83,7 @@ public class DockingErrorDisplay implements ErrorDisplay {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
showDialog(title, message, throwable, dialogType, messageString, getWindow(parent));
|
showDialog(title, throwable, dialogType, messageString, getWindow(parent));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Component getWindow(Component component) {
|
private Component getWindow(Component component) {
|
||||||
|
@ -85,33 +93,45 @@ public class DockingErrorDisplay implements ErrorDisplay {
|
||||||
return component;
|
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) {
|
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,
|
if (dialogType == OptionDialog.ERROR_MESSAGE) {
|
||||||
int dialogType, String messageString, Component parent) {
|
// Note: all calls to manipulate the error dialog must be on the Swing thread to
|
||||||
DialogComponentProvider dialog = null;
|
// guarantee thread visibility to our state variables
|
||||||
if (throwable != null) {
|
Swing.runIfSwingOrRunLater(
|
||||||
dialog = createErrorDialog(title, message, throwable, messageString);
|
() -> showDialogOnSwing(title, throwable, dialogType, messageString, parent));
|
||||||
}
|
}
|
||||||
else {
|
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,
|
private void showDialogOnSwing(String title, Throwable throwable,
|
||||||
final Throwable throwable, String messageString) {
|
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)) {
|
if (containsMultipleCauses(throwable)) {
|
||||||
return new ErrLogExpandableDialog(title, messageString, throwable);
|
return new ErrLogExpandableDialog(title, messageString, throwable);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ErrLogDialog.createExceptionDialog(title, messageString,
|
return ErrLogDialog.createExceptionDialog(title, messageString, throwable);
|
||||||
buildStackTrace(throwable, message == null ? throwable.getMessage() : messageString));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean containsMultipleCauses(Throwable throwable) {
|
private boolean containsMultipleCauses(Throwable throwable) {
|
||||||
|
@ -125,34 +145,4 @@ public class DockingErrorDisplay implements ErrorDisplay {
|
||||||
|
|
||||||
return containsMultipleCauses(throwable.getCause());
|
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,20 +20,35 @@ import java.awt.event.ComponentAdapter;
|
||||||
import java.awt.event.ComponentEvent;
|
import java.awt.event.ComponentEvent;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
import docking.widgets.ScrollableTextArea;
|
import docking.widgets.ScrollableTextArea;
|
||||||
import docking.widgets.label.GHtmlLabel;
|
import docking.widgets.label.GHtmlLabel;
|
||||||
import docking.widgets.label.GIconLabel;
|
import docking.widgets.label.GIconLabel;
|
||||||
|
import docking.widgets.table.*;
|
||||||
|
import generic.json.Json;
|
||||||
import generic.util.WindowUtilities;
|
import generic.util.WindowUtilities;
|
||||||
|
import ghidra.docking.settings.Settings;
|
||||||
import ghidra.framework.Application;
|
import ghidra.framework.Application;
|
||||||
|
import ghidra.framework.plugintool.ServiceProvider;
|
||||||
|
import ghidra.framework.plugintool.ServiceProviderStub;
|
||||||
import ghidra.util.HTMLUtilities;
|
import ghidra.util.HTMLUtilities;
|
||||||
|
import ghidra.util.Swing;
|
||||||
|
import ghidra.util.table.column.DefaultTimestampRenderer;
|
||||||
|
import ghidra.util.table.column.GColumnRenderer;
|
||||||
|
import utilities.util.reflection.ReflectionUtilities;
|
||||||
|
|
||||||
public class ErrLogDialog extends DialogComponentProvider {
|
/**
|
||||||
private static final int TEXT_ROWS = 30;
|
* A dialog that takes error text and displays it with an option details button. If there is
|
||||||
|
* an {@link ErrorReporter}, then a button is provided to report the error.
|
||||||
|
*/
|
||||||
|
public class ErrLogDialog extends AbstractErrDialog {
|
||||||
|
private static final int TEXT_ROWS = 20;
|
||||||
private static final int TEXT_COLUMNS = 80;
|
private static final int TEXT_COLUMNS = 80;
|
||||||
private static final int ERROR_BUFFER_SIZE = 1024;
|
|
||||||
|
|
||||||
private static final String SEND = "Log Error...";
|
private static final String SEND = "Log Error...";
|
||||||
private static final String DETAIL = "Details >>>";
|
private static final String DETAIL = "Details >>>";
|
||||||
|
@ -46,32 +61,30 @@ public class ErrLogDialog extends DialogComponentProvider {
|
||||||
/** tracks 'details panel' open state across invocations */
|
/** tracks 'details panel' open state across invocations */
|
||||||
private static boolean isShowingDetails = false;
|
private static boolean isShowingDetails = false;
|
||||||
|
|
||||||
|
private int errorId = 0;
|
||||||
|
|
||||||
// state-dependent gui members
|
// state-dependent gui members
|
||||||
private ErrorDetailsPanel detailsPanel;
|
private ErrorDetailsSplitPane detailsPane;
|
||||||
private JButton detailsButton;
|
private JButton detailsButton;
|
||||||
private JButton sendButton;
|
private JButton sendButton;
|
||||||
private JPanel mainPanel;
|
private JPanel mainPanel;
|
||||||
private static ErrorReporter errorReporter;
|
private static ErrorReporter errorReporter;
|
||||||
|
|
||||||
public static ErrLogDialog createExceptionDialog(String title, String message, String details) {
|
private List<ErrorEntry> errors = new ArrayList<>();
|
||||||
return new ErrLogDialog(title, message, details, true);
|
|
||||||
|
public static ErrLogDialog createExceptionDialog(String title, String message, Throwable t) {
|
||||||
|
return new ErrLogDialog(title, message, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ErrLogDialog createLogMessageDialog(String title, String message,
|
private ErrLogDialog(String title, String message, Throwable throwable) {
|
||||||
String details) {
|
super(title != null ? title : "Error");
|
||||||
return new ErrLogDialog(title, message, details, false);
|
|
||||||
}
|
ErrorEntry error = new ErrorEntry(message, throwable);
|
||||||
|
errors.add(error);
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
* Used by the Err class's static methods for logging various
|
|
||||||
* kinds of errors: Runtime, System, User, Asserts
|
|
||||||
*/
|
|
||||||
private ErrLogDialog(String title, String message, String details, boolean isException) {
|
|
||||||
super(title != null ? title : "Error", true, false, true, false);
|
|
||||||
setRememberSize(false);
|
setRememberSize(false);
|
||||||
setRememberLocation(false);
|
setRememberLocation(false);
|
||||||
buildMainPanel(message, addUsefulReportingInfo(details), isException);
|
buildMainPanel(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String addUsefulReportingInfo(String details) {
|
private String addUsefulReportingInfo(String details) {
|
||||||
|
@ -127,13 +140,21 @@ public class ErrLogDialog extends DialogComponentProvider {
|
||||||
return errorReporter;
|
return errorReporter;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildMainPanel(String message, String details, boolean isException) {
|
private void buildMainPanel(String message) {
|
||||||
|
|
||||||
JPanel introPanel = new JPanel(new BorderLayout(10, 10));
|
JPanel introPanel = new JPanel(new BorderLayout(10, 10));
|
||||||
introPanel.add(
|
introPanel.add(
|
||||||
new GIconLabel(UIManager.getIcon("OptionPane.errorIcon"), SwingConstants.RIGHT),
|
new GIconLabel(UIManager.getIcon("OptionPane.errorIcon"), SwingConstants.RIGHT),
|
||||||
BorderLayout.WEST);
|
BorderLayout.WEST);
|
||||||
introPanel.add(new GHtmlLabel(HTMLUtilities.toHTML(message)), BorderLayout.CENTER);
|
introPanel.add(new GHtmlLabel(HTMLUtilities.toHTML(message)) {
|
||||||
|
@Override
|
||||||
|
public Dimension getPreferredSize() {
|
||||||
|
// rendering HTML the label can expand larger than the screen; keep it reasonable
|
||||||
|
Dimension size = super.getPreferredSize();
|
||||||
|
size.width = 300;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
}, BorderLayout.CENTER);
|
||||||
|
|
||||||
mainPanel = new JPanel(new BorderLayout(10, 20));
|
mainPanel = new JPanel(new BorderLayout(10, 20));
|
||||||
mainPanel.add(introPanel, BorderLayout.NORTH);
|
mainPanel.add(introPanel, BorderLayout.NORTH);
|
||||||
|
@ -141,21 +162,15 @@ public class ErrLogDialog extends DialogComponentProvider {
|
||||||
sendButton = new JButton(SEND);
|
sendButton = new JButton(SEND);
|
||||||
sendButton.addActionListener(e -> sendDetails());
|
sendButton.addActionListener(e -> sendDetails());
|
||||||
|
|
||||||
detailsPanel = new ErrorDetailsPanel();
|
|
||||||
detailsButton = new JButton(isShowingDetails ? CLOSE : DETAIL);
|
detailsButton = new JButton(isShowingDetails ? CLOSE : DETAIL);
|
||||||
detailsButton.addActionListener(e -> {
|
detailsButton.addActionListener(e -> {
|
||||||
String label = detailsButton.getText();
|
String label = detailsButton.getText();
|
||||||
showDetails(label.equals(DETAIL));
|
showDetails(label.equals(DETAIL));
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isException) {
|
detailsPane = new ErrorDetailsSplitPane();
|
||||||
detailsPanel.setExceptionMessage(details);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
detailsPanel.setLogMessage(details);
|
|
||||||
}
|
|
||||||
|
|
||||||
JPanel buttonPanel = new JPanel(new GridLayout(2, 1, 5, 5));
|
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 5, 5));
|
||||||
buttonPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
buttonPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||||
if (errorReporter != null) {
|
if (errorReporter != null) {
|
||||||
buttonPanel.add(sendButton);
|
buttonPanel.add(sendButton);
|
||||||
|
@ -163,16 +178,16 @@ public class ErrLogDialog extends DialogComponentProvider {
|
||||||
buttonPanel.add(detailsButton);
|
buttonPanel.add(detailsButton);
|
||||||
|
|
||||||
introPanel.add(buttonPanel, BorderLayout.EAST);
|
introPanel.add(buttonPanel, BorderLayout.EAST);
|
||||||
mainPanel.add(detailsPanel, BorderLayout.CENTER);
|
mainPanel.add(detailsPane, BorderLayout.CENTER);
|
||||||
|
|
||||||
addWorkPanel(mainPanel);
|
addWorkPanel(mainPanel);
|
||||||
|
|
||||||
addOKButton();
|
addOKButton();
|
||||||
|
setDefaultButton(okButton);
|
||||||
|
|
||||||
// show the details panel if it was showing previously
|
// show the details panel if it was showing previously
|
||||||
detailsPanel.setVisible(isShowingDetails);
|
detailsPane.setVisible(isShowingDetails);
|
||||||
|
detailsPane.selectFirstError();
|
||||||
// setHelpLocation(new HelpLocation(HelpTopics.INTRO, "Err"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -185,82 +200,69 @@ public class ErrLogDialog extends DialogComponentProvider {
|
||||||
cancelCallback();
|
cancelCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Send error details from dialog.
|
|
||||||
*/
|
|
||||||
private void sendDetails() {
|
private void sendDetails() {
|
||||||
String details = detailsPanel.getDetails();
|
String details = detailsPane.getDetails();
|
||||||
String title = getTitle();
|
String title = getTitle();
|
||||||
close();
|
close();
|
||||||
errorReporter.report(rootPanel, title, details);
|
errorReporter.report(rootPanel, title, details);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* opens and closes the details panel; used also by Err when
|
|
||||||
* showLog is called from SessionGui Help menu to show details
|
|
||||||
* when visible
|
|
||||||
*/
|
|
||||||
private void showDetails(boolean visible) {
|
private void showDetails(boolean visible) {
|
||||||
isShowingDetails = visible;
|
isShowingDetails = visible;
|
||||||
String label = (visible ? CLOSE : DETAIL);
|
String label = (visible ? CLOSE : DETAIL);
|
||||||
detailsButton.setText(label);
|
detailsButton.setText(label);
|
||||||
detailsPanel.setVisible(visible);
|
detailsPane.setVisible(visible);
|
||||||
repack(); // need to re-pack so the detailsPanel can be hidden correctly
|
repack(); // need to re-pack so the detailsPanel can be hidden correctly
|
||||||
}
|
}
|
||||||
|
|
||||||
// custom "pack" so the detailsPanel can be shown/hidden correctly
|
|
||||||
@Override
|
@Override
|
||||||
protected void repack() {
|
public String getMessage() {
|
||||||
|
return detailsPane.getMessage();
|
||||||
// hide the dialog so that the user doesn't see us resize and then move it, which looks
|
|
||||||
// awkward
|
|
||||||
getDialog().setVisible(false);
|
|
||||||
|
|
||||||
detailsPanel.invalidate(); // force to be invalid so resizes correctly
|
|
||||||
rootPanel.validate();
|
|
||||||
|
|
||||||
super.repack();
|
|
||||||
|
|
||||||
// center the dialog after its size changes for a cleaner appearance
|
|
||||||
DockingDialog dialog = getDialog();
|
|
||||||
Container parent = dialog.getParent();
|
|
||||||
Point centerPoint = WindowUtilities.centerOnComponent(parent, dialog);
|
|
||||||
dialog.setLocation(centerPoint);
|
|
||||||
|
|
||||||
getDialog().setVisible(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void dialogShown() {
|
protected void dialogShown() {
|
||||||
|
|
||||||
// TODO test that the parent DockingDialog code handles this....
|
|
||||||
WindowUtilities.ensureOnScreen(getDialog());
|
WindowUtilities.ensureOnScreen(getDialog());
|
||||||
|
Swing.runLater(() -> okButton.requestFocusInWindow());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* scrolled text panel used to display the error message details;
|
void addException(String message, Throwable t) {
|
||||||
* each time an error message is "added", appends the contents to
|
|
||||||
* the internal StringBuffer.
|
int n = errors.size();
|
||||||
*/
|
if (n > MAX_EXCEPTIONS) {
|
||||||
private class ErrorDetailsPanel extends JPanel {
|
return;
|
||||||
private ScrollableTextArea textDetails;
|
}
|
||||||
private StringBuffer errorDetailsBuffer;
|
|
||||||
private Dimension closedSize;
|
errors.add(new ErrorEntry(message, t));
|
||||||
|
|
||||||
|
detailsPane.update();
|
||||||
|
|
||||||
|
updateTitle(); // signal the new error
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
int getExceptionCount() {
|
||||||
|
return errors.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ErrorDetailsSplitPane extends JSplitPane {
|
||||||
|
|
||||||
|
private final double TOP_PREFERRED_RESIZE_WEIGHT = .80;
|
||||||
|
private ErrorDetailsPanel detailsPanel;
|
||||||
|
private ErrorDetailsTablePanel tablePanel;
|
||||||
|
|
||||||
private Dimension openedSize;
|
private Dimension openedSize;
|
||||||
|
|
||||||
private ErrorDetailsPanel() {
|
ErrorDetailsSplitPane() {
|
||||||
super(new BorderLayout(0, 0));
|
super(VERTICAL_SPLIT);
|
||||||
errorDetailsBuffer = new StringBuffer(ERROR_BUFFER_SIZE);
|
setResizeWeight(TOP_PREFERRED_RESIZE_WEIGHT);
|
||||||
textDetails = new ScrollableTextArea(TEXT_ROWS, TEXT_COLUMNS);
|
|
||||||
textDetails.setEditable(false);
|
|
||||||
add(textDetails, BorderLayout.CENTER);
|
|
||||||
validate();
|
|
||||||
textDetails.scrollToBottom();
|
|
||||||
|
|
||||||
// set the initial preferred size of this panel
|
detailsPanel = new ErrorDetailsPanel();
|
||||||
// when "closed"
|
tablePanel = new ErrorDetailsTablePanel();
|
||||||
Rectangle bounds = getBounds();
|
|
||||||
closedSize = new Dimension(bounds.width, 0);
|
setTopComponent(detailsPanel);
|
||||||
|
setBottomComponent(tablePanel);
|
||||||
|
|
||||||
addComponentListener(new ComponentAdapter() {
|
addComponentListener(new ComponentAdapter() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -269,51 +271,283 @@ public class ErrLogDialog extends DialogComponentProvider {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Rectangle localBounds = getBounds();
|
Rectangle localBounds = getBounds();
|
||||||
if (detailsButton.getText().equals(DETAIL)) {
|
if (!detailsButton.getText().equals(DETAIL)) {
|
||||||
closedSize.width = localBounds.width;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
openedSize = new Dimension(localBounds.width, localBounds.height);
|
openedSize = new Dimension(localBounds.width, localBounds.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void selectFirstError() {
|
||||||
|
tablePanel.selectFirstError();
|
||||||
|
}
|
||||||
|
|
||||||
|
String getDetails() {
|
||||||
|
return detailsPanel.getDetails();
|
||||||
|
}
|
||||||
|
|
||||||
|
String getMessage() {
|
||||||
|
return detailsPanel.getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setError(ErrorEntry err) {
|
||||||
|
detailsPanel.setError(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
void update() {
|
||||||
|
tablePanel.update();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dimension getPreferredSize() {
|
public Dimension getPreferredSize() {
|
||||||
|
Dimension superSize = super.getPreferredSize();
|
||||||
if (detailsButton.getText().equals(DETAIL)) {
|
if (detailsButton.getText().equals(DETAIL)) {
|
||||||
return closedSize;
|
return superSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (openedSize == null) {
|
if (openedSize == null) {
|
||||||
return super.getPreferredSize();
|
return superSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
return openedSize;
|
return openedSize;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ErrorDetailsTablePanel extends JPanel {
|
||||||
|
|
||||||
|
private ErrEntryTableModel model;
|
||||||
|
private GTable errorsTable;
|
||||||
|
private GTableFilterPanel<ErrorEntry> tableFilterPanel;
|
||||||
|
|
||||||
|
ErrorDetailsTablePanel() {
|
||||||
|
setLayout(new BorderLayout());
|
||||||
|
model = new ErrEntryTableModel();
|
||||||
|
errorsTable = new GTable(model);
|
||||||
|
tableFilterPanel = new GTableFilterPanel<ErrorEntry>(errorsTable, model);
|
||||||
|
|
||||||
|
errorsTable.getSelectionManager().addListSelectionListener(e -> {
|
||||||
|
if (e.getValueIsAdjusting()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int firstIndex = errorsTable.getSelectedRow();
|
||||||
|
if (firstIndex == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ErrorEntry err = tableFilterPanel.getRowObject(firstIndex);
|
||||||
|
detailsPane.setError(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
JPanel tablePanel = new JPanel(new BorderLayout());
|
||||||
|
tablePanel.add(new JScrollPane(errorsTable), BorderLayout.CENTER);
|
||||||
|
tablePanel.add(tableFilterPanel, BorderLayout.SOUTH);
|
||||||
|
|
||||||
|
add(tablePanel, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
// initialize this value to something small so the full dialog will not consume the
|
||||||
|
// entire screen height
|
||||||
|
setPreferredSize(new Dimension(400, 100));
|
||||||
|
}
|
||||||
|
|
||||||
|
void selectFirstError() {
|
||||||
|
errorsTable.selectRow(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void update() {
|
||||||
|
model.fireTableDataChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* resets the current error buffer to the contents of msg
|
* scrolled text panel used to display the error message details;
|
||||||
|
* each time an error message is "added", appends the contents to
|
||||||
|
* the internal StringBuffer.
|
||||||
*/
|
*/
|
||||||
private void setLogMessage(String msg) {
|
private class ErrorDetailsPanel extends JPanel {
|
||||||
errorDetailsBuffer = new StringBuffer(msg);
|
|
||||||
textDetails.setText(msg);
|
|
||||||
|
|
||||||
// scroll to bottom so user is viewing the last message
|
private ScrollableTextArea textDetails;
|
||||||
|
private ErrorEntry error;
|
||||||
|
|
||||||
|
private ErrorDetailsPanel() {
|
||||||
|
super(new BorderLayout(0, 0));
|
||||||
|
textDetails = new ScrollableTextArea(TEXT_ROWS, TEXT_COLUMNS);
|
||||||
|
textDetails.setEditable(false);
|
||||||
|
|
||||||
|
add(textDetails, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
validate();
|
||||||
textDetails.scrollToBottom();
|
textDetails.scrollToBottom();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setExceptionMessage(String msg) {
|
void setError(ErrorEntry e) {
|
||||||
errorDetailsBuffer = new StringBuffer(msg);
|
error = e;
|
||||||
textDetails.setText(msg);
|
setExceptionMessage(e.getDetailsText());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setExceptionMessage(String message) {
|
||||||
|
|
||||||
|
String updated = addUsefulReportingInfo(message);
|
||||||
|
textDetails.setText(updated);
|
||||||
|
|
||||||
// scroll to the top the see the pertinent part of the exception
|
// scroll to the top the see the pertinent part of the exception
|
||||||
textDetails.scrollToTop();
|
textDetails.scrollToTop();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final String getDetails() {
|
String getDetails() {
|
||||||
return errorDetailsBuffer.toString();
|
return textDetails.getText();
|
||||||
|
}
|
||||||
|
|
||||||
|
String getMessage() {
|
||||||
|
return error.getMessage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class ErrorEntry {
|
||||||
|
|
||||||
|
private String message;
|
||||||
|
private String details;
|
||||||
|
private Date timestamp = new Date();
|
||||||
|
private int myId = ++errorId;
|
||||||
|
|
||||||
|
ErrorEntry(String message, Throwable t) {
|
||||||
|
String updated = message;
|
||||||
|
if (HTMLUtilities.isHTML(updated)) {
|
||||||
|
updated = HTMLUtilities.fromHTML(updated);
|
||||||
|
}
|
||||||
|
this.message = updated;
|
||||||
|
|
||||||
|
if (t != null) {
|
||||||
|
this.details = ReflectionUtilities.stackTraceToString(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int getId() {
|
||||||
|
return myId;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
Date getTimestamp() {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getDetailsText() {
|
||||||
|
if (details == null) {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
return details;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getDetails() {
|
||||||
|
return details;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return Json.toString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ErrEntryTableModel extends GDynamicColumnTableModel<ErrorEntry, Object> {
|
||||||
|
|
||||||
|
public ErrEntryTableModel() {
|
||||||
|
super(new ServiceProviderStub());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TableColumnDescriptor<ErrorEntry> createTableColumnDescriptor() {
|
||||||
|
TableColumnDescriptor<ErrorEntry> descriptor = new TableColumnDescriptor<ErrorEntry>();
|
||||||
|
descriptor.addVisibleColumn(new IdColumn(), 1, true);
|
||||||
|
descriptor.addVisibleColumn(new MessageColumn());
|
||||||
|
descriptor.addHiddenColumn(new DetailsColumn());
|
||||||
|
descriptor.addVisibleColumn(new TimestampColumn());
|
||||||
|
return descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Unexpectd Errors";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ErrorEntry> getModelData() {
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getDataSource() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class IdColumn extends AbstractDynamicTableColumnStub<ErrorEntry, Integer> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getValue(ErrorEntry rowObject, Settings settings, ServiceProvider sp)
|
||||||
|
throws IllegalArgumentException {
|
||||||
|
return rowObject.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getColumnName() {
|
||||||
|
return "#";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getColumnPreferredWidth() {
|
||||||
|
return 40;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class MessageColumn extends AbstractDynamicTableColumnStub<ErrorEntry, String> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getValue(ErrorEntry rowObject, Settings settings, ServiceProvider sp)
|
||||||
|
throws IllegalArgumentException {
|
||||||
|
return rowObject.getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getColumnName() {
|
||||||
|
return "Message";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DetailsColumn extends AbstractDynamicTableColumnStub<ErrorEntry, String> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getValue(ErrorEntry rowObject, Settings settings, ServiceProvider sp)
|
||||||
|
throws IllegalArgumentException {
|
||||||
|
return rowObject.getDetails();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getColumnName() {
|
||||||
|
return "Details";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TimestampColumn extends AbstractDynamicTableColumnStub<ErrorEntry, Date> {
|
||||||
|
|
||||||
|
private GColumnRenderer<Date> renderer = new DefaultTimestampRenderer();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Date getValue(ErrorEntry rowObject, Settings settings, ServiceProvider sp)
|
||||||
|
throws IllegalArgumentException {
|
||||||
|
return rowObject.getTimestamp();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getColumnName() {
|
||||||
|
return "Time";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GColumnRenderer<Date> getColumnRenderer() {
|
||||||
|
return renderer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,12 +32,12 @@ import docking.widgets.label.GHtmlLabel;
|
||||||
import docking.widgets.tree.*;
|
import docking.widgets.tree.*;
|
||||||
import docking.widgets.tree.support.GTreeDragNDropHandler;
|
import docking.widgets.tree.support.GTreeDragNDropHandler;
|
||||||
import ghidra.util.*;
|
import ghidra.util.*;
|
||||||
import ghidra.util.exception.*;
|
import ghidra.util.exception.MultipleCauses;
|
||||||
import ghidra.util.html.HTMLElement;
|
import ghidra.util.html.HTMLElement;
|
||||||
import resources.ResourceManager;
|
import resources.ResourceManager;
|
||||||
import util.CollectionUtils;
|
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_REPORT = ResourceManager.loadImage("images/report.png");
|
||||||
public static ImageIcon IMG_EXCEPTION = ResourceManager.loadImage("images/exception.png");
|
public static ImageIcon IMG_EXCEPTION = ResourceManager.loadImage("images/exception.png");
|
||||||
public static ImageIcon IMG_FRAME_ELEMENT =
|
public static ImageIcon IMG_FRAME_ELEMENT =
|
||||||
|
@ -53,113 +53,21 @@ public class ErrLogExpandableDialog extends DialogComponentProvider {
|
||||||
private static boolean showingDetails = false;
|
private static boolean showingDetails = false;
|
||||||
|
|
||||||
protected ReportRootNode root;
|
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 */
|
/** This spacer addresses the optical impression that the message panel changes size when showing details */
|
||||||
protected Component horizontalSpacer;
|
protected Component horizontalSpacer;
|
||||||
protected JButton detailButton;
|
protected JButton detailButton;
|
||||||
protected JButton sendButton;
|
protected JButton sendButton;
|
||||||
protected boolean hasConsole = false;
|
|
||||||
|
|
||||||
protected JPopupMenu popup;
|
protected JPopupMenu popup;
|
||||||
|
|
||||||
protected static class ExcTreeTransferHandler extends TransferHandler
|
protected ErrLogExpandableDialog(String title, String msg, Throwable throwable) {
|
||||||
implements GTreeDragNDropHandler {
|
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();
|
popup = new JPopupMenu();
|
||||||
JMenuItem menuCopy = new JMenuItem("Copy");
|
JMenuItem menuCopy = new JMenuItem("Copy");
|
||||||
menuCopy.setActionCommand((String) TransferHandler.getCopyAction().getValue(Action.NAME));
|
menuCopy.setActionCommand((String) TransferHandler.getCopyAction().getValue(Action.NAME));
|
||||||
|
@ -173,13 +81,12 @@ public class ErrLogExpandableDialog extends DialogComponentProvider {
|
||||||
msgPanel.setLayout(new BorderLayout(16, 16));
|
msgPanel.setLayout(new BorderLayout(16, 16));
|
||||||
msgPanel.setBorder(new EmptyBorder(16, 16, 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
|
@Override
|
||||||
public Dimension getPreferredSize() {
|
public Dimension getPreferredSize() {
|
||||||
// when rendering HTML the label can expand larger than the screen;
|
// rendering HTML the label can expand larger than the screen; keep it reasonable
|
||||||
// keep it reasonable
|
|
||||||
Dimension size = super.getPreferredSize();
|
Dimension size = super.getPreferredSize();
|
||||||
size.width = 500;
|
size.width = 300;
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -206,7 +113,7 @@ public class ErrLogExpandableDialog extends DialogComponentProvider {
|
||||||
msgPanel.add(buttonBox, BorderLayout.EAST);
|
msgPanel.add(buttonBox, BorderLayout.EAST);
|
||||||
|
|
||||||
horizontalSpacer = Box.createVerticalStrut(10);
|
horizontalSpacer = Box.createVerticalStrut(10);
|
||||||
horizontalSpacer.setVisible(showingDetails | hasConsole);
|
horizontalSpacer.setVisible(showingDetails);
|
||||||
msgPanel.add(horizontalSpacer, BorderLayout.SOUTH);
|
msgPanel.add(horizontalSpacer, BorderLayout.SOUTH);
|
||||||
}
|
}
|
||||||
workPanel.add(msgPanel, BorderLayout.NORTH);
|
workPanel.add(msgPanel, BorderLayout.NORTH);
|
||||||
|
@ -214,29 +121,8 @@ public class ErrLogExpandableDialog extends DialogComponentProvider {
|
||||||
Box workBox = Box.createVerticalBox();
|
Box workBox = Box.createVerticalBox();
|
||||||
{
|
{
|
||||||
|
|
||||||
if (hasConsole) {
|
root = new ReportRootNode(getTitle(), CollectionUtils.asSet(throwable));
|
||||||
JTextArea consoleText = new JTextArea(console);
|
tree = new GTree(root) {
|
||||||
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) {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dimension getPreferredSize() {
|
public Dimension getPreferredSize() {
|
||||||
|
@ -249,19 +135,19 @@ public class ErrLogExpandableDialog extends DialogComponentProvider {
|
||||||
|
|
||||||
for (GTreeNode node : CollectionUtils.asIterable(root.iterator(true))) {
|
for (GTreeNode node : CollectionUtils.asIterable(root.iterator(true))) {
|
||||||
if (node instanceof ReportExceptionNode) {
|
if (node instanceof ReportExceptionNode) {
|
||||||
excTree.expandTree(node);
|
tree.expandTree(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
excTree.setSelectedNode(root.getChild(0));
|
tree.setSelectedNode(root.getChild(0));
|
||||||
excTree.setVisible(showingDetails);
|
tree.setVisible(showingDetails);
|
||||||
ExcTreeTransferHandler handler = new ExcTreeTransferHandler(root);
|
ExcTreeTransferHandler handler = new ExcTreeTransferHandler(root);
|
||||||
excTree.setDragNDropHandler(handler);
|
tree.setDragNDropHandler(handler);
|
||||||
excTree.setTransferHandler(handler);
|
tree.setTransferHandler(handler);
|
||||||
ActionMap map = excTree.getActionMap();
|
ActionMap map = tree.getActionMap();
|
||||||
map.put(TransferHandler.getCopyAction().getValue(Action.NAME),
|
map.put(TransferHandler.getCopyAction().getValue(Action.NAME),
|
||||||
TransferHandler.getCopyAction());
|
TransferHandler.getCopyAction());
|
||||||
excTree.addMouseListener(new MouseAdapter() {
|
tree.addMouseListener(new MouseAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void mousePressed(MouseEvent e) {
|
public void mousePressed(MouseEvent e) {
|
||||||
maybeShowPopup(e);
|
maybeShowPopup(e);
|
||||||
|
@ -279,22 +165,19 @@ public class ErrLogExpandableDialog extends DialogComponentProvider {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
workBox.add(excTree);
|
workBox.add(tree);
|
||||||
}
|
}
|
||||||
workPanel.add(workBox, BorderLayout.CENTER);
|
workPanel.add(workBox, BorderLayout.CENTER);
|
||||||
repack();
|
repack();
|
||||||
|
|
||||||
addWorkPanel(workPanel);
|
addWorkPanel(workPanel);
|
||||||
|
|
||||||
if (hasDismiss) {
|
|
||||||
addDismissButton();
|
addDismissButton();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private String getHTML(String msg, Collection<Throwable> report) {
|
private String getHTML(String msg, Collection<Throwable> report) {
|
||||||
|
|
||||||
//
|
//
|
||||||
// TODO
|
|
||||||
// Usage question: The content herein will be escaped unless you call addHTMLContenet().
|
// Usage question: The content herein will be escaped unless you call addHTMLContenet().
|
||||||
// Further, clients can provide messages that contain HTML. Is there a
|
// Further, clients can provide messages that contain HTML. Is there a
|
||||||
// use case where we want to show escaped HTML content?
|
// use case where we want to show escaped HTML content?
|
||||||
|
@ -332,14 +215,6 @@ public class ErrLogExpandableDialog extends DialogComponentProvider {
|
||||||
|
|
||||||
String htmlTMsg = addBR(tMsg);
|
String htmlTMsg = addBR(tMsg);
|
||||||
body.addElement("p").addHTMLContent(htmlTMsg);
|
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();
|
return html.toString();
|
||||||
}
|
}
|
||||||
|
@ -357,15 +232,15 @@ public class ErrLogExpandableDialog extends DialogComponentProvider {
|
||||||
return t.getClass().getSimpleName();
|
return t.getClass().getSimpleName();
|
||||||
}
|
}
|
||||||
|
|
||||||
void detailCallback() {
|
private void detailCallback() {
|
||||||
showingDetails = !showingDetails;
|
showingDetails = !showingDetails;
|
||||||
excTree.setVisible(showingDetails);
|
tree.setVisible(showingDetails);
|
||||||
horizontalSpacer.setVisible(showingDetails | hasConsole);
|
horizontalSpacer.setVisible(showingDetails);
|
||||||
detailButton.setText(showingDetails ? CLOSE : DETAIL);
|
detailButton.setText(showingDetails ? CLOSE : DETAIL);
|
||||||
repack();
|
repack();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendCallback() {
|
private void sendCallback() {
|
||||||
String details = root.collectReportText(null, 0).trim();
|
String details = root.collectReportText(null, 0).trim();
|
||||||
String title = getTitle();
|
String title = getTitle();
|
||||||
close();
|
close();
|
||||||
|
@ -379,6 +254,29 @@ public class ErrLogExpandableDialog extends DialogComponentProvider {
|
||||||
return dim;
|
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 {
|
static interface NodeWithText {
|
||||||
public String getReportText();
|
public String getReportText();
|
||||||
|
|
||||||
|
@ -528,9 +426,6 @@ public class ErrLogExpandableDialog extends DialogComponentProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getReportText() {
|
public String getReportText() {
|
||||||
if (exc instanceof HasConsoleText) {
|
|
||||||
return getName() + "\n" + HasConsoleText.Util.get(exc);
|
|
||||||
}
|
|
||||||
return getName();
|
return getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -661,6 +556,87 @@ public class ErrLogExpandableDialog extends DialogComponentProvider {
|
||||||
return false;
|
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 {
|
class TransferActionListener implements ActionListener, PropertyChangeListener {
|
||||||
|
|
|
@ -15,78 +15,29 @@
|
||||||
*/
|
*/
|
||||||
package docking.test;
|
package docking.test;
|
||||||
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.*;
|
||||||
import static org.junit.Assert.fail;
|
|
||||||
|
|
||||||
import java.awt.AWTEvent;
|
import java.awt.*;
|
||||||
import java.awt.AWTException;
|
import java.awt.datatransfer.*;
|
||||||
import java.awt.Component;
|
import java.awt.event.*;
|
||||||
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.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
import java.util.*;
|
||||||
import java.util.ConcurrentModificationException;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.swing.AbstractButton;
|
import javax.swing.*;
|
||||||
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.text.JTextComponent;
|
import javax.swing.text.JTextComponent;
|
||||||
|
|
||||||
import org.apache.commons.io.FilenameUtils;
|
import org.apache.commons.io.FilenameUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.junit.After;
|
import org.junit.*;
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Before;
|
|
||||||
|
|
||||||
import docking.ActionContext;
|
import docking.*;
|
||||||
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.action.DockingActionIf;
|
import docking.action.DockingActionIf;
|
||||||
import docking.action.ToggleDockingActionIf;
|
import docking.action.ToggleDockingActionIf;
|
||||||
import docking.actions.DockingToolActions;
|
import docking.actions.DockingToolActions;
|
||||||
|
@ -104,9 +55,7 @@ import generic.test.ConcurrentTestExceptionHandler;
|
||||||
import generic.util.image.ImageUtils;
|
import generic.util.image.ImageUtils;
|
||||||
import ghidra.GhidraTestApplicationLayout;
|
import ghidra.GhidraTestApplicationLayout;
|
||||||
import ghidra.framework.ApplicationConfiguration;
|
import ghidra.framework.ApplicationConfiguration;
|
||||||
import ghidra.util.ConsoleErrorDisplay;
|
import ghidra.util.*;
|
||||||
import ghidra.util.ErrorDisplay;
|
|
||||||
import ghidra.util.Msg;
|
|
||||||
import ghidra.util.exception.AssertException;
|
import ghidra.util.exception.AssertException;
|
||||||
import ghidra.util.task.SwingUpdateManager;
|
import ghidra.util.task.SwingUpdateManager;
|
||||||
import ghidra.util.worker.Worker;
|
import ghidra.util.worker.Worker;
|
||||||
|
@ -209,7 +158,7 @@ public abstract class AbstractDockingTest extends AbstractGenericTest {
|
||||||
Iterator<Window> iter = winList.iterator();
|
Iterator<Window> iter = winList.iterator();
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
Window w = iter.next();
|
Window w = iter.next();
|
||||||
if (!w.isVisible()) {
|
if (!w.isShowing()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
String titleForWindow = getTitleForWindow(w);
|
String titleForWindow = getTitleForWindow(w);
|
||||||
|
@ -229,7 +178,7 @@ public abstract class AbstractDockingTest extends AbstractGenericTest {
|
||||||
Iterator<Window> iter = winList.iterator();
|
Iterator<Window> iter = winList.iterator();
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
Window w = iter.next();
|
Window w = iter.next();
|
||||||
if (!w.isVisible()) {
|
if (!w.isShowing()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
String titleForWindow = getTitleForWindow(w);
|
String titleForWindow = getTitleForWindow(w);
|
||||||
|
@ -240,6 +189,14 @@ public abstract class AbstractDockingTest extends AbstractGenericTest {
|
||||||
return null;
|
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) {
|
public static Window waitForWindow(Class<?> windowClass) {
|
||||||
|
|
||||||
if ((!Dialog.class.isAssignableFrom(windowClass)) &&
|
if ((!Dialog.class.isAssignableFrom(windowClass)) &&
|
||||||
|
@ -256,7 +213,7 @@ public abstract class AbstractDockingTest extends AbstractGenericTest {
|
||||||
Iterator<Window> it = winList.iterator();
|
Iterator<Window> it = winList.iterator();
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
Window w = it.next();
|
Window w = it.next();
|
||||||
if (windowClass.isAssignableFrom(w.getClass()) && w.isVisible()) {
|
if (windowClass.isAssignableFrom(w.getClass()) && w.isShowing()) {
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -346,7 +303,7 @@ public abstract class AbstractDockingTest extends AbstractGenericTest {
|
||||||
Set<Window> allWindows = getAllWindows();
|
Set<Window> allWindows = getAllWindows();
|
||||||
for (Window window : allWindows) {
|
for (Window window : allWindows) {
|
||||||
String windowName = window.getName();
|
String windowName = window.getName();
|
||||||
if (name.equals(windowName) && window.isVisible()) {
|
if (name.equals(windowName) && window.isShowing()) {
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,13 +315,12 @@ public abstract class AbstractDockingTest extends AbstractGenericTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check for and display message component text associated with
|
* Check for and display message component text associated with OptionDialog windows
|
||||||
* ErrLogDialog and OptionDialog windows.
|
|
||||||
* @param w any window
|
* @param w any window
|
||||||
* @return the message string if one can be found; <code>null</code> otherwise
|
* @return the message string if one can be found; <code>null</code> otherwise
|
||||||
*/
|
*/
|
||||||
public static String checkMessageDisplay(Window w) {
|
public static String getMessageText(Window w) {
|
||||||
Component c = findComponentByName(w, "MESSAGE-COMPONENT");
|
Component c = findComponentByName(w, OptionDialog.MESSAGE_COMPONENT_NAME);
|
||||||
if (c instanceof JLabel) {
|
if (c instanceof JLabel) {
|
||||||
return ((JLabel) c).getText();
|
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
|
// note: we use System.err here to get more obvious errors in the console
|
||||||
String title = getDebugTitleForWindow(window);
|
String title = getDebugTitleForWindow(window);
|
||||||
System.err.println("DockingTestCase - Forced window closure: " + title);
|
System.err.println("DockingTestCase - Forced window closure: " + title);
|
||||||
String errorMessage = checkMessageDisplay(window);
|
String errorMessage = getMessageText(window);
|
||||||
if (errorMessage != null) {
|
if (errorMessage != null) {
|
||||||
System.err.println("\tWindow error message: " + errorMessage);
|
System.err.println("\tWindow error message: " + errorMessage);
|
||||||
}
|
}
|
||||||
|
@ -541,7 +497,7 @@ public abstract class AbstractDockingTest extends AbstractGenericTest {
|
||||||
Iterator<Window> iter = winList.iterator();
|
Iterator<Window> iter = winList.iterator();
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
Window w = iter.next();
|
Window w = iter.next();
|
||||||
if ((w instanceof JDialog) && w.isVisible()) {
|
if ((w instanceof JDialog) && w.isShowing()) {
|
||||||
String windowTitle = getTitleForWindow(w);
|
String windowTitle = getTitleForWindow(w);
|
||||||
if (title.equals(windowTitle)) {
|
if (title.equals(windowTitle)) {
|
||||||
return (JDialog) w;
|
return (JDialog) w;
|
||||||
|
@ -576,7 +532,7 @@ public abstract class AbstractDockingTest extends AbstractGenericTest {
|
||||||
Iterator<Window> iter = winList.iterator();
|
Iterator<Window> iter = winList.iterator();
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
Window w = iter.next();
|
Window w = iter.next();
|
||||||
if ((w instanceof JDialog) && w.isVisible()) {
|
if ((w instanceof JDialog) && w.isShowing()) {
|
||||||
String windowTitle = getTitleForWindow(w);
|
String windowTitle = getTitleForWindow(w);
|
||||||
if (title.equals(windowTitle)) {
|
if (title.equals(windowTitle)) {
|
||||||
return (JDialog) w;
|
return (JDialog) w;
|
||||||
|
@ -722,10 +678,6 @@ public abstract class AbstractDockingTest extends AbstractGenericTest {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!window.isVisible()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!window.isShowing()) {
|
if (!window.isShowing()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1132,7 +1084,9 @@ public abstract class AbstractDockingTest extends AbstractGenericTest {
|
||||||
public static Set<DockingActionIf> getActionsByOwnerAndName(Tool tool, String owner,
|
public static Set<DockingActionIf> getActionsByOwnerAndName(Tool tool, String owner,
|
||||||
String name) {
|
String name) {
|
||||||
Set<DockingActionIf> ownerActions = tool.getDockingActionsByOwnerName(owner);
|
Set<DockingActionIf> ownerActions = tool.getDockingActionsByOwnerName(owner);
|
||||||
return ownerActions.stream().filter(action -> action.getName().equals(name)).collect(
|
return ownerActions.stream()
|
||||||
|
.filter(action -> action.getName().equals(name))
|
||||||
|
.collect(
|
||||||
Collectors.toSet());
|
Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,7 @@ import ghidra.util.exception.AssertException;
|
||||||
* @see OptionDialogBuilder
|
* @see OptionDialogBuilder
|
||||||
*/
|
*/
|
||||||
public class OptionDialog extends DialogComponentProvider {
|
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. */
|
/** Used for error messages. */
|
||||||
public static final int ERROR_MESSAGE = 0;
|
public static final int ERROR_MESSAGE = 0;
|
||||||
/** Used for information messages. */
|
/** 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.
|
* @param text the text to append.
|
||||||
*/
|
*/
|
||||||
public void append(String text) {
|
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
|
* Returns the number of lines current set in the text area
|
||||||
|
* @return the count
|
||||||
*/
|
*/
|
||||||
public int getLineCount() {
|
public int getLineCount() {
|
||||||
return textArea.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() {
|
public int getTabSize() {
|
||||||
return textArea.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)
|
* Returns the total area height of the text area (row height * line count)
|
||||||
|
* @return the height
|
||||||
*/
|
*/
|
||||||
public int getTextAreaHeight() {
|
public int getTextAreaHeight() {
|
||||||
return (textArea.getAreaHeight());
|
return (textArea.getAreaHeight());
|
||||||
|
@ -132,6 +135,7 @@ public class ScrollableTextArea extends JScrollPane {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the visible height of the text area
|
* Returns the visible height of the text area
|
||||||
|
* @return the height
|
||||||
*/
|
*/
|
||||||
public int getTextVisibleHeight() {
|
public int getTextVisibleHeight() {
|
||||||
return textArea.getVisibleHeight();
|
return textArea.getVisibleHeight();
|
||||||
|
@ -200,6 +204,7 @@ public class ScrollableTextArea extends JScrollPane {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the text contained within the text area
|
* Returns the text contained within the text area
|
||||||
|
* @return the text
|
||||||
*/
|
*/
|
||||||
public String getText() {
|
public String getText() {
|
||||||
return textArea.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();
|
DockingErrorDisplay display = new DockingErrorDisplay();
|
||||||
DefaultErrorLogger logger = new DefaultErrorLogger();
|
DefaultErrorLogger logger = new DefaultErrorLogger();
|
||||||
Exception exception = new Exception("My test exception");
|
Exception exception = new Exception("My test exception");
|
||||||
doDisplay(display, logger, exception);
|
reportException(display, logger, exception);
|
||||||
|
|
||||||
assertErrLogDialog();
|
assertErrLogDialog();
|
||||||
}
|
}
|
||||||
|
@ -46,11 +46,29 @@ public class DockingErrorDisplayTest extends AbstractDockingTest {
|
||||||
DefaultErrorLogger logger = new DefaultErrorLogger();
|
DefaultErrorLogger logger = new DefaultErrorLogger();
|
||||||
Exception nestedException = new Exception("My nested test exception");
|
Exception nestedException = new Exception("My nested test exception");
|
||||||
Exception exception = new Exception("My test exception", nestedException);
|
Exception exception = new Exception("My test exception", nestedException);
|
||||||
doDisplay(display, logger, exception);
|
reportException(display, logger, exception);
|
||||||
|
|
||||||
assertErrLogDialog();
|
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
|
@Test
|
||||||
public void testMultipleCausesErrorDisplay() {
|
public void testMultipleCausesErrorDisplay() {
|
||||||
DockingErrorDisplay display = new DockingErrorDisplay();
|
DockingErrorDisplay display = new DockingErrorDisplay();
|
||||||
|
@ -58,43 +76,51 @@ public class DockingErrorDisplayTest extends AbstractDockingTest {
|
||||||
|
|
||||||
Throwable firstCause = new Exception("My test exception - first cause");
|
Throwable firstCause = new Exception("My test exception - first cause");
|
||||||
MultipleCauses exception = new MultipleCauses(Collections.singletonList(firstCause));
|
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() {
|
private void assertExceptionCount(AbstractErrDialog errDialog, int n) {
|
||||||
Window w = waitForWindow(TEST_TITLE, 2000);
|
|
||||||
assertNotNull(w);
|
|
||||||
|
|
||||||
final ErrLogExpandableDialog errDialog =
|
int actual = errDialog.getExceptionCount();
|
||||||
|
assertEquals(n, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ErrLogExpandableDialog assertErrLogExpandableDialog() {
|
||||||
|
Window w = waitForWindow(TEST_TITLE);
|
||||||
|
|
||||||
|
ErrLogExpandableDialog errDialog =
|
||||||
getDialogComponentProvider(w, ErrLogExpandableDialog.class);
|
getDialogComponentProvider(w, ErrLogExpandableDialog.class);
|
||||||
assertNotNull(errDialog);
|
assertNotNull(errDialog);
|
||||||
|
return errDialog;
|
||||||
runSwing(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
errDialog.close();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertErrLogDialog() {
|
private void assertErrLogDialog() {
|
||||||
Window w = waitForWindow(TEST_TITLE, 2000);
|
Window w = waitForWindow(TEST_TITLE);
|
||||||
assertNotNull(w);
|
assertNotNull(w);
|
||||||
|
|
||||||
final ErrLogDialog errDialog = getDialogComponentProvider(w, ErrLogDialog.class);
|
ErrLogDialog errDialog = getDialogComponentProvider(w, ErrLogDialog.class);
|
||||||
assertNotNull(errDialog);
|
assertNotNull(errDialog);
|
||||||
|
close(errDialog);
|
||||||
runSwing(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
errDialog.close();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
final Throwable throwable) {
|
||||||
runSwing(new Runnable() {
|
runSwing(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1094,8 +1094,24 @@ public abstract class AbstractGenericTest extends AbstractGTest {
|
||||||
return ref.get();
|
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
|
* an exception
|
||||||
* @param runnable the runnable
|
* @param runnable the runnable
|
||||||
* @param wait true signals to wait for the Swing operation to finish
|
* @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 {
|
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;
|
protected DBHandle dbHandle;
|
||||||
private AddressMap addrMap;
|
private AddressMap addrMap;
|
||||||
private ErrorHandler errHandler;
|
private ErrorHandler errHandler = new DbErrorHandler();
|
||||||
private DataTypeConflictHandler currentHandler;
|
private DataTypeConflictHandler currentHandler;
|
||||||
|
|
||||||
private CategoryDB root;
|
private CategoryDB root;
|
||||||
|
@ -168,12 +168,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
|
||||||
*/
|
*/
|
||||||
protected DataTypeManagerDB() {
|
protected DataTypeManagerDB() {
|
||||||
this.lock = new Lock("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 {
|
try {
|
||||||
dbHandle = new DBHandle();
|
dbHandle = new DBHandle();
|
||||||
int id = startTransaction("");
|
int id = startTransaction("");
|
||||||
|
@ -213,13 +208,6 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
|
||||||
") for read-only Datatype Archive: " + packedDBfile.getAbsolutePath());
|
") 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
|
// Open packed database archive
|
||||||
boolean openSuccess = false;
|
boolean openSuccess = false;
|
||||||
PackedDatabase pdb = null;
|
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
|
* 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.
|
* via the console (no GUI). Also records the message to the logging system.
|
||||||
|
|
|
@ -499,14 +499,31 @@ public class ReflectionUtilities {
|
||||||
* @return the string
|
* @return the string
|
||||||
*/
|
*/
|
||||||
public static String stackTraceToString(Throwable t) {
|
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();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
PrintStream ps = new PrintStream(baos);
|
PrintStream ps = new PrintStream(baos);
|
||||||
|
|
||||||
String msg = t.getMessage();
|
if (message != null) {
|
||||||
if (msg != null) {
|
ps.println(message);
|
||||||
ps.println(msg);
|
}
|
||||||
|
else {
|
||||||
|
String throwableMessage = t.getMessage();
|
||||||
|
if (throwableMessage != null) {
|
||||||
|
ps.println(throwableMessage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
t.printStackTrace(ps);
|
t.printStackTrace(ps);
|
||||||
|
|
|
@ -55,8 +55,8 @@ public class IntroScreenShots extends GhidraScreenShotGenerator {
|
||||||
@Test
|
@Test
|
||||||
public void testErr_Dialog() {
|
public void testErr_Dialog() {
|
||||||
runSwing(() -> {
|
runSwing(() -> {
|
||||||
ErrLogDialog dialog = ErrLogDialog.createLogMessageDialog("Unexpected Error",
|
ErrLogDialog dialog = ErrLogDialog.createExceptionDialog("Unexpected Error",
|
||||||
"Oops, this is really bad!", "");
|
"Oops, this is really bad!", new Throwable());
|
||||||
DockingWindowManager.showDialog(null, dialog);
|
DockingWindowManager.showDialog(null, dialog);
|
||||||
}, false);
|
}, false);
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
|
|
|
@ -25,6 +25,7 @@ import javax.swing.tree.TreePath;
|
||||||
|
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
|
|
||||||
|
import docking.AbstractErrDialog;
|
||||||
import docking.ActionContext;
|
import docking.ActionContext;
|
||||||
import docking.action.DockingActionIf;
|
import docking.action.DockingActionIf;
|
||||||
import docking.widgets.MultiLineLabel;
|
import docking.widgets.MultiLineLabel;
|
||||||
|
@ -102,7 +103,7 @@ public class SetLanguageTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
@Test
|
@Test
|
||||||
public void testActionEnablement() throws Exception {
|
public void testActionEnablement() throws Exception {
|
||||||
assertTrue(setLanguageAction.isEnabled());
|
assertTrue(setLanguageAction.isEnabled());
|
||||||
assertTrue(!setLanguageAction.isEnabledForContext(createProjectDataContext(xyzFolderNode)));
|
assertFalse(setLanguageAction.isEnabledForContext(createProjectDataContext(xyzFolderNode)));
|
||||||
assertTrue(setLanguageAction.isEnabledForContext(createProjectDataContext(notepadNode)));
|
assertTrue(setLanguageAction.isEnabledForContext(createProjectDataContext(notepadNode)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +111,7 @@ public class SetLanguageTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
return addrFactory.getAddress(address);
|
return addrFactory.getAddress(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startSetLanguage(final LanguageID languageID, final CompilerSpecID compilerSpecID,
|
private void startSetLanguage(LanguageID languageID, CompilerSpecID compilerSpecID,
|
||||||
boolean isFailureCase) throws Exception {
|
boolean isFailureCase) throws Exception {
|
||||||
if (languageID == null) {
|
if (languageID == null) {
|
||||||
throw new RuntimeException("languageID == null not allowed");
|
throw new RuntimeException("languageID == null not allowed");
|
||||||
|
@ -135,9 +136,9 @@ public class SetLanguageTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
pressButtonByText(confirmDlg, "Ok");
|
pressButtonByText(confirmDlg, "Ok");
|
||||||
|
|
||||||
final SetLanguageDialog dlg = waitForDialogComponent(SetLanguageDialog.class);
|
SetLanguageDialog dlg = waitForDialogComponent(SetLanguageDialog.class);
|
||||||
assertNotNull(dlg);
|
assertNotNull(dlg);
|
||||||
final NewLanguagePanel languagePanel =
|
NewLanguagePanel languagePanel =
|
||||||
(NewLanguagePanel) getInstanceField("selectLangPanel", dlg);
|
(NewLanguagePanel) getInstanceField("selectLangPanel", dlg);
|
||||||
assertNotNull(languagePanel);
|
assertNotNull(languagePanel);
|
||||||
|
|
||||||
|
@ -174,7 +175,7 @@ public class SetLanguageTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
fileList.add(((DomainFileNode) node).getDomainFile());
|
fileList.add(((DomainFileNode) node).getDomainFile());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
folderList.add(((DomainFolderNode)node).getDomainFolder());
|
folderList.add(((DomainFolderNode) node).getDomainFolder());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new FrontEndProjectTreeContext(null, null, selectionPaths, folderList, fileList,
|
return new FrontEndProjectTreeContext(null, null, selectionPaths, folderList, fileList,
|
||||||
|
@ -208,13 +209,9 @@ public class SetLanguageTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
startSetLanguage(new LanguageID("8051:BE:16:default"), new CompilerSpecID("default"), true);
|
startSetLanguage(new LanguageID("8051:BE:16:default"), new CompilerSpecID("default"), true);
|
||||||
|
|
||||||
final OptionDialog errDlg = waitForDialogComponent(OptionDialog.class);
|
AbstractErrDialog d = waitForErrorDialog();
|
||||||
assertNotNull(errDlg);
|
assertTrue(d.getMessage().contains("Language translation not supported"));
|
||||||
MultiLineLabel msgLabel = findComponent(errDlg, MultiLineLabel.class);
|
close(d);
|
||||||
assertNotNull(msgLabel);
|
|
||||||
assertTrue(msgLabel.getLabel().indexOf("Language translation not supported") >= 0);
|
|
||||||
|
|
||||||
pressButtonByText(errDlg, "OK");
|
|
||||||
closeAllWindows();
|
closeAllWindows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import javax.swing.*;
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
import org.junit.experimental.categories.Category;
|
import org.junit.experimental.categories.Category;
|
||||||
|
|
||||||
|
import docking.AbstractErrDialog;
|
||||||
import docking.action.DockingActionIf;
|
import docking.action.DockingActionIf;
|
||||||
import docking.widgets.OptionDialog;
|
import docking.widgets.OptionDialog;
|
||||||
import docking.wizard.WizardManager;
|
import docking.wizard.WizardManager;
|
||||||
|
@ -300,10 +301,9 @@ public class ProjectInfoDialogTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
pressButtonByText(opt, "Update");
|
pressButtonByText(opt, "Update");
|
||||||
waitForTasks();
|
waitForTasks();
|
||||||
|
|
||||||
opt = waitForDialogComponent(OptionDialog.class);
|
AbstractErrDialog errorDialog = waitForErrorDialog();
|
||||||
assertNotNull(opt);
|
assertEquals("Failed to Update Shared Project Info", errorDialog.getTitle());
|
||||||
assertEquals("Failed to Update Shared Project Info", opt.getTitle());
|
close(errorDialog);
|
||||||
opt.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkProjectInfo(String expectedRepName) {
|
private void checkProjectInfo(String expectedRepName) {
|
||||||
|
|
|
@ -24,9 +24,9 @@ import javax.swing.*;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import docking.AbstractErrDialog;
|
||||||
import docking.ActionContext;
|
import docking.ActionContext;
|
||||||
import docking.action.DockingActionIf;
|
import docking.action.DockingActionIf;
|
||||||
import docking.widgets.MultiLineLabel;
|
|
||||||
import docking.widgets.OptionDialog;
|
import docking.widgets.OptionDialog;
|
||||||
import docking.widgets.table.GTable;
|
import docking.widgets.table.GTable;
|
||||||
import docking.widgets.tree.GTreeNode;
|
import docking.widgets.tree.GTreeNode;
|
||||||
|
@ -146,15 +146,15 @@ public class VersionControlAction2Test extends AbstractVersionControlActionTest
|
||||||
GTreeNode nodeC = getNode(PROGRAM_C);
|
GTreeNode nodeC = getNode(PROGRAM_C);
|
||||||
selectNodes(nodeA, nodeC);
|
selectNodes(nodeA, nodeC);
|
||||||
|
|
||||||
final DockingActionIf action = getAction("Add to Version Control");
|
DockingActionIf action = getAction("Add to Version Control");
|
||||||
SwingUtilities.invokeLater(
|
SwingUtilities.invokeLater(
|
||||||
() -> action.actionPerformed(getDomainFileActionContext(nodeA, nodeC)));
|
() -> action.actionPerformed(getDomainFileActionContext(nodeA, nodeC)));
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
VersionControlDialog dialog = waitForDialogComponent(VersionControlDialog.class);
|
VersionControlDialog dialog = waitForDialogComponent(VersionControlDialog.class);
|
||||||
assertNotNull(dialog);
|
assertNotNull(dialog);
|
||||||
final JTextArea textArea = findComponent(dialog, JTextArea.class);
|
JTextArea textArea = findComponent(dialog, JTextArea.class);
|
||||||
assertNotNull(textArea);
|
assertNotNull(textArea);
|
||||||
final JCheckBox cb = findComponent(dialog, JCheckBox.class);
|
JCheckBox cb = findComponent(dialog, JCheckBox.class);
|
||||||
assertNotNull(cb);
|
assertNotNull(cb);
|
||||||
runSwing(() -> {
|
runSwing(() -> {
|
||||||
textArea.setText("This is a test");
|
textArea.setText("This is a test");
|
||||||
|
@ -176,11 +176,11 @@ public class VersionControlAction2Test extends AbstractVersionControlActionTest
|
||||||
@Test
|
@Test
|
||||||
public void testCheckOut() throws Exception {
|
public void testCheckOut() throws Exception {
|
||||||
// add program to version control
|
// add program to version control
|
||||||
final GTreeNode node = getNode(PROGRAM_A);
|
GTreeNode node = getNode(PROGRAM_A);
|
||||||
addToVersionControl(node, false);
|
addToVersionControl(node, false);
|
||||||
|
|
||||||
selectNode(node);
|
selectNode(node);
|
||||||
final DockingActionIf action = getAction("CheckOut");
|
DockingActionIf action = getAction("CheckOut");
|
||||||
SwingUtilities.invokeLater(() -> action.actionPerformed(getDomainFileActionContext(node)));
|
SwingUtilities.invokeLater(() -> action.actionPerformed(getDomainFileActionContext(node)));
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
waitForTasks();
|
waitForTasks();
|
||||||
|
@ -204,11 +204,11 @@ public class VersionControlAction2Test extends AbstractVersionControlActionTest
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCheckIn() throws Exception {
|
public void testCheckIn() throws Exception {
|
||||||
final GTreeNode node = getNode(PROGRAM_A);
|
GTreeNode node = getNode(PROGRAM_A);
|
||||||
addToVersionControl(node, false);
|
addToVersionControl(node, false);
|
||||||
|
|
||||||
selectNode(node);
|
selectNode(node);
|
||||||
final DockingActionIf action = getAction("CheckOut");
|
DockingActionIf action = getAction("CheckOut");
|
||||||
runSwing(() -> action.actionPerformed(getDomainFileActionContext(node)), false);
|
runSwing(() -> action.actionPerformed(getDomainFileActionContext(node)), false);
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
waitForTasks();
|
waitForTasks();
|
||||||
|
@ -227,14 +227,15 @@ public class VersionControlAction2Test extends AbstractVersionControlActionTest
|
||||||
program.save(null, TaskMonitor.DUMMY);
|
program.save(null, TaskMonitor.DUMMY);
|
||||||
}
|
}
|
||||||
program.release(this);
|
program.release(this);
|
||||||
final DockingActionIf checkInAction = getAction("CheckIn");
|
|
||||||
|
DockingActionIf checkInAction = getAction("CheckIn");
|
||||||
runSwing(() -> checkInAction.actionPerformed(getDomainFileActionContext(node)), false);
|
runSwing(() -> checkInAction.actionPerformed(getDomainFileActionContext(node)), false);
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
VersionControlDialog dialog = waitForDialogComponent(VersionControlDialog.class);
|
VersionControlDialog dialog = waitForDialogComponent(VersionControlDialog.class);
|
||||||
assertNotNull(dialog);
|
assertNotNull(dialog);
|
||||||
final JTextArea textArea = findComponent(dialog, JTextArea.class);
|
JTextArea textArea = findComponent(dialog, JTextArea.class);
|
||||||
assertNotNull(textArea);
|
assertNotNull(textArea);
|
||||||
final JCheckBox cb = findComponent(dialog, JCheckBox.class);
|
JCheckBox cb = findComponent(dialog, JCheckBox.class);
|
||||||
assertNotNull(cb);
|
assertNotNull(cb);
|
||||||
runSwing(() -> {
|
runSwing(() -> {
|
||||||
textArea.setText("This is a test");
|
textArea.setText("This is a test");
|
||||||
|
@ -253,10 +254,10 @@ public class VersionControlAction2Test extends AbstractVersionControlActionTest
|
||||||
setErrorGUIEnabled(true);// expect an error dialog
|
setErrorGUIEnabled(true);// expect an error dialog
|
||||||
// create 3 versions of the program
|
// create 3 versions of the program
|
||||||
doCreateVersions();
|
doCreateVersions();
|
||||||
final GTreeNode node = getNode(PROGRAM_A);
|
GTreeNode node = getNode(PROGRAM_A);
|
||||||
|
|
||||||
selectNode(node);
|
selectNode(node);
|
||||||
final DockingActionIf historyAction = getAction("Show History");
|
DockingActionIf historyAction = getAction("Show History");
|
||||||
runSwing(() -> historyAction.actionPerformed(getDomainFileActionContext(node)));
|
runSwing(() -> historyAction.actionPerformed(getDomainFileActionContext(node)));
|
||||||
|
|
||||||
VersionHistoryDialog dialog = waitForDialogComponent(VersionHistoryDialog.class);
|
VersionHistoryDialog dialog = waitForDialogComponent(VersionHistoryDialog.class);
|
||||||
|
@ -267,14 +268,9 @@ public class VersionControlAction2Test extends AbstractVersionControlActionTest
|
||||||
performAction(deleteAction, false);
|
performAction(deleteAction, false);
|
||||||
|
|
||||||
// cannot delete a file that is checked out
|
// cannot delete a file that is checked out
|
||||||
OptionDialog d = waitForDialogComponent(OptionDialog.class);
|
AbstractErrDialog d = waitForErrorDialog();
|
||||||
assertNotNull(d);
|
assertEquals("File version has one or more checkouts.", d.getMessage());
|
||||||
|
close(d);
|
||||||
MultiLineLabel label = findComponent(d.getComponent(), MultiLineLabel.class);
|
|
||||||
assertNotNull(label);
|
|
||||||
assertEquals("File version has one or more checkouts.", label.getLabel());
|
|
||||||
|
|
||||||
runSwing(() -> d.close());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -283,10 +279,10 @@ public class VersionControlAction2Test extends AbstractVersionControlActionTest
|
||||||
setErrorGUIEnabled(true);// expect an error dialog
|
setErrorGUIEnabled(true);// expect an error dialog
|
||||||
|
|
||||||
doCreateVersions();
|
doCreateVersions();
|
||||||
final GTreeNode node = getNode(PROGRAM_A);
|
GTreeNode node = getNode(PROGRAM_A);
|
||||||
selectNode(node);
|
selectNode(node);
|
||||||
|
|
||||||
final DockingActionIf historyAction = getAction("Show History");
|
DockingActionIf historyAction = getAction("Show History");
|
||||||
runSwing(() -> historyAction.actionPerformed(getDomainFileActionContext(node)));
|
runSwing(() -> historyAction.actionPerformed(getDomainFileActionContext(node)));
|
||||||
|
|
||||||
VersionHistoryDialog dialog = waitForDialogComponent(VersionHistoryDialog.class);
|
VersionHistoryDialog dialog = waitForDialogComponent(VersionHistoryDialog.class);
|
||||||
|
@ -297,17 +293,10 @@ public class VersionControlAction2Test extends AbstractVersionControlActionTest
|
||||||
performAction(deleteAction, false);
|
performAction(deleteAction, false);
|
||||||
|
|
||||||
// can delete only the first or last version of the file
|
// can delete only the first or last version of the file
|
||||||
OptionDialog d = waitForDialogComponent(OptionDialog.class);
|
AbstractErrDialog d = waitForErrorDialog();
|
||||||
assertNotNull(d);
|
assertEquals("Only first and last version may be deleted.", d.getMessage());
|
||||||
|
close(d);
|
||||||
MultiLineLabel label = findComponent(d.getComponent(), MultiLineLabel.class);
|
close(dialog);
|
||||||
assertNotNull(label);
|
|
||||||
assertEquals("Only first and last version may be deleted.", label.getLabel());
|
|
||||||
|
|
||||||
runSwing(() -> {
|
|
||||||
d.close();
|
|
||||||
dialog.close();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -341,7 +330,7 @@ public class VersionControlAction2Test extends AbstractVersionControlActionTest
|
||||||
|
|
||||||
assertEquals(rowCount - 1, table.getRowCount());
|
assertEquals(rowCount - 1, table.getRowCount());
|
||||||
|
|
||||||
runSwing(() -> dialog.close());
|
close(dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -371,7 +360,7 @@ public class VersionControlAction2Test extends AbstractVersionControlActionTest
|
||||||
FindCheckoutsDialog dialog = waitForDialogComponent(FindCheckoutsDialog.class);
|
FindCheckoutsDialog dialog = waitForDialogComponent(FindCheckoutsDialog.class);
|
||||||
assertNotNull(dialog);
|
assertNotNull(dialog);
|
||||||
|
|
||||||
final GTable table = findComponent(dialog.getComponent(), GTable.class);
|
GTable table = findComponent(dialog.getComponent(), GTable.class);
|
||||||
assertNotNull(table);
|
assertNotNull(table);
|
||||||
waitForBusyTable(table);
|
waitForBusyTable(table);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue