diff --git a/Ghidra/Features/Base/certification.manifest b/Ghidra/Features/Base/certification.manifest
index a0a710f186..5c4b89797b 100644
--- a/Ghidra/Features/Base/certification.manifest
+++ b/Ghidra/Features/Base/certification.manifest
@@ -312,11 +312,11 @@ src/main/help/help/topics/FrontEndPlugin/images/SelectSharedProjectType.png||GHI
src/main/help/help/topics/FrontEndPlugin/images/ServerInfo.png||GHIDRA||||END|
src/main/help/help/topics/FrontEndPlugin/images/SharedProjectInfo.png||GHIDRA||||END|
src/main/help/help/topics/FrontEndPlugin/images/UsersPanel.png||GHIDRA||||END|
-src/main/help/help/topics/FrontEndPlugin/images/UsersPanelMini.png||GHIDRA||||END|
src/main/help/help/topics/FrontEndPlugin/images/VersionedFileCOnoServer.png||GHIDRA||||END|
src/main/help/help/topics/FrontEndPlugin/images/VersionedFileCOwithServer.png||GHIDRA||||END|
src/main/help/help/topics/FrontEndPlugin/images/VersionedFileIcon.png||GHIDRA||||END|
src/main/help/help/topics/FrontEndPlugin/images/ViewOtherProjects.png||GHIDRA||||END|
+src/main/help/help/topics/FrontEndPlugin/images/ViewProjectAccessPanel.png||GHIDRA||||END|
src/main/help/help/topics/FrontEndPlugin/images/hijack_file.png||GHIDRA||||END|
src/main/help/help/topics/FunctionComparison/FunctionComparison.htm||GHIDRA||||END|
src/main/help/help/topics/FunctionComparison/images/AddFunctionsPanel.png||GHIDRA||||END|
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/Ghidra_Front_end.htm b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/Ghidra_Front_end.htm
index 56dce2da44..c5766675c9 100644
--- a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/Ghidra_Front_end.htm
+++ b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/Ghidra_Front_end.htm
@@ -917,7 +917,7 @@
"help/shared/arrow.gif" border="0">View Project Access List will be enabled, which will display
the following dialog and allow the user to view the project users and their current access privileges only.
- 
+ 
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ArchiveFileExists.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ArchiveFileExists.png
index 003714b9cc..3813aa8ee3 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ArchiveFileExists.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ArchiveFileExists.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ArchiveProject.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ArchiveProject.png
index 6bfb8baa57..05831c64b5 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ArchiveProject.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ArchiveProject.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ChangeAccessList.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ChangeAccessList.png
index 365070089e..d1c1f8f983 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ChangeAccessList.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ChangeAccessList.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ChangePassword.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ChangePassword.png
index 1d94f040cc..19ec42776b 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ChangePassword.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ChangePassword.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ChangeRepositoryPanel.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ChangeRepositoryPanel.png
index 2ccf0c59ae..8ab0adedbd 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ChangeRepositoryPanel.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ChangeRepositoryPanel.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ChangeServerInfoPanel.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ChangeServerInfoPanel.png
index 26ba2831d0..267a1d9801 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ChangeServerInfoPanel.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ChangeServerInfoPanel.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ConfigureExtensions.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ConfigureExtensions.png
index f2785eeb03..7670d97f4f 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ConfigureExtensions.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ConfigureExtensions.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ConfigureTool.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ConfigureTool.png
index 003d5f4a47..b11e2cef60 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ConfigureTool.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ConfigureTool.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ConfirmChangePassword.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ConfirmChangePassword.png
index e20e032db8..5366e322d0 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ConfirmChangePassword.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ConfirmChangePassword.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ConfirmDeleteProject.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ConfirmDeleteProject.png
index 9d05b0addd..05de979d1e 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ConfirmDeleteProject.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ConfirmDeleteProject.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ConnectTools.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ConnectTools.png
index bf90dba5dd..4aae14590c 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ConnectTools.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ConnectTools.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/DeleteProject.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/DeleteProject.png
index 9285a463fc..2394f74f91 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/DeleteProject.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/DeleteProject.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/EditPluginPath.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/EditPluginPath.png
index fe4537e1d0..b6589f752c 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/EditPluginPath.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/EditPluginPath.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/EditProjectAccessList.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/EditProjectAccessList.png
index df7dc1cd95..1a0d730f31 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/EditProjectAccessList.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/EditProjectAccessList.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/LinkOtherProject.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/LinkOtherProject.png
index 15d4c8bcaa..7ac46d4370 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/LinkOtherProject.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/LinkOtherProject.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/NonSharedProjectInfo.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/NonSharedProjectInfo.png
index 24a00b7bc4..d05da5a65c 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/NonSharedProjectInfo.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/NonSharedProjectInfo.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/OpenProject.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/OpenProject.png
index 09abf9b48c..09450d416b 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/OpenProject.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/OpenProject.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ProjectDataTable.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ProjectDataTable.png
index 6e4906ad68..a8bf774690 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ProjectDataTable.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ProjectDataTable.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ProjectDataTree.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ProjectDataTree.png
index 47b62fcb71..aa28c01b76 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ProjectDataTree.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ProjectDataTree.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ProjectWindow.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ProjectWindow.png
index 59ade2cbf3..257fef7dc9 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ProjectWindow.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ProjectWindow.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ReopenProject.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ReopenProject.png
index 5801e475fc..7fa0ae16b4 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ReopenProject.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ReopenProject.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/RepositoryNamePanel.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/RepositoryNamePanel.png
index 9aabcc88d0..93d1471734 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/RepositoryNamePanel.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/RepositoryNamePanel.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/RestoreProjectFilledIn.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/RestoreProjectFilledIn.png
index d86a95363c..b54f605787 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/RestoreProjectFilledIn.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/RestoreProjectFilledIn.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SaveFiles.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SaveFiles.png
index ab9fa6a0e0..2273e63061 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SaveFiles.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SaveFiles.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SaveReadOnly.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SaveReadOnly.png
index 5ecff9b18a..84da54e497 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SaveReadOnly.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SaveReadOnly.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SelectProjectLocation.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SelectProjectLocation.png
index bd5629b072..8194ecd27b 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SelectProjectLocation.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SelectProjectLocation.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SelectProjectType.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SelectProjectType.png
index eb1fd6fa44..eacadbef90 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SelectProjectType.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SelectProjectType.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SelectSharedProjectLocation.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SelectSharedProjectLocation.png
index 07177139e9..8c306a9287 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SelectSharedProjectLocation.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SelectSharedProjectLocation.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SelectSharedProjectType.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SelectSharedProjectType.png
index f80165f9a8..ab4874b9e3 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SelectSharedProjectType.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SelectSharedProjectType.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ServerInfo.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ServerInfo.png
index d778ddd0dc..cc41854bc6 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ServerInfo.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ServerInfo.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SharedProjectInfo.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SharedProjectInfo.png
index 662dfdcb0e..83a6ac090f 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SharedProjectInfo.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/SharedProjectInfo.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/UsersPanelMini.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/UsersPanelMini.png
deleted file mode 100644
index daaeeecd38..0000000000
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/UsersPanelMini.png and /dev/null differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ViewOtherProjects.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ViewOtherProjects.png
index 95518a3f13..d2f7c74b4a 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ViewOtherProjects.png and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ViewOtherProjects.png differ
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ViewProjectAccessPanel.png b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ViewProjectAccessPanel.png
new file mode 100644
index 0000000000..3be025c21a
Binary files /dev/null and b/Ghidra/Features/Base/src/main/help/help/topics/FrontEndPlugin/images/ViewProjectAccessPanel.png differ
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/listing/ListingCodeComparisonPanel.java b/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/listing/ListingCodeComparisonPanel.java
index f2c445003b..987e6eb2f0 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/listing/ListingCodeComparisonPanel.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/listing/ListingCodeComparisonPanel.java
@@ -601,6 +601,8 @@ public class ListingCodeComparisonPanel
private void updateProgramViews() {
displays.get(LEFT).setProgramView(getProgram(LEFT), getAddresses(LEFT), "listing1");
displays.get(RIGHT).setProgramView(getProgram(RIGHT), getAddresses(RIGHT), "listing2");
+ displays.get(LEFT).goTo(comparisonData.get(LEFT).getInitialLocation());
+ displays.get(RIGHT).goTo(comparisonData.get(LEFT).getInitialLocation());
}
private void nextAreaDiff(boolean forward) {
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/listing/ListingDisplay.java b/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/listing/ListingDisplay.java
index 1862805462..943d36fe78 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/listing/ListingDisplay.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/listing/ListingDisplay.java
@@ -4,9 +4,9 @@
* 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.
@@ -174,10 +174,6 @@ public class ListingDisplay implements ListingDiffChangeListener {
markerManager.getOverviewProvider().setProgram(program, indexMap);
listingPanel.setBackgroundColorModel(
new MarkerServiceBackgroundColorModel(markerManager, program, indexMap));
- setUpAreaMarkerSets(program, name);
- if (!view.isEmpty()) {
- goTo(new ProgramLocation(program, view.getMinAddress()));
- }
repaint();
}
@@ -189,8 +185,9 @@ public class ListingDisplay implements ListingDiffChangeListener {
Color unmatchedColor = comparisonOptions.getUnmatchedCodeUnitsBackgroundColor();
AddressIndexMap indexMap = listingPanel.getAddressIndexMap();
- listingPanel.getFieldPanel().setBackgroundColorModel(new MarkerServiceBackgroundColorModel(
- markerManager, program, indexMap));
+ listingPanel.getFieldPanel()
+ .setBackgroundColorModel(new MarkerServiceBackgroundColorModel(
+ markerManager, program, indexMap));
unmatchedMarkers = markerManager.createAreaMarker(name + " Unmatched Code",
"Instructions that are not matched to an instruction in the other function.",
@@ -307,8 +304,9 @@ public class ListingDisplay implements ListingDiffChangeListener {
}
public void setViewerPosition(ViewerPosition position) {
- listingPanel.getFieldPanel().setViewerPosition(position.getIndex(), position.getXOffset(),
- position.getYOffset());
+ listingPanel.getFieldPanel()
+ .setViewerPosition(position.getIndex(), position.getXOffset(),
+ position.getYOffset());
}
public void setMouseNavigationEnabled(boolean enabled) {
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/panel/AddressSetComparisonData.java b/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/panel/AddressSetComparisonData.java
index 785d2706d6..0866a9240e 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/panel/AddressSetComparisonData.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/panel/AddressSetComparisonData.java
@@ -4,9 +4,9 @@
* 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.
@@ -21,6 +21,7 @@ import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Program;
+import ghidra.program.util.ProgramLocation;
import ghidra.util.HTMLUtilities;
/**
@@ -77,4 +78,9 @@ public class AddressSetComparisonData implements ComparisonData {
public boolean isEmpty() {
return addresses.isEmpty();
}
+
+ @Override
+ public ProgramLocation getInitialLocation() {
+ return new ProgramLocation(program, addresses.getMinAddress());
+ }
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/panel/ComparisonData.java b/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/panel/ComparisonData.java
index a4a6db0366..e5c705e35a 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/panel/ComparisonData.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/panel/ComparisonData.java
@@ -4,9 +4,9 @@
* 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.
@@ -21,6 +21,7 @@ import generic.theme.GThemeDefaults.Colors.Palette;
import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Program;
+import ghidra.program.util.ProgramLocation;
/**
* ComparisonData is an abstract of items that can be compared in a {@link CodeComparisonPanel}.
@@ -68,4 +69,9 @@ public interface ComparisonData {
*/
public boolean isEmpty();
+ /**
+ * Returns the initial program location to put the cursor when the panel is first displayed
+ */
+ public ProgramLocation getInitialLocation();
+
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/panel/DataComparisonData.java b/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/panel/DataComparisonData.java
index 859d6ab907..b683968293 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/panel/DataComparisonData.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/panel/DataComparisonData.java
@@ -4,9 +4,9 @@
* 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.
@@ -20,6 +20,7 @@ import java.util.Objects;
import ghidra.program.model.address.*;
import ghidra.program.model.listing.*;
import ghidra.program.model.mem.MemoryBlock;
+import ghidra.program.util.ProgramLocation;
import ghidra.util.HTMLUtilities;
/**
@@ -108,4 +109,9 @@ public class DataComparisonData implements ComparisonData {
}
return endAddress;
}
+
+ @Override
+ public ProgramLocation getInitialLocation() {
+ return new ProgramLocation(data.getProgram(), data.getMinAddress());
+ }
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/panel/EmptyComparisonData.java b/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/panel/EmptyComparisonData.java
index 36313401c3..f1153afe5c 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/panel/EmptyComparisonData.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/panel/EmptyComparisonData.java
@@ -4,9 +4,9 @@
* 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.
@@ -19,6 +19,7 @@ import ghidra.program.model.address.AddressSet;
import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Program;
+import ghidra.program.util.ProgramLocation;
public class EmptyComparisonData implements ComparisonData {
@@ -51,4 +52,9 @@ public class EmptyComparisonData implements ComparisonData {
public boolean isEmpty() {
return true;
}
+
+ @Override
+ public ProgramLocation getInitialLocation() {
+ return null;
+ }
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/panel/FunctionComparisonData.java b/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/panel/FunctionComparisonData.java
index 4c8080f4f1..bf3f3b3e05 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/panel/FunctionComparisonData.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/features/base/codecompare/panel/FunctionComparisonData.java
@@ -4,9 +4,9 @@
* 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.
@@ -21,6 +21,8 @@ import ghidra.program.model.address.AddressSet;
import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Program;
+import ghidra.program.util.FunctionSignatureFieldLocation;
+import ghidra.program.util.ProgramLocation;
import ghidra.util.HTMLUtilities;
/**
@@ -84,4 +86,9 @@ public class FunctionComparisonData implements ComparisonData {
return false;
}
+ @Override
+ public ProgramLocation getInitialLocation() {
+ return new FunctionSignatureFieldLocation(function.getProgram(), function.getEntryPoint());
+ }
+
}
diff --git a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/CorrelatorPanel.png b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/CorrelatorPanel.png
index 1e2d0de7e1..1183bc38c0 100644
Binary files a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/CorrelatorPanel.png and b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/CorrelatorPanel.png differ
diff --git a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/FunctionsTable.png b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/FunctionsTable.png
index aa3346a298..ea3bb74b72 100644
Binary files a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/FunctionsTable.png and b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/FunctionsTable.png differ
diff --git a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/ImpliedMatchExample.png b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/ImpliedMatchExample.png
index e9c49688d0..d92474d5fa 100644
Binary files a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/ImpliedMatchExample.png and b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/ImpliedMatchExample.png differ
diff --git a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/ImpliedMatchesTable.png b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/ImpliedMatchesTable.png
index 972afa995f..9e3f723585 100644
Binary files a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/ImpliedMatchesTable.png and b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/ImpliedMatchesTable.png differ
diff --git a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/MarkupItemsFilters.png b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/MarkupItemsFilters.png
index 60c0b12dc0..ea57266b48 100644
Binary files a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/MarkupItemsFilters.png and b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/MarkupItemsFilters.png differ
diff --git a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/MatchesTable.png b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/MatchesTable.png
index e4b4e776e9..b8a79f0a05 100644
Binary files a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/MatchesTable.png and b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/MatchesTable.png differ
diff --git a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/OneToManyDestination.png b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/OneToManyDestination.png
index 10852acd80..85101ce11c 100644
Binary files a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/OneToManyDestination.png and b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/OneToManyDestination.png differ
diff --git a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/OneToManySource.png b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/OneToManySource.png
index eab5c44609..804ac2aded 100644
Binary files a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/OneToManySource.png and b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/OneToManySource.png differ
diff --git a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/OptionsPanel.png b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/OptionsPanel.png
index 0f4142b5c8..c576bd0497 100644
Binary files a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/OptionsPanel.png and b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/OptionsPanel.png differ
diff --git a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/PreconditionsPanel.png b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/PreconditionsPanel.png
index e2fdbf5b63..c4a5d00996 100644
Binary files a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/PreconditionsPanel.png and b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/PreconditionsPanel.png differ
diff --git a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/SessionPanel.png b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/SessionPanel.png
index 07a1da6616..0d52705142 100644
Binary files a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/SessionPanel.png and b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/SessionPanel.png differ
diff --git a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/SourceTool.png b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/SourceTool.png
index 84456dc66a..a961b6128f 100644
Binary files a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/SourceTool.png and b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/SourceTool.png differ
diff --git a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/SummaryPanel.png b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/SummaryPanel.png
index da412c9526..11acd81c13 100644
Binary files a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/SummaryPanel.png and b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/SummaryPanel.png differ
diff --git a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VTOptions_AcceptMatchDialog.png b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VTOptions_AcceptMatchDialog.png
index b82a44aeec..c25f9ffd6c 100644
Binary files a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VTOptions_AcceptMatchDialog.png and b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VTOptions_AcceptMatchDialog.png differ
diff --git a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VTOptions_ApplyMarkupDialog.png b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VTOptions_ApplyMarkupDialog.png
index e231e936dd..dd63936868 100644
Binary files a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VTOptions_ApplyMarkupDialog.png and b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VTOptions_ApplyMarkupDialog.png differ
diff --git a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VT_Wizard_AddToSession_Summary.png b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VT_Wizard_AddToSession_Summary.png
index 0dd9503b8f..06a07141a3 100644
Binary files a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VT_Wizard_AddToSession_Summary.png and b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VT_Wizard_AddToSession_Summary.png differ
diff --git a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VT_Wizard_AddressSetOptions.png b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VT_Wizard_AddressSetOptions.png
index 770942d6da..a6691d38a2 100644
Binary files a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VT_Wizard_AddressSetOptions.png and b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VT_Wizard_AddressSetOptions.png differ
diff --git a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VT_Wizard_SelectAddressRanges.png b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VT_Wizard_SelectAddressRanges.png
index d0f63e94d6..f374add593 100644
Binary files a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VT_Wizard_SelectAddressRanges.png and b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VT_Wizard_SelectAddressRanges.png differ
diff --git a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VersionTrackingMarkupItems.png b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VersionTrackingMarkupItems.png
index 225dc9e931..797433fe06 100644
Binary files a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VersionTrackingMarkupItems.png and b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VersionTrackingMarkupItems.png differ
diff --git a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VersionTrackingMarkupItemsHeader.png b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VersionTrackingMarkupItemsHeader.png
index 6faae2059d..43839123db 100644
Binary files a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VersionTrackingMarkupItemsHeader.png and b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VersionTrackingMarkupItemsHeader.png differ
diff --git a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VersionTrackingMarkupItemsSideBySide.png b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VersionTrackingMarkupItemsSideBySide.png
index 5b3b091a30..bbded2b11a 100644
Binary files a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VersionTrackingMarkupItemsSideBySide.png and b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VersionTrackingMarkupItemsSideBySide.png differ
diff --git a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VersionTrackingMarkupItemsTableOnly.png b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VersionTrackingMarkupItemsTableOnly.png
index 5a1d139a99..6fd68cbee3 100644
Binary files a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VersionTrackingMarkupItemsTableOnly.png and b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VersionTrackingMarkupItemsTableOnly.png differ
diff --git a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VersionTrackingTool.png b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VersionTrackingTool.png
index afc82e88d6..4642b4d335 100644
Binary files a/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VersionTrackingTool.png and b/Ghidra/Features/VersionTracking/src/main/help/help/topics/VersionTrackingPlugin/images/VersionTrackingTool.png differ
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/actions/AddToVersionTrackingSessionAction.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/actions/AddToVersionTrackingSessionAction.java
index 64ee1c57dd..f855950287 100644
--- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/actions/AddToVersionTrackingSessionAction.java
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/actions/AddToVersionTrackingSessionAction.java
@@ -4,9 +4,9 @@
* 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.
@@ -20,11 +20,11 @@ import javax.swing.Icon;
import docking.ActionContext;
import docking.action.*;
import docking.tool.ToolConstants;
-import docking.wizard.WizardManager;
+import docking.wizard.WizardDialog;
import generic.theme.GIcon;
import ghidra.feature.vt.gui.plugin.VTController;
import ghidra.feature.vt.gui.plugin.VTPlugin;
-import ghidra.feature.vt.gui.wizard.VTAddToSessionWizardManager;
+import ghidra.feature.vt.gui.wizard.add.VTAddToSessionWizardModel;
import ghidra.util.HelpLocation;
public class AddToVersionTrackingSessionAction extends DockingAction {
@@ -46,10 +46,9 @@ public class AddToVersionTrackingSessionAction extends DockingAction {
@Override
public void actionPerformed(ActionContext context) {
- VTAddToSessionWizardManager vtWizardManager = new VTAddToSessionWizardManager(controller);
- WizardManager wizardManager =
- new WizardManager("Version Tracking Wizard", true, vtWizardManager);
- wizardManager.showWizard(controller.getParentComponent());
+ VTAddToSessionWizardModel model = new VTAddToSessionWizardModel(controller);
+ WizardDialog wizardDialog = new WizardDialog(model);
+ wizardDialog.show(controller.getParentComponent());
}
@Override
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/actions/CreateVersionTrackingSessionAction.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/actions/CreateVersionTrackingSessionAction.java
index 4f749a718a..5b446f09b9 100644
--- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/actions/CreateVersionTrackingSessionAction.java
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/actions/CreateVersionTrackingSessionAction.java
@@ -21,11 +21,11 @@ import docking.ActionContext;
import docking.action.*;
import docking.tool.ToolConstants;
import docking.widgets.OptionDialog;
-import docking.wizard.WizardManager;
+import docking.wizard.WizardDialog;
import generic.theme.GIcon;
import ghidra.feature.vt.gui.plugin.VTController;
import ghidra.feature.vt.gui.plugin.VTPlugin;
-import ghidra.feature.vt.gui.wizard.VTNewSessionWizardManager;
+import ghidra.feature.vt.gui.wizard.session.VTNewSessionWizardModel;
import ghidra.util.HelpLocation;
public class CreateVersionTrackingSessionAction extends DockingAction {
@@ -58,10 +58,9 @@ public class CreateVersionTrackingSessionAction extends DockingAction {
if (!controller.closeVersionTrackingSession()) {
return; // user cancelled during save dialog
}
- VTNewSessionWizardManager vtWizardManager = new VTNewSessionWizardManager(controller);
- WizardManager wizardManager =
- new WizardManager("Version Tracking Wizard", true, vtWizardManager);
- wizardManager.showWizard(controller.getParentComponent());
+ VTNewSessionWizardModel model = new VTNewSessionWizardModel(controller);
+ WizardDialog wizardDialog = new WizardDialog(model);
+ wizardDialog.show(controller.getParentComponent());
}
}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/plugin/VTPlugin.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/plugin/VTPlugin.java
index eff11789d7..6c2e876af6 100644
--- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/plugin/VTPlugin.java
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/plugin/VTPlugin.java
@@ -4,9 +4,9 @@
* 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.
@@ -24,7 +24,7 @@ import javax.swing.JFrame;
import docking.action.DockingActionIf;
import docking.tool.ToolConstants;
-import docking.wizard.WizardManager;
+import docking.wizard.WizardDialog;
import generic.theme.GIcon;
import ghidra.GhidraOptions;
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
@@ -37,7 +37,7 @@ import ghidra.feature.vt.gui.provider.functionassociation.VTFunctionAssociationP
import ghidra.feature.vt.gui.provider.impliedmatches.*;
import ghidra.feature.vt.gui.provider.markuptable.VTMarkupItemsTableProvider;
import ghidra.feature.vt.gui.provider.matchtable.VTMatchTableProvider;
-import ghidra.feature.vt.gui.wizard.VTNewSessionWizardManager;
+import ghidra.feature.vt.gui.wizard.session.VTNewSessionWizardModel;
import ghidra.framework.model.*;
import ghidra.framework.options.Options;
import ghidra.framework.options.SaveState;
@@ -268,11 +268,10 @@ public class VTPlugin extends Plugin {
if (!controller.closeVersionTrackingSession()) {
return false; // user cancelled during save dialog
}
- VTNewSessionWizardManager vtWizardManager =
- new VTNewSessionWizardManager(controller, programFile1, programFile2);
- WizardManager wizardManager =
- new WizardManager("Version Tracking Wizard", true, vtWizardManager);
- wizardManager.showWizard(tool.getToolFrame());
+ VTNewSessionWizardModel model =
+ new VTNewSessionWizardModel(controller, programFile1, programFile2);
+ WizardDialog wizardDialog = new WizardDialog(model);
+ wizardDialog.show(tool.getToolFrame());
return true;
}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/task/SaveTask.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/task/SaveTask.java
index bb0efe1df2..6c3dddb168 100644
--- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/task/SaveTask.java
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/task/SaveTask.java
@@ -1,13 +1,12 @@
/* ###
* 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.
@@ -16,7 +15,7 @@
*/
package ghidra.feature.vt.gui.task;
-import ghidra.feature.vt.gui.wizard.VTWizardUtils;
+import ghidra.feature.vt.gui.wizard.session.VTWizardUtils;
import ghidra.framework.model.DomainFile;
import ghidra.util.Msg;
import ghidra.util.exception.CancelledException;
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/AddressRangeListener.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/AddressRangeListener.java
deleted file mode 100644
index f3cf720223..0000000000
--- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/AddressRangeListener.java
+++ /dev/null
@@ -1,25 +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.feature.vt.gui.wizard;
-
-import ghidra.program.model.address.Address;
-
-public interface AddressRangeListener {
-
- public void processAddressRange(Address minAddress, Address maxAddress);
-
-}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/AddressSetOptionsPanel.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/AddressSetOptionsPanel.java
deleted file mode 100644
index 4c919164ec..0000000000
--- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/AddressSetOptionsPanel.java
+++ /dev/null
@@ -1,152 +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.feature.vt.gui.wizard;
-
-import java.util.List;
-
-import javax.swing.BorderFactory;
-import javax.swing.JCheckBox;
-
-import docking.widgets.checkbox.GCheckBox;
-import docking.wizard.*;
-import ghidra.feature.vt.api.main.VTProgramCorrelatorAddressRestrictionPreference;
-import ghidra.feature.vt.api.main.VTProgramCorrelatorFactory;
-import ghidra.program.model.address.AddressSetView;
-import ghidra.util.HTMLUtilities;
-import ghidra.util.HelpLocation;
-import ghidra.util.layout.VerticalLayout;
-
-public class AddressSetOptionsPanel extends AbstractMageJPanel {
-
- private JCheckBox excludeCheckbox;
- private JCheckBox showAddressSetPanelsCheckbox;
-
- public AddressSetOptionsPanel() { //
- setBorder(BorderFactory.createEmptyBorder(40, 40, 0, 0));
-
- excludeCheckbox = new GCheckBox("Exclude accepted matches", false);
- String excludeAcceptedTooltip = "This option will cause the correlator algorithm " +
- "to not consider any functions or data that have already been " +
- "accepted. Using this option can greatly speed up the processing time " +
- "of the correlator algorithm; however, this options should only be " +
- "used when you trust that your accepted matches are correct.";
- excludeCheckbox.setToolTipText(HTMLUtilities.toWrappedHTML(excludeAcceptedTooltip));
-
- showAddressSetPanelsCheckbox = new GCheckBox("Limit source and destination address sets");
- String manuallyLimitTooltip = "Selecting this checkbox will trigger additional wizard " +
- " panels allowing you to customize the address sets used " +
- " by the selected algorithm. When not selected, the entire address space is used.";
-
- showAddressSetPanelsCheckbox.setToolTipText(
- HTMLUtilities.toWrappedHTML(manuallyLimitTooltip));
-
- add(excludeCheckbox);
- add(showAddressSetPanelsCheckbox);
- setLayout(new VerticalLayout(20));
- }
-
- @Override
- public void addDependencies(WizardState state) {
- // none
- }
-
- @Override
- public void dispose() {
- // nothing to do
- }
-
- @Override
- public void enterPanel(WizardState state) {
- @SuppressWarnings("unchecked")
- List list = (List) state.get(
- VTWizardStateKey.PROGRAM_CORRELATOR_FACTORY_LIST);
-
- Boolean value = (Boolean) state.get(VTWizardStateKey.EXCLUDE_ACCEPTED_MATCHES);
- if (value != null) {
- excludeCheckbox.setSelected(value.booleanValue());
- }
- value = (Boolean) state.get(VTWizardStateKey.SHOW_ADDRESS_SET_PANELS);
- if (value != null) {
- showAddressSetPanelsCheckbox.setSelected(value.booleanValue());
- }
- else {
- AddressSetView sourceSelection =
- (AddressSetView) state.get(VTWizardStateKey.SOURCE_SELECTION);
- AddressSetView destinationSelection =
- (AddressSetView) state.get(VTWizardStateKey.DESTINATION_SELECTION);
- boolean somethingSelected = (sourceSelection != null && !sourceSelection.isEmpty()) ||
- (destinationSelection != null && !destinationSelection.isEmpty());
- showAddressSetPanelsCheckbox.setSelected(somethingSelected);
- }
-
- if (allowRestrictions(list)) {
- excludeCheckbox.setEnabled(true);
- }
- else {
- excludeCheckbox.setSelected(false);
- excludeCheckbox.setEnabled(false);
- }
-
- }
-
- private boolean allowRestrictions(List list) {
- for (VTProgramCorrelatorFactory factory : list) {
- if (factory.getAddressRestrictionPreference() != VTProgramCorrelatorAddressRestrictionPreference.RESTRICTION_NOT_ALLOWED) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public WizardPanelDisplayability getPanelDisplayabilityAndUpdateState(
- WizardState state) {
- return WizardPanelDisplayability.CAN_BE_DISPLAYED;
- }
-
- @Override
- public void leavePanel(WizardState state) {
- updateStateObjectWithPanelInfo(state);
- }
-
- @Override
- public void updateStateObjectWithPanelInfo(WizardState state) {
- state.put(VTWizardStateKey.EXCLUDE_ACCEPTED_MATCHES, excludeCheckbox.isSelected());
- state.put(VTWizardStateKey.SHOW_ADDRESS_SET_PANELS,
- showAddressSetPanelsCheckbox.isSelected());
- }
-
- @Override
- public HelpLocation getHelpLocation() {
- return new HelpLocation("VersionTrackingPlugin", "Address_Set_Panel");
- }
-
- @Override
- public String getTitle() {
- return "Address Set Options";
- }
-
- @Override
- public void initialize() {
- // nothing to do
- }
-
- @Override
- public boolean isValidInformation() {
- return true;
- }
-
-}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/AddressSetPanel.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/AddressSetPanel.java
deleted file mode 100644
index 8224cd2533..0000000000
--- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/AddressSetPanel.java
+++ /dev/null
@@ -1,156 +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.feature.vt.gui.wizard;
-
-import ghidra.feature.vt.gui.wizard.ChooseAddressSetEditorPanel.AddressSetChoice;
-import ghidra.framework.plugintool.PluginTool;
-import ghidra.program.model.address.*;
-import ghidra.program.model.listing.Program;
-import ghidra.util.HelpLocation;
-
-import java.awt.BorderLayout;
-
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-
-import docking.wizard.*;
-
-public class AddressSetPanel extends AbstractMageJPanel {
-
- private final PluginTool tool;
- private final String name;
- private final VTWizardStateKey programDependencyKey;
- private final VTWizardStateKey addressSetViewKey;
- private final VTWizardStateKey selectionKey;
- private final VTWizardStateKey addressSetChoiceKey;
- private ChooseAddressSetEditorPanel panel;
- private Program program;
-
- public AddressSetPanel(PluginTool tool, String name, VTWizardStateKey programFileDependencyKey,
- VTWizardStateKey programDependencyKey, VTWizardStateKey addressSetViewKey,
- VTWizardStateKey selectionKey, VTWizardStateKey addressSetChoiceKey) {
- this.tool = tool;
- this.name = name;
- this.programDependencyKey = programDependencyKey;
- this.addressSetViewKey = addressSetViewKey;
- this.selectionKey = selectionKey;
- this.addressSetChoiceKey = addressSetChoiceKey;
- setLayout(new BorderLayout());
- }
-
- @Override
- public void addDependencies(WizardState state) {
- // no dependencies
- }
-
- @Override
- public void dispose() {
- // nothing to do
- }
-
- // Keep this method for now in case we want it as the default for the entire program address set
- // instead of the program's memory address set.
- @SuppressWarnings("unused")
- private AddressSet getAddressFactoryAddressSet(WizardState state) {
- Program programFromState = (Program) state.get(programDependencyKey);
- AddressFactory factory = programFromState.getAddressFactory();
- AddressSet everything = new AddressSet();
- AddressSpace[] addressSpaces = factory.getAddressSpaces();
- for (AddressSpace addressSpace : addressSpaces) {
- Address minAddress = addressSpace.getMinAddress();
- Address maxAddress = addressSpace.getMaxAddress();
- AddressRangeImpl range = new AddressRangeImpl(minAddress, maxAddress);
- everything.add(range);
- }
- return everything;
- }
-
- @Override
- public HelpLocation getHelpLocation() {
- return new HelpLocation("VersionTrackingPlugin", "Address_Set_Panel");
- }
-
- @Override
- public void enterPanel(WizardState state) {
- if (panel != null) {
- remove(panel);
- }
- program = (Program) state.get(programDependencyKey);
- AddressSetView addressSetView = (AddressSetView) state.get(addressSetViewKey);
- AddressSetView selection = (AddressSetView) state.get(selectionKey);
- AddressSetChoice addressSetChoice = (AddressSetChoice) state.get(addressSetChoiceKey);
- if (addressSetChoice == null) {
- if (selection != null && !selection.isEmpty()) {
- addressSetChoice = AddressSetChoice.SELECTION;
- }
- else {
- addressSetChoice = AddressSetChoice.ENTIRE_PROGRAM;
- }
- }
- panel =
- new ChooseAddressSetEditorPanel(tool, name, program, selection, addressSetView,
- addressSetChoice);
- panel.addChangeListener(new ChangeListener() {
- @Override
- public void stateChanged(ChangeEvent e) {
- notifyListenersOfValidityChanged();
- }
- });
- add(panel, BorderLayout.CENTER);
- }
-
- @Override
- public WizardPanelDisplayability getPanelDisplayabilityAndUpdateState(
- WizardState state) {
- Boolean value = (Boolean) state.get(VTWizardStateKey.SHOW_ADDRESS_SET_PANELS);
- boolean showPanel = value == null ? false : value.booleanValue();
- if (!showPanel) {
- return WizardPanelDisplayability.DO_NOT_DISPLAY;
- }
- return WizardPanelDisplayability.CAN_BE_DISPLAYED;
- }
-
- @Override
- public void leavePanel(WizardState state) {
- updateStateObjectWithPanelInfo(state);
- }
-
- @Override
- public void updateStateObjectWithPanelInfo(WizardState state) {
- AddressSetView addressSetView = panel.getAddressSetView();
- state.put(addressSetViewKey, addressSetView);
- state.put(addressSetChoiceKey, panel.getAddressSetChoice());
- }
-
- @Override
- public String getTitle() {
- return "Select " + name + " Address Range(s)";
- }
-
- @Override
- public void initialize() {
- // not sure if we need this
- }
-
- @Override
- public boolean isValidInformation() {
- boolean empty = panel.getAddressSetView().isEmpty();
- String msg = empty ? "At least one address range is required" : "";
- notifyListenersOfStatusMessage(msg);
- return !empty;
- }
-}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/LimitAddressSetsPanel.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/LimitAddressSetsPanel.java
deleted file mode 100644
index 1853b6ebdd..0000000000
--- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/LimitAddressSetsPanel.java
+++ /dev/null
@@ -1,109 +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.feature.vt.gui.wizard;
-
-import ghidra.framework.plugintool.PluginTool;
-import ghidra.util.HelpLocation;
-
-import java.awt.GridLayout;
-
-import docking.wizard.*;
-
-public class LimitAddressSetsPanel extends AbstractMageJPanel {
-
- private AddressSetPanel sourcePanel;
- private AddressSetPanel destinationPanel;
-
- public LimitAddressSetsPanel(PluginTool tool) {
-
- setLayout(new GridLayout());
- sourcePanel =
- new AddressSetPanel(tool, "Source", VTWizardStateKey.SOURCE_PROGRAM_FILE,
- VTWizardStateKey.SOURCE_PROGRAM, VTWizardStateKey.SOURCE_ADDRESS_SET_VIEW,
- VTWizardStateKey.SOURCE_SELECTION, VTWizardStateKey.SOURCE_ADDRESS_SET_CHOICE);
- destinationPanel =
- new AddressSetPanel(tool, "Destination", VTWizardStateKey.DESTINATION_PROGRAM_FILE,
- VTWizardStateKey.DESTINATION_PROGRAM,
- VTWizardStateKey.DESTINATION_ADDRESS_SET_VIEW,
- VTWizardStateKey.DESTINATION_SELECTION,
- VTWizardStateKey.DESTINATION_ADDRESS_SET_CHOICE);
- add(sourcePanel);
- add(destinationPanel);
- }
-
- @Override
- public HelpLocation getHelpLocation() {
- return new HelpLocation("VersionTrackingPlugin", "Select_Address_Ranges_Panel");
- }
-
- @Override
- public void addDependencies(WizardState state) {
- sourcePanel.addDependencies(state);
- destinationPanel.addDependencies(state);
- }
-
- @Override
- public void dispose() {
- sourcePanel.dispose();
- destinationPanel.dispose();
- }
-
- @Override
- public void enterPanel(WizardState state) {
- sourcePanel.enterPanel(state);
- destinationPanel.enterPanel(state);
- }
-
- @Override
- public WizardPanelDisplayability getPanelDisplayabilityAndUpdateState(
- WizardState state) {
- WizardPanelDisplayability sourceDisplayability =
- sourcePanel.getPanelDisplayabilityAndUpdateState(state);
- destinationPanel.getPanelDisplayabilityAndUpdateState(state);
- // Use the displayability of the source panel as that of the source/destination combined.
- return sourceDisplayability;
- }
-
- @Override
- public void leavePanel(WizardState state) {
- sourcePanel.leavePanel(state);
- destinationPanel.leavePanel(state);
- }
-
- @Override
- public void updateStateObjectWithPanelInfo(WizardState state) {
- sourcePanel.updateStateObjectWithPanelInfo(state);
- destinationPanel.updateStateObjectWithPanelInfo(state);
- }
-
- @Override
- public String getTitle() {
- return "Select Address Range(s)";
- }
-
- @Override
- public void initialize() {
- sourcePanel.initialize();
- destinationPanel.initialize();
- }
-
- @Override
- public boolean isValidInformation() {
- return sourcePanel.isValidInformation() && destinationPanel.isValidInformation();
-
- }
-}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/NewSessionPanel.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/NewSessionPanel.java
deleted file mode 100644
index e4b0894a35..0000000000
--- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/NewSessionPanel.java
+++ /dev/null
@@ -1,611 +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.feature.vt.gui.wizard;
-
-import static ghidra.framework.main.DataTreeDialogType.*;
-
-import java.awt.*;
-import java.util.*;
-
-import javax.swing.*;
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.DocumentListener;
-
-import org.apache.commons.lang3.StringUtils;
-
-import docking.widgets.button.BrowseButton;
-import docking.widgets.label.GDLabel;
-import docking.wizard.*;
-import generic.theme.GIcon;
-import generic.theme.GThemeDefaults.Ids.Fonts;
-import generic.theme.Gui;
-import ghidra.app.util.task.OpenProgramRequest;
-import ghidra.app.util.task.OpenProgramTask;
-import ghidra.feature.vt.api.util.VTSessionFileUtil;
-import ghidra.framework.main.DataTreeDialog;
-import ghidra.framework.model.DomainFile;
-import ghidra.framework.model.DomainFolder;
-import ghidra.framework.plugintool.PluginTool;
-import ghidra.program.model.listing.Program;
-import ghidra.util.*;
-import ghidra.util.task.TaskLauncher;
-
-/**
- * Version tracking wizard panel to create a new session.
- */
-public class NewSessionPanel extends AbstractMageJPanel {
-
- // The maximum length to allow for each program's name portion of the session name.
- // In the filesystem API, when saved, the session name is restricted to 60 characters.
- // The default VTSession name combines the two program names so split the length between them,
- // minus text we add below.
- private static final int VTSESSION_NAME_PROGRAM_NAME_MAX_LENGTH = 28;
- private static final int TEXT_FIELD_LENGTH = 40;
- private static final Icon SWAP_ICON = new GIcon("icon.version.tracking.new.session.swap");
- private static final Icon INFO_ICON = new GIcon("icon.version.tracking.new.session.info");
-
- private JTextField sourceField;
- private JTextField destinationField;
- private JButton sourceBrowseButton;
- private JButton destinationBrowseButton;
- private JButton swapProgramsButton;
- private JTextField sessionNameField;
- private JTextField folderNameField;
- private DomainFolder folder;
- private PluginTool tool;
-
- // All program info objects that the user may have opened while using the wizard. We keep
- // these around to avoid reopening them and any accompanying upgrading that may be required.
- // These will be released when the wizard is finished.
- private Map allProgramInfos = new HashMap<>();
- private ProgramInfo sourceProgramInfo;
- private ProgramInfo destinationProgramInfo;
-
- NewSessionPanel(PluginTool tool) {
-
- this.tool = tool;
- setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
-
- JLabel folderLabel = new GDLabel("Project folder ");
- folderLabel.setHorizontalAlignment(SwingConstants.RIGHT);
- folderLabel.setToolTipText("The folder to store the new Version Tracking Session");
- folderNameField = new JTextField();
- Gui.registerFont(folderNameField, Fonts.MONOSPACED);
- folderNameField.setEditable(false); // force user to browse to choose
-
- JButton browseFolderButton = new BrowseButton();
- browseFolderButton.addActionListener(e -> browseDataTreeFolders());
-
- JLabel newSessionLabel = new GDLabel("New Session Name: ");
- newSessionLabel.setToolTipText("The name for the new Version Tracking Session");
- newSessionLabel.setHorizontalAlignment(SwingConstants.RIGHT);
-
- sessionNameField = new JTextField(TEXT_FIELD_LENGTH);
- sessionNameField.getDocument().addDocumentListener(new DocumentListener() {
- @Override
- public void changedUpdate(DocumentEvent e) {
- // do nothing
- }
-
- @Override
- public void insertUpdate(DocumentEvent e) {
- notifyListenersOfValidityChanged();
- }
-
- @Override
- public void removeUpdate(DocumentEvent e) {
- notifyListenersOfValidityChanged();
- }
- });
-
- JLabel sourceLabel = new GDLabel("Source Program: ");
- sourceLabel.setIcon(INFO_ICON);
- sourceLabel.setToolTipText("Analyzed program with markup to transfer");
- sourceLabel.setHorizontalAlignment(SwingConstants.RIGHT);
-
- JLabel destinationLabel = new GDLabel("Destination Program: ");
- destinationLabel.setIcon(INFO_ICON);
- destinationLabel.setToolTipText("New program that receives the transferred markup");
- destinationLabel.setHorizontalAlignment(SwingConstants.RIGHT);
-
- sourceField = new JTextField(TEXT_FIELD_LENGTH);
- sourceField.setEditable(false);
-
- destinationField = new JTextField(TEXT_FIELD_LENGTH);
- destinationField.setEditable(false);
-
- sourceBrowseButton = createSourceBrowseButton();
- destinationBrowseButton = createDestinationBrowseButton();
-
- swapProgramsButton = new JButton(SWAP_ICON);
- swapProgramsButton.setText("swap");
- swapProgramsButton.setName("SWAP_BUTTON");
- swapProgramsButton.addActionListener(arg0 -> swapPrograms());
-
- JPanel mainPanel = new JPanel(new GridBagLayout());
- GridBagConstraints gbc = new GridBagConstraints();
-
- gbc.gridx = 0;
- gbc.gridy = 0;
- mainPanel.add(Box.createVerticalStrut(15), gbc);
-
- gbc.gridy++;
- gbc.fill = GridBagConstraints.HORIZONTAL;
- mainPanel.add(folderLabel, gbc);
-
- gbc.gridx++;
- mainPanel.add(folderNameField, gbc);
-
- gbc.gridx++;
- mainPanel.add(Box.createHorizontalStrut(5), gbc);
-
- gbc.gridx++;
- mainPanel.add(browseFolderButton, gbc);
-
- gbc.gridx = 0;
- gbc.gridy++;
- mainPanel.add(Box.createVerticalStrut(10), gbc);
-
- gbc.gridy++;
- gbc.fill = GridBagConstraints.HORIZONTAL;
- mainPanel.add(newSessionLabel, gbc);
-
- gbc.gridx++;
- mainPanel.add(sessionNameField, gbc);
-
- gbc.gridx = 0;
- gbc.gridy++;
- mainPanel.add(Box.createVerticalStrut(15), gbc);
-
- gbc.gridy++;
- gbc.gridwidth = 4;
- mainPanel.add(new JSeparator(), gbc);
-
- gbc.gridy++;
- gbc.gridwidth = 1;
- mainPanel.add(Box.createVerticalStrut(25), gbc);
-
- gbc.gridy++;
- mainPanel.add(sourceLabel, gbc);
-
- gbc.gridx++;
- mainPanel.add(sourceField, gbc);
-
- gbc.gridx += 2;
- mainPanel.add(sourceBrowseButton, gbc);
-
- gbc.gridx = 0;
- gbc.gridy++;
- gbc.fill = GridBagConstraints.NONE;
- gbc.gridwidth = 4;
- mainPanel.add(swapProgramsButton, gbc);
-
- gbc.gridwidth = 1;
- gbc.gridy++;
- gbc.fill = GridBagConstraints.HORIZONTAL;
- mainPanel.add(destinationLabel, gbc);
-
- gbc.gridx++;
- mainPanel.add(destinationField, gbc);
-
- gbc.gridx += 2;
- mainPanel.add(destinationBrowseButton, gbc);
-
- gbc.gridx = 0;
- gbc.gridy++;
- mainPanel.add(Box.createVerticalStrut(25), gbc);
-
- gbc.gridy++;
- gbc.gridwidth = 4;
- mainPanel.add(new JSeparator(), gbc);
-
- gbc.gridy++;
- gbc.gridwidth = 1;
- mainPanel.add(Box.createVerticalStrut(60), gbc);
-
- setLayout(new BorderLayout());
- add(mainPanel, BorderLayout.NORTH);
- }
-
- private void initializePrograms(WizardState state) {
- DomainFile source = (DomainFile) state.get(VTWizardStateKey.SOURCE_PROGRAM_FILE);
- DomainFile destintation = (DomainFile) state.get(VTWizardStateKey.DESTINATION_PROGRAM_FILE);
-
- if (source != null) {
- setSourceProgram(source);
- }
- if (destintation != null) {
- setDestinationProgram(destintation);
- }
- }
-
- /**
- * Presents the user with a tree of the existing project folders and allows
- * them to pick one
- */
- private void browseDataTreeFolders() {
- final DataTreeDialog dataTreeDialog =
- new DataTreeDialog(this, "Choose a project folder", CHOOSE_FOLDER);
-
- dataTreeDialog.addOkActionListener(e -> {
- dataTreeDialog.close();
- setFolder(dataTreeDialog.getDomainFolder());
- });
- dataTreeDialog.showComponent();
- }
-
- void setFolder(DomainFolder folder) {
- this.folder = folder;
-
- if (folder != null) {
- folderNameField.setText(folder.toString());
- }
- else {
- folderNameField.setText("< Choose a folder >");
- }
-
- notifyListenersOfValidityChanged();
- }
-
- private void setSourceProgram(DomainFile programFile) {
- notifyListenersOfStatusMessage(" ");
-
- String path;
- if (programFile == null) {
- sourceProgramInfo = null;
- path = "";
- }
- else {
- sourceProgramInfo =
- allProgramInfos.computeIfAbsent(programFile, file -> new ProgramInfo(file));
- path = programFile.getPathname();
- }
-
- sourceField.setText(path);
-
- updateSessionNameIfBlank();
- notifyListenersOfValidityChanged();
- }
-
- private void updateSessionNameIfBlank() {
- if (!StringUtils.isBlank(sessionNameField.getText())) {
- return;
- }
- if (sourceProgramInfo == null || destinationProgramInfo == null) {
- return;
- }
-
- String defaultSessionName =
- createVTSessionName(sourceProgramInfo.getName(), destinationProgramInfo.getName());
- sessionNameField.setText(defaultSessionName);
- }
-
- private String createVTSessionName(String sourceName, String destinationName) {
-
- // if together they are within the bounds just return session name with both full names
- if (sourceName.length() + destinationName.length() <= 2 *
- VTSESSION_NAME_PROGRAM_NAME_MAX_LENGTH) {
- return "VT_" + sourceName + "_" + destinationName;
- }
-
- // give destination name all space not used by source name
- if (sourceName.length() < VTSESSION_NAME_PROGRAM_NAME_MAX_LENGTH) {
- int leftover = VTSESSION_NAME_PROGRAM_NAME_MAX_LENGTH - sourceName.length();
- destinationName = StringUtilities.trimMiddle(destinationName,
- VTSESSION_NAME_PROGRAM_NAME_MAX_LENGTH + leftover);
- return "VT_" + sourceName + "_" + destinationName;
- }
-
- // give source name all space not used by destination name
- if (destinationName.length() < VTSESSION_NAME_PROGRAM_NAME_MAX_LENGTH) {
- int leftover = VTSESSION_NAME_PROGRAM_NAME_MAX_LENGTH - destinationName.length();
- sourceName = StringUtilities.trimMiddle(sourceName,
- VTSESSION_NAME_PROGRAM_NAME_MAX_LENGTH + leftover);
- return "VT_" + sourceName + "_" + destinationName;
- }
-
- // if both too long, shorten both of them
- sourceName = StringUtilities.trimMiddle(sourceName, VTSESSION_NAME_PROGRAM_NAME_MAX_LENGTH);
- destinationName =
- StringUtilities.trimMiddle(destinationName, VTSESSION_NAME_PROGRAM_NAME_MAX_LENGTH);
-
- return "VT_" + sourceName + "_" + destinationName;
- }
-
- private void setDestinationProgram(DomainFile programFile) {
- notifyListenersOfStatusMessage(" ");
-
- String path;
- if (programFile == null) {
- destinationProgramInfo = null;
- path = "";
- }
- else {
- destinationProgramInfo =
- allProgramInfos.computeIfAbsent(programFile, file -> new ProgramInfo(file));
- path = programFile.getPathname();
- }
-
- destinationField.setText(path);
- updateSessionNameIfBlank();
- notifyListenersOfValidityChanged();
- }
-
- private void swapPrograms() {
- notifyListenersOfStatusMessage(" ");
-
- ProgramInfo temp = destinationProgramInfo;
- destinationProgramInfo = sourceProgramInfo;
- sourceProgramInfo = temp;
-
- if (sourceProgramInfo != null) {
- sourceField.setText(sourceProgramInfo.getPathname());
- }
- else {
- sourceField.setText("");
- }
-
- if (destinationProgramInfo != null) {
- destinationField.setText(destinationProgramInfo.getPathname());
- }
- else {
- destinationField.setText("");
- }
-
- notifyListenersOfValidityChanged();
- }
-
- @Override
- public HelpLocation getHelpLocation() {
- return new HelpLocation("VersionTrackingPlugin", "New_Session_Panel");
- }
-
- private void releaseConsumers() {
-
- for (ProgramInfo info : allProgramInfos.values()) {
- info.release(tool);
- }
-
- allProgramInfos.clear();
- }
-
- @Override
- public void enterPanel(WizardState state) {
- initializePrograms(state);
- }
-
- @Override
- public WizardPanelDisplayability getPanelDisplayabilityAndUpdateState(
- WizardState state) {
- return WizardPanelDisplayability.MUST_BE_DISPLAYED;
- }
-
- @Override
- public void leavePanel(WizardState state) {
- updateStateObjectWithPanelInfo(state);
- }
-
- @Override
- public void updateStateObjectWithPanelInfo(WizardState state) {
- state.put(VTWizardStateKey.SOURCE_PROGRAM_FILE, sourceProgramInfo.getFile());
- state.put(VTWizardStateKey.DESTINATION_PROGRAM_FILE, destinationProgramInfo.getFile());
- state.put(VTWizardStateKey.SOURCE_PROGRAM, sourceProgramInfo.getProgram());
- state.put(VTWizardStateKey.DESTINATION_PROGRAM, destinationProgramInfo.getProgram());
- state.put(VTWizardStateKey.SESSION_NAME, sessionNameField.getText());
- state.put(VTWizardStateKey.NEW_SESSION_FOLDER, folder);
- }
-
- private boolean openProgram(ProgramInfo programInfo) {
-
- if (programInfo.hasProgram()) {
- return true; // already open
- }
-
- OpenProgramTask openProgramTask = new OpenProgramTask(programInfo.getFile(), tool);
- new TaskLauncher(openProgramTask, tool.getActiveWindow());
- OpenProgramRequest openProgram = openProgramTask.getOpenProgram();
- programInfo.setProgram(openProgram != null ? openProgram.getProgram() : null);
- return programInfo.hasProgram();
- }
-
- @Override
- public String getTitle() {
- return "New Version Tracking Session";
- }
-
- @Override
- public void initialize() {
- sourceProgramInfo = null;
- destinationProgramInfo = null;
- sessionNameField.setText("");
- sourceField.setText("");
- destinationField.setText("");
- setFolder(tool.getProject().getProjectData().getRootFolder());
- }
-
- @Override
- public boolean isValidInformation() {
-
- if (folder == null) {
- notifyListenersOfStatusMessage("Choose a project folder to continue!");
- return false;
- }
-
- if (sourceProgramInfo == null || destinationProgramInfo == null) {
- return false;
- }
-
- if (sourceProgramInfo.hasSameFile(destinationProgramInfo)) {
- notifyListenersOfStatusMessage("Source and Destination Programs must be different");
- releaseConsumers();
- return false;
- }
-
- String name = sessionNameField.getText().trim();
- if (StringUtils.isBlank(name)) {
- notifyListenersOfStatusMessage("Please enter a name for this session");
- return false;
- }
-
- try {
- tool.getProject().getProjectData().testValidName(name, false);
- }
- catch (InvalidNameException e) {
- notifyListenersOfStatusMessage("'" + name + "' contains invalid characters");
- return false;
- }
-
- DomainFile file = folder.getFile(name);
- if (file != null) {
- notifyListenersOfStatusMessage(
- "'" + file.getPathname() + "' is the name of an existing project file");
- return false;
- }
-
- // Known Issue: Opening programs before comitted to using them (i.e., Next is clicked) seems
- // premature and will subject user to prompts about possible checkout and/or upgrades
- // with possible slow re-disassembly (see GP-4151)
-
- if (!isValidDestinationProgramFile() || !isValidSourceProgramFile()) {
- return false;
- }
-
- if (!openProgram(sourceProgramInfo)) {
- notifyListenersOfStatusMessage(
- "Can't open source program " + sourceProgramInfo.getName());
- return false;
- }
-
- if (!openProgram(destinationProgramInfo)) {
- notifyListenersOfStatusMessage(
- "Can't open destination program " + destinationProgramInfo.getName());
- return false;
- }
-
- notifyListenersOfStatusMessage(" ");
- return true;
- }
-
- private boolean isValidSourceProgramFile() {
- try {
- VTSessionFileUtil.validateSourceProgramFile(sourceProgramInfo.file, false);
- }
- catch (Exception e) {
- notifyListenersOfStatusMessage(e.getMessage());
- return false;
- }
- return true;
- }
-
- private boolean isValidDestinationProgramFile() {
- try {
- VTSessionFileUtil.validateDestinationProgramFile(destinationProgramInfo.file, false,
- false);
- }
- catch (Exception e) {
- notifyListenersOfStatusMessage(e.getMessage());
- return false;
- }
- return true;
- }
-
- @Override
- public void addDependencies(WizardState state) {
- // none
- }
-
- private JButton createSourceBrowseButton() {
- JButton button = new BrowseButton();
- button.setName("SOURCE_BUTTON");
- button.addActionListener(e -> {
- DomainFile programFile = VTWizardUtils.chooseDomainFile(NewSessionPanel.this,
- "a source program", VTWizardUtils.PROGRAM_FILTER, null);
- if (programFile != null) {
- setSourceProgram(programFile);
- }
- });
- return button;
- }
-
- private JButton createDestinationBrowseButton() {
- JButton button = new BrowseButton();
- button.setName("DESTINATION_BUTTON");
- button.addActionListener(e -> {
- DomainFile programFile = VTWizardUtils.chooseDomainFile(NewSessionPanel.this,
- "a destination program", VTWizardUtils.PROGRAM_FILTER, null);
- if (programFile != null) {
- setDestinationProgram(programFile);
- }
- });
- return button;
- }
-
- @Override
- public void dispose() {
- releaseConsumers();
- }
-
- // simple object to track a domain file and its program
- private class ProgramInfo {
-
- private Program program;
- private DomainFile file;
-
- public ProgramInfo(DomainFile file) {
- this.file = Objects.requireNonNull(file);
- }
-
- void setProgram(Program program) {
- this.program = program;
- }
-
- Program getProgram() {
- return program;
- }
-
- DomainFile getFile() {
- return file;
- }
-
- String getPathname() {
- return file.getPathname();
- }
-
- String getName() {
- return file.getName();
- }
-
- void release(Object consumer) {
- if (program == null) {
- return;
- }
-
- if (program.getConsumerList().contains(consumer)) {
- program.release(consumer);
- }
-
- program = null;
- }
-
- boolean hasSameFile(ProgramInfo other) {
- return file.getPathname().equals(other.getPathname());
- }
-
- boolean hasProgram() {
- return program != null;
- }
- }
-}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/OptionsPanel.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/OptionsPanel.java
deleted file mode 100644
index eecde4e144..0000000000
--- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/OptionsPanel.java
+++ /dev/null
@@ -1,233 +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.feature.vt.gui.wizard;
-
-import java.awt.BorderLayout;
-import java.awt.Dimension;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.util.*;
-
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-
-import docking.options.editor.OptionsEditorPanel;
-import docking.wizard.*;
-import ghidra.feature.vt.api.main.VTProgramCorrelatorFactory;
-import ghidra.feature.vt.api.util.VTOptions;
-import ghidra.framework.options.EditorStateFactory;
-import ghidra.framework.options.Options;
-import ghidra.util.HelpLocation;
-import ghidra.util.layout.MiddleLayout;
-import ghidra.util.layout.VerticalLayout;
-import util.CollectionUtils;
-
-public class OptionsPanel extends AbstractMageJPanel {
-
- private static final Dimension DEFAULT_PREFERRED_SIZE = new Dimension(650, 350);
-
- private List optionsEditorPanelList;
- private List optionsList = null;
- private PropertyChangeListener propertyChangeListener = new PropertyChangeListener() {
- @Override
- public void propertyChange(PropertyChangeEvent evt) {
- notifyListenersOfValidityChanged();
- }
- };
-
- OptionsPanel() {
- super(new BorderLayout());
- // restricting use?
- }
-
- @Override
- public HelpLocation getHelpLocation() {
- if (optionsList != null) {
- for (VTOptions options : optionsList) {
- if (options != null) {
- HelpLocation helpLocation = options.getOptionsHelpLocation();
- if (helpLocation != null) {
- return helpLocation;
- }
- }
- }
- }
-
- // default
- return new HelpLocation("VersionTrackingPlugin", "Options_Panel");
- }
-
- @Override
- public Dimension getPreferredSize() {
- Dimension preferredSize = super.getPreferredSize();
- if (preferredSize.width < DEFAULT_PREFERRED_SIZE.width) {
- return DEFAULT_PREFERRED_SIZE;
- }
- return preferredSize;
- }
-
- @Override
- public void dispose() {
- if (optionsEditorPanelList != null) {
- removeAll();
- optionsEditorPanelList = null;
- optionsList = null;
- }
- }
-
- @Override
- public void enterPanel(WizardState state) {
- dispose();
- List correlatorFactoryList = getCorrelators(state);
-
- optionsList = getCorrelatorOptions(state);
- if (optionsList == null) {
- optionsList = generateDefaultOptions(state);
- }
-
- JPanel panel = new JPanel(new VerticalLayout(30));
-
- optionsEditorPanelList = new ArrayList();
- for (int i = 0; i < correlatorFactoryList.size(); i++) {
- String correlatorName = correlatorFactoryList.get(i).getName();
- String title = correlatorName + " Options";
- if (optionsList.get(i) == null) {
- continue;
- }
-
- EditorStateFactory editorStateFactory = new EditorStateFactory();
- Options options = optionsList.get(i);
- List optionNames = options.getLeafOptionNames();
- if (optionNames.isEmpty()) {
- continue;
- }
- Collections.sort(optionNames);
- OptionsEditorPanel optionsPanel =
- new OptionsEditorPanel(title, options, optionNames, editorStateFactory);
- optionsPanel.setOptionsPropertyChangeListener(propertyChangeListener);
- optionsEditorPanelList.add(optionsPanel);
- panel.add(optionsPanel);
- }
- JPanel outerPanel = new JPanel(new MiddleLayout());
- outerPanel.add(panel);
- JScrollPane scrollPane = new JScrollPane(outerPanel);
- scrollPane.getVerticalScrollBar().setUnitIncrement(5);
- add(scrollPane);
- }
-
- private List generateDefaultOptions(WizardState state) {
- List list = new ArrayList();
- List correlatorFactoryList = getCorrelators(state);
- for (VTProgramCorrelatorFactory vtProgramCorrelatorFactory : correlatorFactoryList) {
- list.add(vtProgramCorrelatorFactory.createDefaultOptions());
- }
- return list;
- }
-
- private List getCorrelatorOptions(WizardState state) {
- List> list = (List>) state.get(VTWizardStateKey.PROGRAM_CORRELATOR_OPTIONS_LIST);
- if (list == null) {
- return null;
- }
- return CollectionUtils.asList(list, VTOptions.class);
- }
-
- private List getCorrelators(WizardState state) {
- List> list = (List>) state.get(VTWizardStateKey.PROGRAM_CORRELATOR_FACTORY_LIST);
- if (list == null) {
- return null;
- }
- return CollectionUtils.asList(list, VTProgramCorrelatorFactory.class);
- }
-
- @Override
- public WizardPanelDisplayability getPanelDisplayabilityAndUpdateState(
- WizardState state) {
-
- List tmpOptions = getCorrelatorOptions(state);
- if (tmpOptions == null) {
- tmpOptions = generateDefaultOptions(state);
- }
- for (VTOptions vtOptions : tmpOptions) {
- if (vtOptions == null) {
- continue;
- }
-
- List names = vtOptions.getOptionNames();
- if (names.isEmpty()) {
- continue;
- }
-
- return WizardPanelDisplayability.MUST_BE_DISPLAYED;
- }
- return WizardPanelDisplayability.DO_NOT_DISPLAY;
- }
-
- @Override
- public void leavePanel(WizardState state) {
- updateStateObjectWithPanelInfo(state);
- }
-
- @Override
- public void updateStateObjectWithPanelInfo(WizardState state) {
- if (optionsList != null) {
- applyOptions();
- }
-
- List newOptions =
- optionsList != null ? optionsList : generateDefaultOptions(state);
-
- state.put(VTWizardStateKey.PROGRAM_CORRELATOR_OPTIONS_LIST, newOptions);
- }
-
- @Override
- public String getTitle() {
- return "Correlator Options";
- }
-
- @Override
- public void initialize() {
- // nothing to do
- }
-
- @Override
- public boolean isValidInformation() {
- applyOptions();
- for (VTOptions options : optionsList) {
- if (options != null) {
- if (!options.validate()) {
- return false;
- }
- }
-
- }
- return true;
- }
-
- private void applyOptions() {
- for (OptionsEditorPanel panel : optionsEditorPanelList) {
- panel.apply();
- }
- }
-
- @Override
- public void addDependencies(WizardState state) {
- state.addDependency(VTWizardStateKey.PROGRAM_CORRELATOR_OPTIONS_LIST,
- VTWizardStateKey.PROGRAM_CORRELATOR_FACTORY_LIST);
-
- }
-
-}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/PreconditionsPanel.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/PreconditionsPanel.java
deleted file mode 100644
index 4865f6bee7..0000000000
--- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/PreconditionsPanel.java
+++ /dev/null
@@ -1,252 +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.feature.vt.gui.wizard;
-
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.lang.reflect.Constructor;
-import java.util.*;
-import java.util.List;
-
-import javax.swing.*;
-
-import docking.widgets.conditiontestpanel.*;
-import docking.wizard.*;
-import ghidra.feature.vt.api.main.VTSession;
-import ghidra.feature.vt.gui.validator.VTPreconditionValidator;
-import ghidra.program.model.listing.Program;
-import ghidra.util.HelpLocation;
-import ghidra.util.Msg;
-import ghidra.util.classfinder.ClassSearcher;
-
-public class PreconditionsPanel extends AbstractMageJPanel implements Scrollable {
- private static final Dimension DEFAULT_SIZE = new Dimension(650, 480);
- private ConditionTestPanel conditionsTestPanel;
- private boolean testsDone = false;
- private VTNewSessionWizardManager wizardManager;
-
- public PreconditionsPanel(VTNewSessionWizardManager panelManager) {
-
- this.wizardManager = panelManager;
- setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
- setLayout(new BorderLayout());
-
- JPanel runButtonPanel = new JPanel();
- runButtonPanel.setBorder(BorderFactory.createEmptyBorder(20, 0, 0, 0));
- runButtonPanel.setLayout(new FlowLayout());
- JButton runTestsButton = new JButton("Run Precondition Checks");
- runTestsButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- conditionsTestPanel.runTests();
- }
- });
- runButtonPanel.add(runTestsButton);
-
- JButton skipTestsButton = new JButton("Skip");
- skipTestsButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- conditionsTestPanel.skipTests();
- wizardManager.getWizardManager().next();
- }
- });
- runButtonPanel.add(skipTestsButton);
-
- add(runButtonPanel, BorderLayout.SOUTH);
- }
-
- @Override
- public HelpLocation getHelpLocation() {
- return new HelpLocation("VersionTrackingPlugin", "Preconditions_Panel");
- }
-
- @Override
- public void addDependencies(WizardState state) {
- state.addDependency(VTWizardStateKey.PRECONDITION_CHECKS_RUN,
- VTWizardStateKey.SOURCE_PROGRAM_FILE);
- state.addDependency(VTWizardStateKey.PRECONDITION_CHECKS_RUN,
- VTWizardStateKey.DESTINATION_PROGRAM_FILE);
-
- state.addDependency(VTWizardStateKey.HIGHEST_PRECONDITION_STATUS,
- VTWizardStateKey.PRECONDITION_CHECKS_RUN);
- }
-
- @Override
- public void dispose() {
- if (conditionsTestPanel != null) {
- conditionsTestPanel.cancel();
- }
- }
-
- @Override
- public void enterPanel(WizardState state) {
- initializeRunState(state);
-
- if (!testsDone) {
- if (conditionsTestPanel != null) {
- remove(conditionsTestPanel);
- }
- conditionsTestPanel = buildConditionPanel(state);
- add(conditionsTestPanel, BorderLayout.CENTER);
- }
- }
-
- private void initializeRunState(WizardState state) {
- Boolean b = (Boolean) state.get(VTWizardStateKey.PRECONDITION_CHECKS_RUN);
- testsDone = b == null ? false : b.booleanValue();
- }
-
- private ConditionTestPanel buildConditionPanel(final WizardState state) {
-
- Program sourceProgram = (Program) state.get(VTWizardStateKey.SOURCE_PROGRAM);
- Program destinationProgram = (Program) state.get(VTWizardStateKey.DESTINATION_PROGRAM);
-
- VTSession existingResults = (VTSession) state.get(VTWizardStateKey.EXISTING_SESSION);
-
- List list =
- getConditionTests(sourceProgram, destinationProgram, existingResults);
- Collections.sort(list, new ConditionsComparator());
- ConditionTestPanel panel = new ConditionTestPanel(list);
- panel.addListener(new ConditionTestListener() {
- @Override
- public void testsCompleted() {
- state.put(VTWizardStateKey.PRECONDITION_CHECKS_RUN, Boolean.valueOf(testsDone));
- testsDone();
- }
- });
- return panel;
- }
-
- private void testsDone() {
- testsDone = true;
- notifyListenersOfValidityChanged();
- if (hasAnyErrorStatus()) {
- Msg.showError(getClass(), this, "Warning - Serious Precondition failures",
- "The precondition checks discovered one or more serious problems. \n\n"
- + "If you continue, your version tracking results may be invalid.\n"
- + "You should review the errors, cancel this wizard, and correct the problems.");
- }
- }
-
- private List getConditionTests(Program sourceProgram,
- Program destinationProgram, VTSession existingResults) throws SecurityException {
- List list = new ArrayList();
-
- List> vtValidatorClasses =
- ClassSearcher.getClasses(VTPreconditionValidator.class);
- for (Class extends VTPreconditionValidator> validatorClass : vtValidatorClasses) {
- try {
- Constructor extends VTPreconditionValidator> ctor =
- validatorClass.getConstructor(Program.class, Program.class, VTSession.class);
- VTPreconditionValidator validator =
- ctor.newInstance(sourceProgram, destinationProgram, existingResults);
- list.add(validator);
- }
- catch (Exception e) {
- Msg.error(this, "error including VTPreconditionValidator " + validatorClass, e);
- }
- }
- return list;
- }
-
- @Override
- public WizardPanelDisplayability getPanelDisplayabilityAndUpdateState(
- WizardState state) {
-
- initializeRunState(state);
- return testsDone ? WizardPanelDisplayability.CAN_BE_DISPLAYED
- : WizardPanelDisplayability.MUST_BE_DISPLAYED;
- }
-
- @Override
- public void leavePanel(WizardState state) {
- updateStateObjectWithPanelInfo(state);
- }
-
- @Override
- public void updateStateObjectWithPanelInfo(WizardState state) {
- state.put(VTWizardStateKey.PRECONDITION_CHECKS_RUN, Boolean.valueOf(testsDone));
- state.put(VTWizardStateKey.HIGHEST_PRECONDITION_STATUS, hasAnyErrorStatus());
- }
-
- private Boolean hasAnyErrorStatus() {
- return conditionsTestPanel.getErrorCount() > 0;
- }
-
- @Override
- public String getTitle() {
- return "Precondition Checklist";
- }
-
- @Override
- public void initialize() {
- // do nothing
- }
-
- @Override
- public boolean isValidInformation() {
- return testsDone;
- }
-
- @Override
- // Overridden to account for the fact that we don't know our preferred size until later in
- // the wizard flow. At that point, the initial size of the wizard is already too small.
- public Dimension getPreferredSize() {
- Dimension superSize = super.getPreferredSize();
- if (superSize.width > DEFAULT_SIZE.width && superSize.height > DEFAULT_SIZE.height) {
- return superSize;
- }
- return DEFAULT_SIZE;
- }
-
- @Override
- public Dimension getPreferredScrollableViewportSize() {
- return getPreferredSize();
- }
-
- @Override
- public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
- return 25;
- }
-
- @Override
- public boolean getScrollableTracksViewportHeight() {
- return true;
- }
-
- @Override
- public boolean getScrollableTracksViewportWidth() {
- return true;
- }
-
- @Override
- public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
- return 10;
- }
-
-//==================================================================================================
-// Inner Classes
-//==================================================================================================
-
- private class ConditionsComparator implements Comparator {
- @Override
- public int compare(ConditionTester o1, ConditionTester o2) {
- return o1.getName().compareTo(o2.getName());
- }
- }
-}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/SummaryPanel.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/SummaryPanel.java
deleted file mode 100644
index 33256dec72..0000000000
--- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/SummaryPanel.java
+++ /dev/null
@@ -1,221 +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.feature.vt.gui.wizard;
-
-import java.awt.BorderLayout;
-import java.util.List;
-
-import javax.swing.*;
-
-import docking.widgets.label.GDHtmlLabel;
-import docking.wizard.*;
-import ghidra.feature.vt.api.main.VTProgramCorrelatorFactory;
-import ghidra.feature.vt.gui.wizard.ChooseAddressSetEditorPanel.AddressSetChoice;
-import ghidra.framework.model.DomainFile;
-import ghidra.util.HTMLUtilities;
-import ghidra.util.HelpLocation;
-import ghidra.util.layout.PairLayout;
-import util.CollectionUtils;
-
-public class SummaryPanel extends AbstractMageJPanel {
- private JLabel labelLabel;
- private JLabel summaryLabel;
- private static String NEW_SUMMARY_PANEL = "New_Session_Summary_Panel";
- private static String ADD_SUMMARY_PANEL = "Add_To_Session_Summary_Panel";
- private String helpName = ADD_SUMMARY_PANEL;
-
- SummaryPanel() {
-
- labelLabel = new GDHtmlLabel();
- summaryLabel = new GDHtmlLabel();
-
- JPanel mainPanel = new JPanel(new PairLayout(5, 10));
- mainPanel.add(labelLabel);
- mainPanel.add(summaryLabel);
-
- setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
- setLayout(new BorderLayout());
- add(mainPanel, BorderLayout.CENTER);
- }
-
- @Override
- public void dispose() {
- // nothing to do
- }
-
- @Override
- public HelpLocation getHelpLocation() {
- return new HelpLocation("VersionTrackingPlugin", helpName);
- }
-
- @Override
- public void enterPanel(WizardState state) {
- StringBuilder label = new StringBuilder();
- StringBuilder summary = new StringBuilder();
-
- label.append("");
- summary.append("");
-
- // session mode
-
- label.append("Operation:");
- String opDescription = (String) state.get(VTWizardStateKey.WIZARD_OP_DESCRIPTION);
- helpName = ((opDescription != null) && opDescription.startsWith("New")) ? NEW_SUMMARY_PANEL
- : ADD_SUMMARY_PANEL;
- summary.append(opDescription);
- label.append("
");
- summary.append("
");
-
- String sessionName = (String) state.get(VTWizardStateKey.SESSION_NAME);
-
- label.append("Session Name:");
- summary.append(sessionName);
- label.append("
");
- summary.append("
");
-
- String sourceProgramName = null;
- String destinationProgramName = null;
-
- DomainFile sourceProgram = (DomainFile) state.get(VTWizardStateKey.SOURCE_PROGRAM_FILE);
- sourceProgramName = sourceProgram.getName();
-
- DomainFile destinationProgram =
- (DomainFile) state.get(VTWizardStateKey.DESTINATION_PROGRAM_FILE);
- destinationProgramName = destinationProgram.getName();
-
- // source program
-
- label.append("Source Program:");
- summary.append(
- sourceProgramName == null ? "(null)" : HTMLUtilities.escapeHTML(sourceProgramName));
- label.append("
");
- summary.append("
");
-
- // destination program
-
- label.append("Destination Program:");
- summary.append(destinationProgramName == null ? "(null)"
- : HTMLUtilities.escapeHTML(destinationProgramName));
- label.append("
");
- summary.append("
");
-
- String correlatorLabel = "";
- String correlatorName = null;
-
- List correlators = getCorrelators(state);
- if (correlators != null) {
- for (VTProgramCorrelatorFactory correlatorFactory : correlators) {
- correlatorName = correlatorFactory.getName();
-
- label.append(correlatorLabel + "Program Correlator:");
- summary.append(correlatorName == null ? "(null)" : correlatorName);
- label.append("
");
- summary.append("
");
-
- }
- }
-
- Boolean excludeAcceptedMatches =
- (Boolean) state.get(VTWizardStateKey.EXCLUDE_ACCEPTED_MATCHES);
- if (excludeAcceptedMatches != null) {
- label.append("Exclude Accepted Matches:");
- summary.append(excludeAcceptedMatches.booleanValue() ? "Yes" : "No");
- label.append("
");
- summary.append("
");
- }
-
- Boolean showAddressSetPanels =
- (Boolean) state.get(VTWizardStateKey.SHOW_ADDRESS_SET_PANELS);
- if (showAddressSetPanels != null) {
- boolean manuallySpecifiedAddresses = showAddressSetPanels.booleanValue();
- AddressSetChoice sourceAddressSetChoice =
- (AddressSetChoice) state.get(VTWizardStateKey.SOURCE_ADDRESS_SET_CHOICE);
- AddressSetChoice destinationAddressSetChoice =
- (AddressSetChoice) state.get(VTWizardStateKey.DESTINATION_ADDRESS_SET_CHOICE);
- String sourceAddressesInfo =
- (sourceAddressSetChoice == AddressSetChoice.MANUALLY_DEFINED) ? "Manually Defined"
- : ((sourceAddressSetChoice == AddressSetChoice.SELECTION))
- ? "Source Tool Selection"
- : "Entire Source Program";
- String destinationAddressesInfo =
- (destinationAddressSetChoice == AddressSetChoice.MANUALLY_DEFINED)
- ? "Manually Defined"
- : ((destinationAddressSetChoice == AddressSetChoice.SELECTION))
- ? "Destination Tool Selection"
- : "Entire Destination Program";
-
- label.append("Source Address Set:");
- summary.append(sourceAddressesInfo);
- label.append("
");
- summary.append("
");
-
- label.append("Destination Address Set:");
- summary.append(destinationAddressesInfo);
- label.append("
");
- summary.append("
");
- }
-
- label.append("");
- summary.append("");
-
- labelLabel.setText(label.toString());
- summaryLabel.setText(summary.toString());
- }
-
- private List getCorrelators(WizardState state) {
- List> list = (List>) state.get(VTWizardStateKey.PROGRAM_CORRELATOR_FACTORY_LIST);
- if (list == null) {
- return null;
- }
- return CollectionUtils.asList(list, VTProgramCorrelatorFactory.class);
- }
-
- @Override
- public WizardPanelDisplayability getPanelDisplayabilityAndUpdateState(
- WizardState state) {
- return WizardPanelDisplayability.CAN_BE_DISPLAYED;
- }
-
- @Override
- public void leavePanel(WizardState state) {
- updateStateObjectWithPanelInfo(state);
- }
-
- @Override
- public void updateStateObjectWithPanelInfo(WizardState state) {
- // Do nothing. The summary panel only displays information.
- }
-
- @Override
- public String getTitle() {
- return "Summary";
- }
-
- @Override
- public void initialize() {
- // nothing to do
- }
-
- @Override
- public boolean isValidInformation() {
- return true;
- }
-
- @Override
- public void addDependencies(WizardState state) {
- // no dependencies; we just confirm what's going to happen
- }
-}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/VTAddToSessionWizardManager.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/VTAddToSessionWizardManager.java
deleted file mode 100644
index cdb922b1b3..0000000000
--- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/VTAddToSessionWizardManager.java
+++ /dev/null
@@ -1,76 +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.feature.vt.gui.wizard;
-
-import ghidra.feature.vt.api.main.VTSession;
-import ghidra.feature.vt.gui.plugin.VTController;
-import ghidra.program.model.listing.Program;
-import ghidra.util.task.Task;
-import ghidra.util.task.TaskLauncher;
-
-import java.util.ArrayList;
-
-import docking.wizard.*;
-
-public class VTAddToSessionWizardManager extends AbstractMagePanelManager {
-
- private final VTController controller;
-
- public VTAddToSessionWizardManager(VTController controller) {
- super(new WizardState());
- this.controller = controller;
- Program sourceProgram = controller.getSourceProgram();
- Program destinationProgram = controller.getDestinationProgram();
- VTSession session = controller.getSession();
-
- WizardState state = getState();
- state.put(VTWizardStateKey.SOURCE_PROGRAM, sourceProgram);
- state.put(VTWizardStateKey.DESTINATION_PROGRAM, destinationProgram);
- state.put(VTWizardStateKey.SOURCE_PROGRAM_FILE, sourceProgram.getDomainFile());
- state.put(VTWizardStateKey.DESTINATION_PROGRAM_FILE, destinationProgram.getDomainFile());
- state.put(VTWizardStateKey.EXISTING_SESSION, session);
- state.put(VTWizardStateKey.SESSION_NAME, session.getName());
- state.put(VTWizardStateKey.WIZARD_OP_DESCRIPTION, "Add to Version Tracking Session");
- state.put(VTWizardStateKey.SOURCE_SELECTION, controller.getSelectionInSourceTool());
- state.put(VTWizardStateKey.DESTINATION_SELECTION,
- controller.getSelectionInDestinationTool());
-
- }
-
- protected ArrayList> createPanels() {
- ArrayList> panels =
- new ArrayList>();
- panels.add(new CorrelatorPanel(controller.getSession()));
- panels.add(new OptionsPanel());
- panels.add(new AddressSetOptionsPanel());
- panels.add(new LimitAddressSetsPanel(controller.getTool()));
- panels.add(new SummaryPanel());
- return panels;
- }
-
- @Override
- protected void doFinish() {
- try {
- Task task = new AddToSessionTask(controller, getState());
- new TaskLauncher(task, getWizardManager().getComponent());
- }
- finally {
- getWizardManager().completed(true);
- }
- }
-
-}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/VTNewSessionWizardManager.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/VTNewSessionWizardManager.java
deleted file mode 100644
index f56f1212f2..0000000000
--- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/VTNewSessionWizardManager.java
+++ /dev/null
@@ -1,82 +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.feature.vt.gui.wizard;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import docking.wizard.*;
-import ghidra.feature.vt.gui.plugin.VTController;
-import ghidra.framework.model.DomainFile;
-import ghidra.framework.plugintool.PluginTool;
-import ghidra.util.task.Task;
-import ghidra.util.task.TaskLauncher;
-
-public class VTNewSessionWizardManager extends AbstractMagePanelManager {
-
- private final VTController controller;
-
- public VTNewSessionWizardManager(VTController controller) {
- super(new WizardState());
- this.controller = controller;
- getState().put(VTWizardStateKey.WIZARD_OP_DESCRIPTION, "New Version Tracking Session");
- }
-
- public VTNewSessionWizardManager(VTController controller, DomainFile sourceFile,
- DomainFile destinationFile) {
- this(controller);
- getState().put(VTWizardStateKey.SOURCE_PROGRAM_FILE, sourceFile);
- getState().put(VTWizardStateKey.DESTINATION_PROGRAM_FILE, destinationFile);
- }
-
- @Override
- protected List> createPanels() {
- List> panels = new ArrayList<>();
- panels.add(new NewSessionPanel(controller.getTool()));
- panels.add(new PreconditionsPanel(this));
- panels.add(new SummaryPanel());
- return panels;
- }
-
- @Override
- protected void doFinish() {
- try {
- Task task = new CreateNewSessionTask(controller, getState());
- new TaskLauncher(task, getWizardManager().getComponent());
- }
- finally {
- getWizardManager().completed(true);
- cleanup();
- }
- }
-
- @Override
- public void cancel() {
- cleanup();
- }
-
- private void cleanup() {
- List> panels = getPanels();
- for (MagePanel magePanel : panels) {
- magePanel.dispose();
- }
- }
-
- public PluginTool getTool() {
- return controller.getTool();
- }
-
-}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/VTWizardStateKey.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/VTWizardStateKey.java
deleted file mode 100644
index 4e3903426e..0000000000
--- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/VTWizardStateKey.java
+++ /dev/null
@@ -1,45 +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.feature.vt.gui.wizard;
-
-enum VTWizardStateKey {
- WIZARD_OP_DESCRIPTION, EXISTING_SESSION, SESSION_NAME,
-
- SOURCE_PROGRAM_FILE, DESTINATION_PROGRAM_FILE,
-
- SOURCE_PROGRAM, DESTINATION_PROGRAM,
-
- SOURCE_ADDRESS_SET_VIEW, DESTINATION_ADDRESS_SET_VIEW,
-
- PRECONDITION_CHECKS_RUN,
-
- NEW_SESSION_FOLDER,
-
- ADDRESS_RANGES_MODE,
-
- PROGRAM_CORRELATOR_FACTORY_LIST,
-
- PROGRAM_CORRELATOR_OPTIONS_LIST, HIGHEST_PRECONDITION_STATUS,
-
- SHOW_ADDRESS_SET_PANELS,
-
- EXCLUDE_ACCEPTED_MATCHES,
-
- SOURCE_SELECTION, DESTINATION_SELECTION,
-
- SOURCE_ADDRESS_SET_CHOICE, DESTINATION_ADDRESS_SET_CHOICE;
-}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/AddRemoveAddressRangeDialog.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/AddRemoveAddressRangeDialog.java
similarity index 90%
rename from Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/AddRemoveAddressRangeDialog.java
rename to Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/AddRemoveAddressRangeDialog.java
index 850b07c517..96973bb128 100644
--- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/AddRemoveAddressRangeDialog.java
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/AddRemoveAddressRangeDialog.java
@@ -13,9 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package ghidra.feature.vt.gui.wizard;
+package ghidra.feature.vt.gui.wizard.add;
import java.awt.Dimension;
+import java.util.Objects;
+import java.util.function.Consumer;
import javax.swing.*;
@@ -23,7 +25,7 @@ import docking.DialogComponentProvider;
import docking.widgets.label.GDLabel;
import ghidra.app.util.AddressInput;
import ghidra.app.util.HelpTopics;
-import ghidra.program.model.address.Address;
+import ghidra.program.model.address.*;
import ghidra.program.model.listing.Program;
import ghidra.util.HelpLocation;
import ghidra.util.layout.PairLayout;
@@ -31,7 +33,7 @@ import ghidra.util.layout.PairLayout;
public class AddRemoveAddressRangeDialog extends DialogComponentProvider {
private Program program;
- private AddressRangeListener listener;
+ private Consumer addressRangeConsumer;
private JPanel addressRangePanel;
private JLabel minLabel;
@@ -40,10 +42,10 @@ public class AddRemoveAddressRangeDialog extends DialogComponentProvider {
private AddressInput maxAddressField;
protected AddRemoveAddressRangeDialog(String type, String programIndicator, Program program,
- AddressRangeListener listener) {
+ Consumer addressRangeConsumer) {
super(programIndicator + " Address Range", true, true, true, false);
this.program = program;
- this.listener = listener;
+ this.addressRangeConsumer = Objects.requireNonNull(addressRangeConsumer);
setHelpLocation(new HelpLocation(HelpTopics.LABEL, "AddEditDialog"));
addWorkPanel(createAddressRangePanel());
@@ -99,9 +101,7 @@ public class AddRemoveAddressRangeDialog extends DialogComponentProvider {
@Override
protected void okCallback() {
if (isValidRange()) {
- if (listener != null) {
- listener.processAddressRange(getMinAddress(), getMaxAddress());
- }
+ addressRangeConsumer.accept(new AddressRangeImpl(getMinAddress(), getMaxAddress()));
close();
}
}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/AddToSessionData.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/AddToSessionData.java
new file mode 100644
index 0000000000..90938de6a8
--- /dev/null
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/AddToSessionData.java
@@ -0,0 +1,177 @@
+/* ###
+ * 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.feature.vt.gui.wizard.add;
+
+import java.util.*;
+
+import ghidra.feature.vt.api.main.VTProgramCorrelatorFactory;
+import ghidra.feature.vt.api.main.VTSession;
+import ghidra.feature.vt.api.util.VTOptions;
+import ghidra.framework.model.DomainFile;
+import ghidra.program.model.address.AddressSetView;
+import ghidra.program.model.listing.Program;
+
+/**
+ * Wizard data used by the {@link VTAddToSessionWizardModel} and its steps for the "add to version
+ * tracking session" wizard.
+ */
+public class AddToSessionData {
+ public static enum AddressSetChoice {
+ ENTIRE_PROGRAM, SELECTION, MANUALLY_DEFINED
+ }
+
+ private Program sourceProgram;
+ private Program destinationProgram;
+ private VTSession session;
+ private AddressSetView customSourceAddressSet;
+ private AddressSetView customDestinationAddressSet;
+ private AddressSetView sourceSelection;
+ private AddressSetView destinationSelection;
+ private List correlators;
+ private Map optionsMap = new HashMap<>();
+ private boolean shouldExcludeAcceptedMatches;
+ private boolean shouldLimitAddressSets;
+ private AddressSetChoice sourceAddressSetChoice = AddressSetChoice.ENTIRE_PROGRAM;
+ private AddressSetChoice destinationAddressSetChoice = AddressSetChoice.ENTIRE_PROGRAM;
+
+ public void setSourceProgram(Program sourceProgram) {
+ this.sourceProgram = sourceProgram;
+ }
+
+ public Program getSourceProgram() {
+ return sourceProgram;
+ }
+
+ public void setDestinationProgram(Program destinationProgram) {
+ this.destinationProgram = destinationProgram;
+ }
+
+ public Program getDestinationProgram() {
+ return destinationProgram;
+ }
+
+ public void setSession(VTSession session) {
+ this.session = session;
+ }
+
+ public VTSession getSession() {
+ return session;
+ }
+
+ public DomainFile getSourceFile() {
+ return sourceProgram.getDomainFile();
+ }
+
+ public DomainFile getDestinationFile() {
+ return destinationProgram.getDomainFile();
+ }
+
+ public AddressSetChoice getSourceAddressSetChoice() {
+ return sourceAddressSetChoice;
+ }
+
+ public AddressSetChoice getDestinationAddressSetChoice() {
+ return destinationAddressSetChoice;
+ }
+
+ public void setSourceAddressSetChoice(AddressSetChoice choice) {
+ this.sourceAddressSetChoice = choice;
+ }
+
+ public void setDestinationAddressSetChoice(AddressSetChoice choice) {
+ this.destinationAddressSetChoice = choice;
+ }
+
+ public void setSourceSelection(AddressSetView addressSet) {
+ this.sourceSelection = addressSet;
+ // if a source selection is set, the limit option defaults to true;
+ if (addressSet != null && !addressSet.isEmpty()) {
+ shouldLimitAddressSets = true;
+ sourceAddressSetChoice = AddressSetChoice.SELECTION;
+ }
+ }
+
+ public void setDestinationSelection(AddressSetView addresseSet) {
+ this.destinationSelection = addresseSet;
+ // if a destination selection is set, the limit option defaults to true;
+ if (addresseSet != null && !addresseSet.isEmpty()) {
+ shouldLimitAddressSets = true;
+ destinationAddressSetChoice = AddressSetChoice.SELECTION;
+ }
+ }
+
+ public AddressSetView getCustomSourceAddressSet() {
+ return customSourceAddressSet;
+ }
+
+ public void setCustomSourceAddressSet(AddressSetView addressSet) {
+ customSourceAddressSet = addressSet;
+ }
+
+ public void setCustomDestinationAddressSet(AddressSetView addressSet) {
+ customDestinationAddressSet = addressSet;
+ }
+
+ public AddressSetView getCustomDestinationAddressSet() {
+ return customDestinationAddressSet;
+ }
+
+ public AddressSetView getSourceSelection() {
+ return sourceSelection;
+ }
+
+ public AddressSetView getDestinationSelection() {
+ return destinationSelection;
+ }
+
+ public List getCorrelators() {
+ return correlators;
+ }
+
+ public void setCorrelators(List correlators) {
+ if (!correlators.equals(this.correlators)) {
+ this.correlators = correlators;
+ // whenever the set of correlators changes, reset the options to force options panel
+ // to show
+ optionsMap = null;
+ }
+ }
+
+ public void setOptions(Map optionsMap) {
+ this.optionsMap = optionsMap;
+ }
+
+ public Map getOptions() {
+ return optionsMap;
+ }
+
+ public boolean shouldExcludeAcceptedMatches() {
+ return shouldExcludeAcceptedMatches;
+ }
+
+ public void setShouldExcludeAcceptedMatches(boolean b) {
+ shouldExcludeAcceptedMatches = b;
+ }
+
+ public boolean shouldLimitAddressSets() {
+ return shouldLimitAddressSets;
+ }
+
+ public void setShouldLimitAddressSets(boolean b) {
+ shouldLimitAddressSets = b;
+ }
+
+}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/AddToSessionTask.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/AddToSessionTask.java
similarity index 64%
rename from Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/AddToSessionTask.java
rename to Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/AddToSessionTask.java
index b32adf5aba..aa72881c8d 100644
--- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/AddToSessionTask.java
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/AddToSessionTask.java
@@ -4,25 +4,23 @@
* 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.feature.vt.gui.wizard;
+package ghidra.feature.vt.gui.wizard.add;
import java.util.*;
-import docking.wizard.WizardState;
import ghidra.feature.vt.api.main.*;
import ghidra.feature.vt.api.util.VTMatchUtil;
import ghidra.feature.vt.api.util.VTOptions;
import ghidra.feature.vt.gui.plugin.VTController;
-import ghidra.feature.vt.gui.wizard.ChooseAddressSetEditorPanel.AddressSetChoice;
import ghidra.framework.data.DomainObjectAdapterDB;
import ghidra.program.model.address.AddressSet;
import ghidra.program.model.address.AddressSetView;
@@ -31,16 +29,15 @@ import ghidra.util.Msg;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.Task;
import ghidra.util.task.TaskMonitor;
-import util.CollectionUtils;
public class AddToSessionTask extends Task {
- private final WizardState state;
+ private final AddToSessionData data;
private final VTController controller;
- public AddToSessionTask(VTController controller, WizardState state) {
+ public AddToSessionTask(VTController controller, AddToSessionData data) {
super("Merge Version Tracking Session", true, true, true);
this.controller = controller;
- this.state = state;
+ this.data = data;
}
@Override
@@ -51,49 +48,10 @@ public class AddToSessionTask extends Task {
Program sourceProgram = session.getSourceProgram();
Program destinationProgram = session.getDestinationProgram();
- Boolean value = (Boolean) state.get(VTWizardStateKey.EXCLUDE_ACCEPTED_MATCHES);
- boolean excludeAcceptedMatches = (value == null) ? false : value.booleanValue();
+ boolean excludeAcceptedMatches = data.shouldExcludeAcceptedMatches();
- AddressSetChoice sourceAddressSetChoice =
- (AddressSetChoice) state.get(VTWizardStateKey.SOURCE_ADDRESS_SET_CHOICE);
- AddressSetChoice destinationAddressSetChoice =
- (AddressSetChoice) state.get(VTWizardStateKey.DESTINATION_ADDRESS_SET_CHOICE);
- if (sourceAddressSetChoice == null) {
- sourceAddressSetChoice = AddressSetChoice.ENTIRE_PROGRAM;
- }
- if (destinationAddressSetChoice == null) {
- destinationAddressSetChoice = AddressSetChoice.ENTIRE_PROGRAM;
- }
-
- AddressSetView sourceAddressSet;
- switch (sourceAddressSetChoice) {
- case SELECTION:
- sourceAddressSet = (AddressSetView) state.get(VTWizardStateKey.SOURCE_SELECTION);
- break;
- case MANUALLY_DEFINED:
- sourceAddressSet =
- (AddressSetView) state.get(VTWizardStateKey.SOURCE_ADDRESS_SET_VIEW);
- break;
- case ENTIRE_PROGRAM:
- default:
- sourceAddressSet = sourceProgram.getMemory();
- break;
- }
- AddressSetView destinationAddressSet;
- switch (destinationAddressSetChoice) {
- case SELECTION:
- destinationAddressSet =
- (AddressSetView) state.get(VTWizardStateKey.DESTINATION_SELECTION);
- break;
- case MANUALLY_DEFINED:
- destinationAddressSet =
- (AddressSetView) state.get(VTWizardStateKey.DESTINATION_ADDRESS_SET_VIEW);
- break;
- case ENTIRE_PROGRAM:
- default:
- destinationAddressSet = destinationProgram.getMemory();
- break;
- }
+ AddressSetView sourceAddressSet = getSourceAddressSet();
+ AddressSetView destinationAddressSet = getDestinationAddressSet();
if (excludeAcceptedMatches) {
sourceAddressSet = excludeAcceptedMatches(sourceAddressSet, true);
@@ -104,14 +62,14 @@ public class AddToSessionTask extends Task {
boolean completedSucessfully = false;
try {
session.setEventsEnabled(false); // prevent table updates while busy
- List correlatorFactories = getCorrelators(state);
- List correlatorOptions = getCorrelatorOptions(state);
+ List correlatorFactories = data.getCorrelators();
+ Map optionsMap = data.getOptions();
List noMatchList = new ArrayList<>();
- for (int i = 0; i < correlatorFactories.size(); i++) {
- VTProgramCorrelatorFactory factory = correlatorFactories.get(i);
+ for (VTProgramCorrelatorFactory factory : correlatorFactories) {
+ VTOptions options = optionsMap.get(factory);
VTProgramCorrelator correlator =
factory.createCorrelator(sourceProgram, sourceAddressSet, destinationProgram,
- destinationAddressSet, correlatorOptions.get(i));
+ destinationAddressSet, options);
VTMatchSet resultSet = correlator.correlate(session, monitor);
if (resultSet.getMatchCount() == 0) {
@@ -150,6 +108,36 @@ public class AddToSessionTask extends Task {
}
}
+ private AddressSetView getSourceAddressSet() {
+ if (!data.shouldLimitAddressSets()) {
+ return data.getSourceProgram().getMemory();
+ }
+ switch (data.getSourceAddressSetChoice()) {
+ case MANUALLY_DEFINED:
+ return data.getCustomSourceAddressSet();
+ case SELECTION:
+ return data.getSourceSelection();
+ case ENTIRE_PROGRAM:
+ default:
+ return data.getSourceProgram().getMemory();
+ }
+ }
+
+ private AddressSetView getDestinationAddressSet() {
+ if (!data.shouldLimitAddressSets()) {
+ return data.getDestinationProgram().getMemory();
+ }
+ switch (data.getDestinationAddressSetChoice()) {
+ case MANUALLY_DEFINED:
+ return data.getCustomDestinationAddressSet();
+ case SELECTION:
+ return data.getDestinationSelection();
+ case ENTIRE_PROGRAM:
+ default:
+ return data.getDestinationProgram().getMemory();
+ }
+ }
+
private void endTransaction(VTSession session, int transactionID,
boolean completedSucessfully) {
if (transactionID == -1) {
@@ -165,21 +153,8 @@ public class AddToSessionTask extends Task {
return -1;
}
- private List getCorrelatorOptions(WizardState stateKey) {
- return CollectionUtils.asList(
- (List>) stateKey.get(VTWizardStateKey.PROGRAM_CORRELATOR_OPTIONS_LIST),
- VTOptions.class);
- }
-
- private List getCorrelators(
- WizardState stateKey) {
- return CollectionUtils.asList(
- (List>) stateKey.get(VTWizardStateKey.PROGRAM_CORRELATOR_FACTORY_LIST),
- VTProgramCorrelatorFactory.class);
- }
-
private AddressSet excludeAcceptedMatches(AddressSetView addrSetView, boolean source) {
- VTSession session = (VTSession) state.get(VTWizardStateKey.EXISTING_SESSION);
+ VTSession session = data.getSession();
AddressSet addrSet = new AddressSet(addrSetView);
if (session != null) {
List matchSets = session.getMatchSets();
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/AddressSetOptionsPanel.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/AddressSetOptionsPanel.java
new file mode 100644
index 0000000000..a7743ac335
--- /dev/null
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/AddressSetOptionsPanel.java
@@ -0,0 +1,90 @@
+/* ###
+ * 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.feature.vt.gui.wizard.add;
+
+import static ghidra.feature.vt.api.main.VTProgramCorrelatorAddressRestrictionPreference.*;
+
+import java.util.List;
+
+import javax.swing.*;
+
+import docking.widgets.checkbox.GCheckBox;
+import ghidra.feature.vt.api.main.VTProgramCorrelatorFactory;
+import ghidra.util.HTMLUtilities;
+import ghidra.util.layout.VerticalLayout;
+
+/**
+ * Panel for choosing the address set to used for performing new correlations when adding to
+ * a version tracking session. Used by the {@link AddressSetOptionsStep}.
+ */
+public class AddressSetOptionsPanel extends JPanel {
+
+ private JCheckBox excludeCheckbox;
+ private JCheckBox limitAddressSetsCheckbox;
+
+ public AddressSetOptionsPanel() { //
+ setBorder(BorderFactory.createEmptyBorder(40, 40, 0, 0));
+
+ excludeCheckbox = new GCheckBox("Exclude accepted matches", false);
+ String excludeAcceptedTooltip = "This option will cause the correlator algorithm " +
+ "to not consider any functions or data that have already been " +
+ "accepted. Using this option can greatly speed up the processing time " +
+ "of the correlator algorithm; however, this options should only be " +
+ "used when you trust that your accepted matches are correct.";
+ excludeCheckbox.setToolTipText(HTMLUtilities.toWrappedHTML(excludeAcceptedTooltip));
+
+ limitAddressSetsCheckbox = new GCheckBox("Limit source and destination address sets");
+ String manuallyLimitTooltip = "Selecting this checkbox will trigger additional wizard " +
+ " panels allowing you to customize the address sets used " +
+ " by the selected algorithm. When not selected, the entire address space is used.";
+
+ limitAddressSetsCheckbox.setToolTipText(
+ HTMLUtilities.toWrappedHTML(manuallyLimitTooltip));
+
+ add(excludeCheckbox);
+ add(limitAddressSetsCheckbox);
+ setLayout(new VerticalLayout(20));
+ }
+
+ public void initialize(AddToSessionData data) {
+
+ excludeCheckbox.setSelected(data.shouldExcludeAcceptedMatches());
+ limitAddressSetsCheckbox.setSelected(data.shouldLimitAddressSets());
+
+ if (allowRestrictions(data.getCorrelators())) {
+ excludeCheckbox.setEnabled(true);
+ }
+ else {
+ excludeCheckbox.setSelected(false);
+ excludeCheckbox.setEnabled(false);
+ }
+ }
+
+ private boolean allowRestrictions(List list) {
+ for (VTProgramCorrelatorFactory factory : list) {
+ if (factory.getAddressRestrictionPreference() != RESTRICTION_NOT_ALLOWED) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void updateChoices(AddToSessionData data) {
+ data.setShouldExcludeAcceptedMatches(excludeCheckbox.isSelected());
+ data.setShouldLimitAddressSets(limitAddressSetsCheckbox.isSelected());
+ }
+
+}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/AddressSetOptionsStep.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/AddressSetOptionsStep.java
new file mode 100644
index 0000000000..6df2375c86
--- /dev/null
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/AddressSetOptionsStep.java
@@ -0,0 +1,67 @@
+/* ###
+ * 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.feature.vt.gui.wizard.add;
+
+import javax.swing.JComponent;
+
+import docking.wizard.WizardModel;
+import docking.wizard.WizardStep;
+import ghidra.util.HelpLocation;
+
+/**
+ * Wizard step for configuring address sets when adding correlations to an existing version
+ * tracking session.
+ */
+public class AddressSetOptionsStep extends WizardStep {
+ private AddressSetOptionsPanel panel;
+
+ protected AddressSetOptionsStep(WizardModel model) {
+ super(model, "Address Set Options",
+ new HelpLocation("VersionTrackingPlugin", "Address_Set_Panel"));
+ panel = new AddressSetOptionsPanel();
+ }
+
+ @Override
+ public void initialize(AddToSessionData data) {
+ panel.initialize(data);
+ }
+
+ @Override
+ public boolean isValid() {
+ return true;
+ }
+
+ @Override
+ public void populateData(AddToSessionData data) {
+ panel.updateChoices(data);
+ }
+
+ @Override
+ public boolean canFinish(AddToSessionData data) {
+ return true;
+ }
+
+ @Override
+ public boolean apply(AddToSessionData data) {
+ return true;
+ }
+
+ @Override
+ public JComponent getComponent() {
+ return panel;
+ }
+
+}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/ChooseAddressSetEditorPanel.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/ChooseAddressSetEditorPanel.java
similarity index 92%
rename from Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/ChooseAddressSetEditorPanel.java
rename to Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/ChooseAddressSetEditorPanel.java
index 7123591adf..7a34b59d77 100644
--- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/ChooseAddressSetEditorPanel.java
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/ChooseAddressSetEditorPanel.java
@@ -4,16 +4,16 @@
* 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.feature.vt.gui.wizard;
+package ghidra.feature.vt.gui.wizard.add;
import java.awt.BorderLayout;
import java.awt.Component;
@@ -28,18 +28,18 @@ import docking.widgets.button.GRadioButton;
import docking.widgets.label.GLabel;
import docking.widgets.list.GList;
import generic.theme.GIcon;
+import ghidra.feature.vt.gui.wizard.add.AddToSessionData.AddressSetChoice;
import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.address.*;
import ghidra.program.model.listing.Program;
import ghidra.util.layout.MiddleLayout;
import ghidra.util.layout.VerticalLayout;
+/**
+ * Panel for manually adjusting address sets.
+ */
public class ChooseAddressSetEditorPanel extends JPanel {
- public static enum AddressSetChoice {
- ENTIRE_PROGRAM, SELECTION, MANUALLY_DEFINED
- }
-
private static Icon ADD_ICON = new GIcon("icon.version.tracking.add");
private static Icon SUBTRACT_ICON = new GIcon("icon.version.tracking.subtract");
@@ -210,18 +210,14 @@ public class ChooseAddressSetEditorPanel extends JPanel {
}
protected void showAddRangeDialog() {
- AddressRangeListener addListener =
- (minAddress, maxAddress) -> addRange(minAddress, maxAddress);
AddRemoveAddressRangeDialog addRangeDialog =
- new AddRemoveAddressRangeDialog("Add", name, program, addListener);
+ new AddRemoveAddressRangeDialog("Add", name, program, r -> addRange(r));
tool.showDialog(addRangeDialog, this.getRootPane());
}
protected void showSubtractRangeDialog() {
- AddressRangeListener subtractListener =
- (minAddress, maxAddress) -> subtractRange(minAddress, maxAddress);
AddRemoveAddressRangeDialog removeRangeDialog =
- new AddRemoveAddressRangeDialog("Remove", name, program, subtractListener);
+ new AddRemoveAddressRangeDialog("Remove", name, program, r -> subtractRange(r));
tool.showDialog(removeRangeDialog, this.getRootPane());
}
@@ -246,14 +242,14 @@ public class ChooseAddressSetEditorPanel extends JPanel {
notifyListeners();
}
- private synchronized void addRange(Address minAddress, Address maxAddress) {
- myCurrentAddressSet.addRange(minAddress, maxAddress);
+ private synchronized void addRange(AddressRange range) {
+ myCurrentAddressSet.add(range);
listModel.setData(myCurrentAddressSet.toList());
notifyListeners();
}
- private synchronized void subtractRange(Address minAddress, Address maxAddress) {
- myCurrentAddressSet.deleteRange(minAddress, maxAddress);
+ private synchronized void subtractRange(AddressRange range) {
+ myCurrentAddressSet.delete(range);
listModel.setData(myCurrentAddressSet.toList());
notifyListeners();
}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/CorrelatorPanel.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/CorrelatorChooserPanel.java
similarity index 62%
rename from Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/CorrelatorPanel.java
rename to Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/CorrelatorChooserPanel.java
index 4bb774ddcd..41ef131d7d 100644
--- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/CorrelatorPanel.java
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/CorrelatorChooserPanel.java
@@ -4,19 +4,20 @@
* 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.feature.vt.gui.wizard;
+package ghidra.feature.vt.gui.wizard.add;
import java.awt.*;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
import javax.swing.*;
@@ -25,21 +26,26 @@ import javax.swing.table.TableColumnModel;
import docking.widgets.table.GTableCellRenderer;
import docking.widgets.table.GTableCellRenderingData;
-import docking.wizard.*;
import ghidra.feature.vt.api.impl.VTProgramCorrelatorInfo;
import ghidra.feature.vt.api.main.*;
-import ghidra.util.HelpLocation;
import ghidra.util.table.GhidraTable;
+import utility.function.Callback;
-public class CorrelatorPanel extends AbstractMageJPanel implements Scrollable {
+/**
+ * Panel for displaying and choosing from a list of version tracking correlators. Used by the
+ * {@link CorrelatorChooserStep} of the "add to version tracking session" wizard.
+ */
+public class CorrelatorChooserPanel extends JPanel {
private VTProgramTableCorrelatorModel model;
private GhidraTable table;
+ private Callback statusChangedCallback;
- CorrelatorPanel(VTSession session) {
+ CorrelatorChooserPanel(VTSession session, Callback statusChangedCallback) {
setLayout(new BorderLayout());
table = createBasicTable(getPreviouslyRunAlgorithms(session));
add(new JScrollPane(table), BorderLayout.CENTER);
+ this.statusChangedCallback = statusChangedCallback;
}
private GhidraTable createBasicTable(Set previouslyRunCorrelators) {
@@ -56,16 +62,16 @@ public class CorrelatorPanel extends AbstractMageJPanel implem
return table;
}
- @Override
- protected void notifyListenersOfValidityChanged() {
- super.notifyListenersOfValidityChanged();
- }
-
@Override
public Dimension getPreferredSize() {
return new Dimension(1000, 400);
}
+ void notifyStatusChanged() {
+ statusChangedCallback.call();
+
+ }
+
private void setColumnSizes() {
TableColumnModel columnModel = table.getColumnModel();
int width = 0;
@@ -102,87 +108,8 @@ public class CorrelatorPanel extends AbstractMageJPanel implem
return set;
}
- @Override
- public void dispose() {
- // nothing to do
- }
-
- @Override
- public HelpLocation getHelpLocation() {
- return new HelpLocation("VersionTrackingPlugin", "Correlator_Panel");
- }
-
- @Override
- public void enterPanel(WizardState state) {
- // nothing to do
- }
-
- static WizardPanelDisplayability correlatorDisplayability(WizardState state) {
- return WizardPanelDisplayability.MUST_BE_DISPLAYED;
- }
-
- @Override
- public WizardPanelDisplayability getPanelDisplayabilityAndUpdateState(
- WizardState state) {
- return correlatorDisplayability(state);
- }
-
- @Override
- public void leavePanel(WizardState state) {
- updateStateObjectWithPanelInfo(state);
- }
-
- @Override
- public void updateStateObjectWithPanelInfo(WizardState state) {
- java.util.List selectedFactories = model.getSelectedFactories();
- if (!selectedFactories.isEmpty()) {
- state.put(VTWizardStateKey.PROGRAM_CORRELATOR_FACTORY_LIST, selectedFactories);
- }
- }
-
- @Override
- public String getTitle() {
- return "Select Correlation Algorithm(s)";
- }
-
- @Override
- public void initialize() {
- // nothing to do
- }
-
- @Override
- public boolean isValidInformation() {
- return !model.getSelectedFactories().isEmpty();
- }
-
- @Override
- public void addDependencies(WizardState state) {
- // no dependencies
- }
-
- @Override
- public Dimension getPreferredScrollableViewportSize() {
- return null;
- }
-
- @Override
- public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
- return 25;
- }
-
- @Override
- public boolean getScrollableTracksViewportHeight() {
- return true;
- }
-
- @Override
- public boolean getScrollableTracksViewportWidth() {
- return true;
- }
-
- @Override
- public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
- return 10;
+ public List getSelectedCorrelators() {
+ return model.getSelectedFactories();
}
//==================================================================================================
@@ -209,4 +136,5 @@ public class CorrelatorPanel extends AbstractMageJPanel implem
return renderer;
}
}
+
}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/CorrelatorChooserStep.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/CorrelatorChooserStep.java
new file mode 100644
index 0000000000..7617a92588
--- /dev/null
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/CorrelatorChooserStep.java
@@ -0,0 +1,75 @@
+/* ###
+ * 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.feature.vt.gui.wizard.add;
+
+import java.util.List;
+
+import javax.swing.JComponent;
+
+import docking.wizard.WizardStep;
+import ghidra.feature.vt.api.main.VTProgramCorrelatorFactory;
+import ghidra.feature.vt.api.main.VTSession;
+import ghidra.util.HelpLocation;
+
+/**
+ * Wizard step for choosing which correlators to run when adding to an existing version
+ * tracking session.
+ */
+public class CorrelatorChooserStep extends WizardStep {
+ private CorrelatorChooserPanel panel;
+
+ public CorrelatorChooserStep(VTAddToSessionWizardModel model, VTSession session) {
+ super(model, "Select Correlation Algorithm(s)",
+ new HelpLocation("VersionTrackingPlugin", "Correlator_Panel"));
+
+ panel = new CorrelatorChooserPanel(session, this::notifyStatusChanged);
+ }
+
+ @Override
+ public void initialize(AddToSessionData data) {
+ // nothing to do
+ }
+
+ @Override
+ public boolean isValid() {
+ List correlators = panel.getSelectedCorrelators();
+ if (!correlators.isEmpty()) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void populateData(AddToSessionData data) {
+ data.setCorrelators(panel.getSelectedCorrelators());
+ }
+
+ @Override
+ public boolean apply(AddToSessionData data) {
+ return true;
+ }
+
+ @Override
+ public JComponent getComponent() {
+ return panel;
+ }
+
+ @Override
+ public boolean canFinish(AddToSessionData data) {
+ return data.getCorrelators() != null;
+ }
+
+}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/LimitAddressSetsPanel.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/LimitAddressSetsPanel.java
new file mode 100644
index 0000000000..df24ba3631
--- /dev/null
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/LimitAddressSetsPanel.java
@@ -0,0 +1,85 @@
+/* ###
+ * 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.feature.vt.gui.wizard.add;
+
+import java.awt.GridLayout;
+
+import javax.swing.JPanel;
+
+import ghidra.feature.vt.gui.wizard.add.AddToSessionData.AddressSetChoice;
+import ghidra.framework.plugintool.PluginTool;
+import ghidra.program.model.address.AddressSetView;
+import ghidra.program.model.listing.Program;
+
+/**
+ * Panel for adjusting address sets for both the source and destination programs at the same time.
+ * Used by the {@link LimitAddressSetsStep} of the "add to version tracking session wizard.
+ */
+public class LimitAddressSetsPanel extends JPanel {
+
+ private ChooseAddressSetEditorPanel sourcePanel;
+ private ChooseAddressSetEditorPanel destinationPanel;
+ private PluginTool tool;
+
+ public LimitAddressSetsPanel(PluginTool tool) {
+
+ this.tool = tool;
+ setLayout(new GridLayout());
+ }
+
+ public void initialize(AddToSessionData data) {
+ removeAll();
+
+ sourcePanel = buildSourcePanel(data);
+ destinationPanel = buildDestinationPanel(data);
+
+ add(sourcePanel);
+ add(destinationPanel);
+ }
+
+ private ChooseAddressSetEditorPanel buildSourcePanel(AddToSessionData data) {
+ Program program = data.getSourceProgram();
+ AddressSetView selection = data.getSourceSelection();
+ AddressSetView set = data.getCustomSourceAddressSet();
+ AddressSetChoice choice = data.getSourceAddressSetChoice();
+ return new ChooseAddressSetEditorPanel(tool, "Source", program, selection, set, choice);
+ }
+
+ private ChooseAddressSetEditorPanel buildDestinationPanel(AddToSessionData data) {
+ Program program = data.getDestinationProgram();
+ AddressSetView selection = data.getDestinationSelection();
+ AddressSetView set = data.getCustomDestinationAddressSet();
+ AddressSetChoice choice = data.getDestinationAddressSetChoice();
+ return new ChooseAddressSetEditorPanel(tool, "Destination", program, selection, set,
+ choice);
+ }
+
+ public void apply(AddToSessionData data) {
+ AddressSetChoice sourceChoice = sourcePanel.getAddressSetChoice();
+ AddressSetChoice destinationChoice = destinationPanel.getAddressSetChoice();
+ data.setSourceAddressSetChoice(sourceChoice);
+ data.setDestinationAddressSetChoice(destinationChoice);
+ data.setCustomSourceAddressSet(null);
+ data.setCustomDestinationAddressSet(null);
+ if (sourceChoice == AddressSetChoice.MANUALLY_DEFINED) {
+ data.setCustomSourceAddressSet(sourcePanel.getAddressSetView());
+ }
+ if (destinationChoice == AddressSetChoice.MANUALLY_DEFINED) {
+ data.setCustomDestinationAddressSet(destinationPanel.getAddressSetView());
+ }
+
+ }
+}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/LimitAddressSetsStep.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/LimitAddressSetsStep.java
new file mode 100644
index 0000000000..8063fa6da1
--- /dev/null
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/LimitAddressSetsStep.java
@@ -0,0 +1,73 @@
+/* ###
+ * 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.feature.vt.gui.wizard.add;
+
+import javax.swing.JComponent;
+
+import docking.wizard.WizardStep;
+import ghidra.framework.plugintool.PluginTool;
+import ghidra.util.HelpLocation;
+
+/**
+ * Wizard step for choosing the addresses to apply for adding correlation runs to an existing
+ * version tracking session.
+ */
+public class LimitAddressSetsStep extends WizardStep {
+ private LimitAddressSetsPanel panel;
+
+ public LimitAddressSetsStep(VTAddToSessionWizardModel model, PluginTool tool) {
+ super(model, "Select Address Range(s)",
+ new HelpLocation("VersionTrackingPlugin", "Select_Address_Ranges_Panel"));
+
+ panel = new LimitAddressSetsPanel(tool);
+ }
+
+ @Override
+ public void initialize(AddToSessionData data) {
+ panel.initialize(data);
+ }
+
+ @Override
+ public boolean isValid() {
+ return true;
+ }
+
+ @Override
+ public boolean apply(AddToSessionData data) {
+ return true;
+ }
+
+ @Override
+ public void populateData(AddToSessionData data) {
+ panel.apply(data);
+ }
+
+ @Override
+ public boolean isApplicable(AddToSessionData data) {
+ return data.shouldLimitAddressSets();
+ }
+
+ @Override
+ public boolean canFinish(AddToSessionData data) {
+ return true;
+ }
+
+ @Override
+ public JComponent getComponent() {
+ return panel;
+ }
+
+}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/OptionsPanel.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/OptionsPanel.java
new file mode 100644
index 0000000000..658816962a
--- /dev/null
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/OptionsPanel.java
@@ -0,0 +1,141 @@
+/* ###
+ * 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.feature.vt.gui.wizard.add;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.util.*;
+
+import javax.swing.*;
+
+import docking.options.editor.OptionsEditorPanel;
+import ghidra.feature.vt.api.main.VTProgramCorrelatorFactory;
+import ghidra.feature.vt.api.util.VTOptions;
+import ghidra.framework.options.EditorStateFactory;
+import ghidra.util.layout.VerticalLayout;
+import utility.function.Callback;
+
+/**
+ * Panel for displaying version tracking correlator options for selected correlators. Used by
+ * the {@link OptionsStep} of the "add to version tracking session" wizard to configure the
+ * selected correlators from a previous step.
+ */
+public class OptionsPanel extends JPanel {
+
+ private static final Dimension DEFAULT_PREFERRED_SIZE = new Dimension(650, 350);
+
+ private List optionsEditorPanelList = new ArrayList<>();
+ private Callback statusChangedCallback;
+ private Map optionsMap = new HashMap<>();
+
+ private JPanel stagingPanel;
+
+ OptionsPanel(Callback statusChangedCallback) {
+ super(new BorderLayout());
+ this.statusChangedCallback = statusChangedCallback;
+
+ stagingPanel = new JPanel(new BorderLayout());
+ stagingPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
+ JScrollPane scrollPane = new JScrollPane(stagingPanel);
+ scrollPane.getVerticalScrollBar().setUnitIncrement(5);
+ add(scrollPane);
+ }
+
+ @Override
+ public Dimension getPreferredSize() {
+ Dimension preferredSize = super.getPreferredSize();
+ if (preferredSize.width < DEFAULT_PREFERRED_SIZE.width) {
+ return DEFAULT_PREFERRED_SIZE;
+ }
+ return preferredSize;
+ }
+
+ public boolean isApplicable(List correlators) {
+ updateOptionsMap(correlators);
+ return !optionsMap.isEmpty();
+ }
+
+ private void updateOptionsMap(List correlators) {
+ optionsMap.keySet().retainAll(correlators);
+ for (VTProgramCorrelatorFactory correlator : correlators) {
+ if (!optionsMap.containsKey(correlator)) {
+ VTOptions defaultOptions = correlator.createDefaultOptions();
+ if (defaultOptions != null) {
+ optionsMap.put(correlator, defaultOptions);
+ }
+ }
+ }
+ }
+
+ void initialize(List correlators) {
+ updateOptionsMap(correlators);
+ JPanel panel = new JPanel(new VerticalLayout(30));
+ optionsEditorPanelList.clear();
+ for (VTProgramCorrelatorFactory correlator : correlators) {
+ OptionsEditorPanel optionsPanel = buildOptionsPanel(correlator);
+ if (optionsPanel != null) {
+ optionsEditorPanelList.add(optionsPanel);
+ optionsPanel.setOptionsPropertyChangeListener(e -> statusChangedCallback.call());
+ panel.add(optionsPanel);
+ }
+ }
+
+ stagingPanel.removeAll();
+ stagingPanel.add(panel, BorderLayout.CENTER);
+ stagingPanel.revalidate();
+ }
+
+ private OptionsEditorPanel buildOptionsPanel(VTProgramCorrelatorFactory factory) {
+ VTOptions options = optionsMap.get(factory);
+ if (options == null) {
+ return null;
+ }
+
+ String title = factory.getName() + " Options";
+
+ EditorStateFactory editorStateFactory = new EditorStateFactory();
+ List optionNames = options.getLeafOptionNames();
+ if (optionNames.isEmpty()) {
+ return null;
+ }
+ Collections.sort(optionNames);
+ return new OptionsEditorPanel(title, options, optionNames, editorStateFactory);
+ }
+
+ public boolean hasValidOptions() {
+ applyOptions();
+ for (VTOptions options : optionsMap.values()) {
+ if (options != null) {
+ if (!options.validate()) {
+ return false;
+ }
+ }
+
+ }
+ return true;
+ }
+
+ private void applyOptions() {
+ for (OptionsEditorPanel panel : optionsEditorPanelList) {
+ panel.apply();
+ }
+ }
+
+ Map getOptionsMap() {
+ return optionsMap;
+ }
+
+}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/OptionsStep.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/OptionsStep.java
new file mode 100644
index 0000000000..8cbd1fef55
--- /dev/null
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/OptionsStep.java
@@ -0,0 +1,75 @@
+/* ###
+ * 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.feature.vt.gui.wizard.add;
+
+import javax.swing.JComponent;
+
+import docking.wizard.WizardModel;
+import docking.wizard.WizardStep;
+import ghidra.util.HelpLocation;
+
+/**
+ * Wizard step for configuring options for the selected correlators when adding to an existing
+ * version tracking session.
+ */
+public class OptionsStep extends WizardStep {
+ private OptionsPanel panel;
+
+ protected OptionsStep(WizardModel model) {
+ super(model, "Correlator Options",
+ new HelpLocation("VersionTrackingPlugin", "Options_Panel"));
+
+ panel = new OptionsPanel(this::notifyStatusChanged);
+ }
+
+ @Override
+ public void initialize(AddToSessionData data) {
+ panel.initialize(data.getCorrelators());
+ // set the options here so that we know this step was visited
+ data.setOptions(panel.getOptionsMap());
+ }
+
+ @Override
+ public boolean isApplicable(AddToSessionData data) {
+ return panel.isApplicable(data.getCorrelators());
+ }
+
+ @Override
+ public boolean isValid() {
+ return panel.hasValidOptions();
+ }
+
+ @Override
+ public boolean canFinish(AddToSessionData data) {
+ return true;
+ }
+
+ @Override
+ public void populateData(AddToSessionData data) {
+ data.setOptions(panel.getOptionsMap());
+ }
+
+ @Override
+ public boolean apply(AddToSessionData data) {
+ return true;
+ }
+
+ @Override
+ public JComponent getComponent() {
+ return panel;
+ }
+
+}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/SummaryStep.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/SummaryStep.java
new file mode 100644
index 0000000000..9d32b0cc45
--- /dev/null
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/SummaryStep.java
@@ -0,0 +1,163 @@
+/* ###
+ * 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.feature.vt.gui.wizard.add;
+
+import java.util.List;
+
+import javax.swing.JComponent;
+
+import docking.wizard.WizardModel;
+import docking.wizard.WizardStep;
+import ghidra.feature.vt.api.main.VTProgramCorrelatorFactory;
+import ghidra.feature.vt.gui.wizard.add.AddToSessionData.AddressSetChoice;
+import ghidra.feature.vt.gui.wizard.session.SummaryPanel;
+import ghidra.framework.model.DomainFile;
+import ghidra.util.HTMLUtilities;
+import ghidra.util.HelpLocation;
+
+/**
+ * Wizard step in the "add to tracking session" wizard for summarizing the information that
+ * will be used to add correlations to a version tracking session.
+ */
+public class SummaryStep extends WizardStep {
+ private SummaryPanel summaryPanel;
+
+ protected SummaryStep(WizardModel model) {
+ super(model, "Summary",
+ new HelpLocation("VersionTrackingPlugin", "New_Session_Summary_Panel"));
+
+ summaryPanel = new SummaryPanel();
+ }
+
+ @Override
+ public void initialize(AddToSessionData data) {
+ StringBuilder label = new StringBuilder();
+ StringBuilder summary = new StringBuilder();
+
+ label.append("");
+ summary.append("");
+
+ // session mode
+
+ label.append("Operation:");
+ summary.append("Add to Version Tracking Session");
+ label.append("
");
+ summary.append("
");
+
+ String sessionName = data.getSession().getName();
+
+ label.append("Session Name:");
+ summary.append(sessionName);
+ label.append("
");
+ summary.append("
");
+
+ String sourceProgramName = null;
+ String destinationProgramName = null;
+
+ DomainFile sourceProgram = data.getSourceFile();
+ sourceProgramName = sourceProgram.getName();
+
+ DomainFile destinationProgram = data.getDestinationFile();
+ destinationProgramName = destinationProgram.getName();
+
+ // source program
+
+ label.append("Source Program:");
+ summary.append(HTMLUtilities.escapeHTML(sourceProgramName));
+ label.append("
");
+ summary.append("
");
+
+ // destination program
+
+ label.append("Destination Program:");
+ summary.append(HTMLUtilities.escapeHTML(destinationProgramName));
+ label.append("
");
+ summary.append("
");
+
+ String correlatorLabel = "";
+ String correlatorName = null;
+
+ List correlators = data.getCorrelators();
+ for (VTProgramCorrelatorFactory correlatorFactory : correlators) {
+ correlatorName = correlatorFactory.getName();
+
+ label.append(correlatorLabel + "Program Correlator:");
+ summary.append(correlatorName == null ? "(null)" : correlatorName);
+ label.append("
");
+ summary.append("
");
+ }
+ boolean excludeAcceptedMatches = data.shouldExcludeAcceptedMatches();
+ label.append("Exclude Accepted Matches:");
+ summary.append(excludeAcceptedMatches ? "Yes" : "No");
+ label.append("
");
+ summary.append("
");
+
+ AddressSetChoice sourceAddressSetChoice = data.getSourceAddressSetChoice();
+ AddressSetChoice destinationAddressSetChoice = data.getDestinationAddressSetChoice();
+ String sourceAddressesInfo =
+ (sourceAddressSetChoice == AddressSetChoice.MANUALLY_DEFINED) ? "Manually Defined"
+ : ((sourceAddressSetChoice == AddressSetChoice.SELECTION))
+ ? "Source Tool Selection"
+ : "Entire Source Program";
+ String destinationAddressesInfo =
+ (destinationAddressSetChoice == AddressSetChoice.MANUALLY_DEFINED)
+ ? "Manually Defined"
+ : ((destinationAddressSetChoice == AddressSetChoice.SELECTION))
+ ? "Destination Tool Selection"
+ : "Entire Destination Program";
+
+ label.append("Source Address Set:");
+ summary.append(sourceAddressesInfo);
+ label.append("
");
+ summary.append("
");
+
+ label.append("Destination Address Set:");
+ summary.append(destinationAddressesInfo);
+ label.append("
");
+ summary.append("
");
+
+ label.append("");
+ summary.append("");
+
+ summaryPanel.initialize(label.toString(), summary.toString());
+ }
+
+ @Override
+ public boolean isValid() {
+ return true;
+ }
+
+ @Override
+ public boolean canFinish(AddToSessionData data) {
+ return true;
+ }
+
+ @Override
+ public boolean apply(AddToSessionData data) {
+ return true;
+ }
+
+ @Override
+ public void populateData(AddToSessionData data) {
+ // nothing to do
+ }
+
+ @Override
+ public JComponent getComponent() {
+ return summaryPanel;
+ }
+
+}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/VTAddToSessionWizardModel.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/VTAddToSessionWizardModel.java
new file mode 100644
index 0000000000..7ba7e08544
--- /dev/null
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/VTAddToSessionWizardModel.java
@@ -0,0 +1,66 @@
+/* ###
+ * 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.feature.vt.gui.wizard.add;
+
+import java.util.List;
+
+import docking.wizard.WizardModel;
+import docking.wizard.WizardStep;
+import ghidra.feature.vt.api.main.VTSession;
+import ghidra.feature.vt.gui.plugin.VTController;
+import ghidra.program.model.listing.Program;
+import ghidra.util.task.Task;
+import ghidra.util.task.TaskLauncher;
+
+/**
+ * Wizard model for adding correlation runs to an existing version tracking session.
+ */
+public class VTAddToSessionWizardModel extends WizardModel {
+
+ private final VTController controller;
+
+ public VTAddToSessionWizardModel(VTController controller) {
+ super("Add to Version Tracking Session", new AddToSessionData());
+ this.controller = controller;
+ Program sourceProgram = controller.getSourceProgram();
+ Program destinationProgram = controller.getDestinationProgram();
+ VTSession session = controller.getSession();
+
+ data.setSourceProgram(sourceProgram);
+ data.setDestinationProgram(destinationProgram);
+ data.setSession(session);
+ data.setSourceSelection(controller.getSelectionInSourceTool());
+ data.setDestinationSelection(controller.getSelectionInDestinationTool());
+
+ }
+
+ @Override
+ protected void addWizardSteps(List> list) {
+ list.add(new CorrelatorChooserStep(this, controller.getSession()));
+ list.add(new OptionsStep(this));
+ list.add(new AddressSetOptionsStep(this));
+ list.add(new LimitAddressSetsStep(this, controller.getTool()));
+ list.add(new SummaryStep(this));
+
+ }
+
+ @Override
+ protected boolean doFinish() {
+ Task task = new AddToSessionTask(controller, data);
+ new TaskLauncher(task, wizardDialog.getComponent());
+ return true;
+ }
+}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/VTProgramTableCorrelatorModel.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/VTProgramTableCorrelatorModel.java
similarity index 91%
rename from Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/VTProgramTableCorrelatorModel.java
rename to Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/VTProgramTableCorrelatorModel.java
index a964855841..a8f79fda4f 100644
--- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/VTProgramTableCorrelatorModel.java
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/add/VTProgramTableCorrelatorModel.java
@@ -4,16 +4,16 @@
* 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.feature.vt.gui.wizard;
+package ghidra.feature.vt.gui.wizard.add;
import java.util.*;
@@ -26,6 +26,9 @@ import ghidra.feature.vt.api.util.VTAbstractProgramCorrelatorFactory;
import ghidra.util.classfinder.ClassSearcher;
import ghidra.util.exception.AssertException;
+/**
+ * Table model for showing version tracking correlators.
+ */
public class VTProgramTableCorrelatorModel extends AbstractGTableModel {
static final String NAME_COLUMN_NAME = "Name";
@@ -47,9 +50,9 @@ public class VTProgramTableCorrelatorModel extends AbstractGTableModel previouslyRunCorrelators;
private Set selectedFactories =
new HashSet<>();
- private CorrelatorPanel panel;
+ private CorrelatorChooserPanel panel;
- public VTProgramTableCorrelatorModel(CorrelatorPanel panel,
+ public VTProgramTableCorrelatorModel(CorrelatorChooserPanel panel,
Set previouslyRunCorrelators) {
this.panel = panel;
this.previouslyRunCorrelators = previouslyRunCorrelators;
@@ -57,7 +60,9 @@ public class VTProgramTableCorrelatorModel extends AbstractGTableModel getSelectedFactories() {
- return new ArrayList<>(selectedFactories);
+ List factories = new ArrayList<>(selectedFactories);
+ factories.sort(comparator);
+ return factories;
}
private static List generateList() {
@@ -136,7 +141,7 @@ public class VTProgramTableCorrelatorModel extends AbstractGTableModel state;
+ private final NewSessionData data;
private final VTController controller;
- public CreateNewSessionTask(VTController controller, WizardState state) {
+ public CreateNewSessionTask(VTController controller, NewSessionData data) {
super("Create New Version Tracking Session", true, true, true);
this.controller = controller;
- this.state = state;
+ this.data = data;
}
@Override
@@ -43,16 +42,16 @@ public class CreateNewSessionTask extends Task {
VTSessionDB session = null;
String name = null;
try {
- Program sourceProgram = (Program) state.get(VTWizardStateKey.SOURCE_PROGRAM);
- Program destinationProgram = (Program) state.get(VTWizardStateKey.DESTINATION_PROGRAM);
+ Program sourceProgram = data.getSourceProgram();
+ Program destinationProgram = data.getDestinationProgram();
session = new VTSessionDB("New Session", sourceProgram, destinationProgram, this);
sourceProgram.release(controller.getTool());
destinationProgram.release(controller.getTool());
- name = (String) state.get(VTWizardStateKey.SESSION_NAME);
- DomainFolder folder = (DomainFolder) state.get(VTWizardStateKey.NEW_SESSION_FOLDER);
+ name = data.getSessionName();
+ DomainFolder folder = data.getSessionFolder();
try {
folder.createFile(name, session, monitor);
}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/session/NewSessionData.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/session/NewSessionData.java
new file mode 100644
index 0000000000..b6182b17f7
--- /dev/null
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/session/NewSessionData.java
@@ -0,0 +1,112 @@
+/* ###
+ * 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.feature.vt.gui.wizard.session;
+
+import ghidra.framework.model.DomainFile;
+import ghidra.framework.model.DomainFolder;
+import ghidra.framework.plugintool.PluginTool;
+import ghidra.program.model.listing.Program;
+
+/**
+ * Wizard data used by the {@link VTNewSessionWizardModel} and its steps for the "create new version
+ * tracking session" wizard.
+ */
+public class NewSessionData {
+ private Program sourceProgram;
+ private Program destinationProgram;
+ private DomainFile sourceFile;
+ private DomainFile destinationFile;
+ private DomainFolder sessionFolder;
+ private String sessionName;
+ private boolean preconditionChecksCompleted;
+
+ public DomainFile getSourceFile() {
+ return sourceFile;
+ }
+
+ public DomainFile getDestinationFile() {
+ return destinationFile;
+ }
+
+ public Program getSourceProgram() {
+ return sourceProgram;
+ }
+
+ public Program getDestinationProgram() {
+ return destinationProgram;
+ }
+
+ public String getSessionName() {
+ return sessionName;
+ }
+
+ public DomainFolder getSessionFolder() {
+ return sessionFolder;
+ }
+
+ public void setSourceFile(DomainFile file, PluginTool tool) {
+ this.sourceFile = file;
+ if (isProgramInvalidForFile(file, sourceProgram)) {
+ sourceProgram.release(tool);
+ sourceProgram = null;
+ }
+ }
+
+ private boolean isProgramInvalidForFile(DomainFile file, Program program) {
+
+ if (program == null) {
+ return false;
+ }
+ if (program.getDomainFile().equals(file)) {
+ return false;
+ }
+ return true;
+ }
+
+ public void setDestinationFile(DomainFile file, PluginTool tool) {
+ this.destinationFile = file;
+ if (isProgramInvalidForFile(file, destinationProgram)) {
+ sourceProgram.release(tool);
+ sourceProgram = null;
+ }
+ }
+
+ public void setSourceProgram(Program program) {
+ this.sourceProgram = program;
+ preconditionChecksCompleted = false;
+ }
+
+ public void setDestinationProgram(Program program) {
+ this.destinationProgram = program;
+ preconditionChecksCompleted = false;
+ }
+
+ public void setSessionName(String name) {
+ this.sessionName = name;
+ }
+
+ public void setSessionFolder(DomainFolder folder) {
+ this.sessionFolder = folder;
+ }
+
+ public boolean hasPerformedPreconditionChecks() {
+ return preconditionChecksCompleted;
+ }
+
+ public void setPerformedPreconditionChecks(boolean b) {
+ preconditionChecksCompleted = b;
+ }
+}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/session/PreconditionsPanel.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/session/PreconditionsPanel.java
new file mode 100644
index 0000000000..23cfd8fb67
--- /dev/null
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/session/PreconditionsPanel.java
@@ -0,0 +1,152 @@
+/* ###
+ * 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.feature.vt.gui.wizard.session;
+
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.swing.*;
+
+import docking.widgets.conditiontestpanel.*;
+import docking.wizard.WizardModel;
+import ghidra.feature.vt.api.main.VTSession;
+import ghidra.feature.vt.gui.validator.VTPreconditionValidator;
+import ghidra.program.model.listing.Program;
+import ghidra.util.Msg;
+import ghidra.util.classfinder.ClassSearcher;
+import utility.function.Callback;
+
+public class PreconditionsPanel extends JPanel {
+ private static final Dimension DEFAULT_SIZE = new Dimension(650, 480);
+ private ConditionTestPanel conditionsTestPanel;
+ private boolean testsDone = false;
+ private Callback statusChangedCallback;
+
+ public PreconditionsPanel(WizardModel model,
+ Callback statusChangedCallback) {
+ this.statusChangedCallback = statusChangedCallback;
+ setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
+ setLayout(new BorderLayout());
+
+ JPanel runButtonPanel = new JPanel();
+ runButtonPanel.setBorder(BorderFactory.createEmptyBorder(20, 0, 0, 0));
+ runButtonPanel.setLayout(new FlowLayout());
+ JButton runTestsButton = new JButton("Run Precondition Checks");
+ runTestsButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ conditionsTestPanel.runTests();
+ }
+ });
+ runButtonPanel.add(runTestsButton);
+
+ JButton skipTestsButton = new JButton("Skip");
+ skipTestsButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ conditionsTestPanel.skipTests();
+ model.goNext();
+ }
+ });
+ runButtonPanel.add(skipTestsButton);
+
+ add(runButtonPanel, BorderLayout.SOUTH);
+ }
+
+ void dispose() {
+ if (conditionsTestPanel != null) {
+ conditionsTestPanel.cancel();
+ }
+ }
+
+ private ConditionTestPanel buildConditionPanel(Program source, Program destination) {
+ List list = getConditionTests(source, destination);
+ Collections.sort(list, (t1, t2) -> t1.getName().compareTo(t2.getName()));
+ ConditionTestPanel panel = new ConditionTestPanel(list);
+ panel.addListener(new ConditionTestListener() {
+ @Override
+ public void testsCompleted() {
+ testsDone();
+ }
+ });
+ return panel;
+ }
+
+ private void testsDone() {
+ testsDone = true;
+ statusChangedCallback.call();
+ if (hasAnyErrorStatus()) {
+ Msg.showError(getClass(), this, "Warning - Serious Precondition failures",
+ "The precondition checks discovered one or more serious problems. \n\n" +
+ "If you continue, your version tracking results may be invalid.\n" +
+ "You should review the errors, cancel this wizard, and correct the problems.");
+ }
+ }
+
+ private List getConditionTests(Program sourceProgram,
+ Program destinationProgram) throws SecurityException {
+ List list = new ArrayList();
+
+ List> vtValidatorClasses =
+ ClassSearcher.getClasses(VTPreconditionValidator.class);
+ for (Class extends VTPreconditionValidator> validatorClass : vtValidatorClasses) {
+ try {
+ Constructor extends VTPreconditionValidator> ctor =
+ validatorClass.getConstructor(Program.class, Program.class, VTSession.class);
+ VTPreconditionValidator validator =
+ ctor.newInstance(sourceProgram, destinationProgram, null);
+ list.add(validator);
+ }
+ catch (Exception e) {
+ Msg.error(this, "error including VTPreconditionValidator " + validatorClass, e);
+ }
+ }
+ return list;
+ }
+
+ private Boolean hasAnyErrorStatus() {
+ return conditionsTestPanel.getErrorCount() > 0;
+ }
+
+ @Override
+ // Overridden to account for the fact that we don't know our preferred size until later in
+ // the wizard flow. At that point, the initial size of the wizard is already too small.
+ public Dimension getPreferredSize() {
+ Dimension superSize = super.getPreferredSize();
+ if (superSize.width > DEFAULT_SIZE.width && superSize.height > DEFAULT_SIZE.height) {
+ return superSize;
+ }
+ return DEFAULT_SIZE;
+ }
+
+ public void initializeTests(Program sourceProgram, Program destinationProgram) {
+ testsDone = false;
+ if (conditionsTestPanel != null) {
+ remove(conditionsTestPanel);
+ }
+ conditionsTestPanel = buildConditionPanel(sourceProgram, destinationProgram);
+ add(conditionsTestPanel, BorderLayout.CENTER);
+ }
+
+ public boolean hasRunTests() {
+ return testsDone;
+ }
+}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/session/PreconditionsStep.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/session/PreconditionsStep.java
new file mode 100644
index 0000000000..dae644530c
--- /dev/null
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/session/PreconditionsStep.java
@@ -0,0 +1,82 @@
+/* ###
+ * 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.feature.vt.gui.wizard.session;
+
+import javax.swing.JComponent;
+
+import docking.wizard.WizardModel;
+import docking.wizard.WizardStep;
+import ghidra.program.model.listing.Program;
+import ghidra.util.HelpLocation;
+
+/**
+ * Wizard step for running version tracking precondition tests when creating a new version tracking
+ * session.
+ */
+public class PreconditionsStep extends WizardStep {
+ private PreconditionsPanel preconditionsPanel;
+
+ protected PreconditionsStep(WizardModel model) {
+ super(model, "Precondition Checklist",
+ new HelpLocation("VersionTrackingPlugin", "Preconditions_Panel"));
+
+ preconditionsPanel = new PreconditionsPanel(model, this::notifyStatusChanged);
+ }
+
+ @Override
+ public void initialize(NewSessionData data) {
+ if (!data.hasPerformedPreconditionChecks()) {
+ Program sourceProgram = data.getSourceProgram();
+ Program destinationProgram = data.getDestinationProgram();
+ preconditionsPanel.initializeTests(sourceProgram, destinationProgram);
+ }
+ }
+
+ @Override
+ public boolean isValid() {
+ boolean hasRunTests = preconditionsPanel.hasRunTests();
+ if (hasRunTests) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void populateData(NewSessionData data) {
+ data.setPerformedPreconditionChecks(true);
+ }
+
+ @Override
+ public boolean apply(NewSessionData data) {
+ return true;
+ }
+
+ @Override
+ public boolean canFinish(NewSessionData data) {
+ return data.hasPerformedPreconditionChecks();
+ }
+
+ @Override
+ public JComponent getComponent() {
+ return preconditionsPanel;
+ }
+
+ @Override
+ protected void dispose(NewSessionData data) {
+ preconditionsPanel.dispose();
+ }
+
+}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/session/SessionConfigurationPanel.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/session/SessionConfigurationPanel.java
new file mode 100644
index 0000000000..a03f71b445
--- /dev/null
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/session/SessionConfigurationPanel.java
@@ -0,0 +1,348 @@
+/* ###
+ * 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.feature.vt.gui.wizard.session;
+
+import static ghidra.framework.main.DataTreeDialogType.*;
+
+import java.awt.*;
+
+import javax.swing.*;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+
+import org.apache.commons.lang3.StringUtils;
+
+import docking.widgets.button.BrowseButton;
+import docking.widgets.label.GDLabel;
+import generic.theme.GIcon;
+import generic.theme.GThemeDefaults.Ids.Fonts;
+import generic.theme.Gui;
+import ghidra.framework.main.DataTreeDialog;
+import ghidra.framework.model.DomainFile;
+import ghidra.framework.model.DomainFolder;
+import ghidra.util.StringUtilities;
+import utility.function.Callback;
+
+public class SessionConfigurationPanel extends JPanel {
+ // The maximum length to allow for each program's name portion of the session name.
+ // In the filesystem API, when saved, the session name is restricted to 60 characters.
+ // The default VTSession name combines the two program names so split the length between them,
+ // minus text we add below.
+ private static final int VTSESSION_NAME_PROGRAM_NAME_MAX_LENGTH = 28;
+ private static final int TEXT_FIELD_LENGTH = 40;
+ private static final Icon SWAP_ICON = new GIcon("icon.version.tracking.new.session.swap");
+ private static final Icon INFO_ICON = new GIcon("icon.version.tracking.new.session.info");
+ private JTextField sourceField;
+ private JTextField destinationField;
+ private JButton sourceBrowseButton;
+ private JButton destinationBrowseButton;
+ private JButton swapProgramsButton;
+ private JTextField sessionNameField;
+ private JTextField folderNameField;
+
+ private DomainFile sourceFile;
+ private DomainFile destinationFile;
+ private DomainFolder sessionFolder;
+ private Callback statusChangedCallback;
+
+ SessionConfigurationPanel(Callback statusChangedCallback) {
+ this.statusChangedCallback = statusChangedCallback;
+ setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
+
+ JLabel folderLabel = new GDLabel("Project folder ");
+ folderLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+ folderLabel.setToolTipText("The folder to store the new Version Tracking Session");
+ folderNameField = new JTextField();
+ Gui.registerFont(folderNameField, Fonts.MONOSPACED);
+ folderNameField.setEditable(false); // force user to browse to choose
+
+ JButton browseFolderButton = new BrowseButton();
+ browseFolderButton.addActionListener(e -> browseDataTreeFolders());
+
+ JLabel newSessionLabel = new GDLabel("New Session Name: ");
+ newSessionLabel.setToolTipText("The name for the new Version Tracking Session");
+ newSessionLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+
+ sessionNameField = new JTextField(TEXT_FIELD_LENGTH);
+ sessionNameField.getDocument().addDocumentListener(new DocumentListener() {
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ statusChangedCallback.call();
+ }
+
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ statusChangedCallback.call();
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ statusChangedCallback.call();
+ }
+ });
+
+ JLabel sourceLabel = new GDLabel("Source Program: ");
+ sourceLabel.setIcon(INFO_ICON);
+ sourceLabel.setToolTipText("Analyzed program with markup to transfer");
+ sourceLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+
+ JLabel destinationLabel = new GDLabel("Destination Program: ");
+ destinationLabel.setIcon(INFO_ICON);
+ destinationLabel.setToolTipText("New program that receives the transferred markup");
+ destinationLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+
+ sourceField = new JTextField(TEXT_FIELD_LENGTH);
+ sourceField.setEditable(false);
+
+ destinationField = new JTextField(TEXT_FIELD_LENGTH);
+ destinationField.setEditable(false);
+
+ sourceBrowseButton = createSourceBrowseButton();
+ destinationBrowseButton = createDestinationBrowseButton();
+
+ swapProgramsButton = new JButton(SWAP_ICON);
+ swapProgramsButton.setText("swap");
+ swapProgramsButton.setName("SWAP_BUTTON");
+ swapProgramsButton.addActionListener(arg0 -> swapPrograms());
+
+ JPanel mainPanel = new JPanel(new GridBagLayout());
+ GridBagConstraints gbc = new GridBagConstraints();
+
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+ mainPanel.add(Box.createVerticalStrut(15), gbc);
+
+ gbc.gridy++;
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+ mainPanel.add(folderLabel, gbc);
+
+ gbc.gridx++;
+ mainPanel.add(folderNameField, gbc);
+
+ gbc.gridx++;
+ mainPanel.add(Box.createHorizontalStrut(5), gbc);
+
+ gbc.gridx++;
+ mainPanel.add(browseFolderButton, gbc);
+
+ gbc.gridx = 0;
+ gbc.gridy++;
+ mainPanel.add(Box.createVerticalStrut(10), gbc);
+
+ gbc.gridy++;
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+ mainPanel.add(newSessionLabel, gbc);
+
+ gbc.gridx++;
+ mainPanel.add(sessionNameField, gbc);
+
+ gbc.gridx = 0;
+ gbc.gridy++;
+ mainPanel.add(Box.createVerticalStrut(15), gbc);
+
+ gbc.gridy++;
+ gbc.gridwidth = 4;
+ mainPanel.add(new JSeparator(), gbc);
+
+ gbc.gridy++;
+ gbc.gridwidth = 1;
+ mainPanel.add(Box.createVerticalStrut(25), gbc);
+
+ gbc.gridy++;
+ mainPanel.add(sourceLabel, gbc);
+
+ gbc.gridx++;
+ mainPanel.add(sourceField, gbc);
+
+ gbc.gridx += 2;
+ mainPanel.add(sourceBrowseButton, gbc);
+
+ gbc.gridx = 0;
+ gbc.gridy++;
+ gbc.fill = GridBagConstraints.NONE;
+ gbc.gridwidth = 4;
+ mainPanel.add(swapProgramsButton, gbc);
+
+ gbc.gridwidth = 1;
+ gbc.gridy++;
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+ mainPanel.add(destinationLabel, gbc);
+
+ gbc.gridx++;
+ mainPanel.add(destinationField, gbc);
+
+ gbc.gridx += 2;
+ mainPanel.add(destinationBrowseButton, gbc);
+
+ gbc.gridx = 0;
+ gbc.gridy++;
+ mainPanel.add(Box.createVerticalStrut(25), gbc);
+
+ gbc.gridy++;
+ gbc.gridwidth = 4;
+ mainPanel.add(new JSeparator(), gbc);
+
+ gbc.gridy++;
+ gbc.gridwidth = 1;
+ mainPanel.add(Box.createVerticalStrut(60), gbc);
+
+ setLayout(new BorderLayout());
+ add(mainPanel, BorderLayout.NORTH);
+
+ }
+
+ public void setDestinationFile(DomainFile file) {
+ destinationFile = file;
+ if (destinationFile != null) {
+ destinationField.setText(destinationFile.getPathname());
+ }
+ else {
+ destinationField.setText("");
+ }
+ updateSessionNameIfBlank();
+ }
+
+ public void setSourceFile(DomainFile file) {
+ sourceFile = file;
+ if (sourceFile != null) {
+ sourceField.setText(sourceFile.getPathname());
+ }
+ else {
+ sourceField.setText("");
+ }
+ updateSessionNameIfBlank();
+ }
+
+ private JButton createSourceBrowseButton() {
+ JButton button = new BrowseButton();
+ button.setName("SOURCE_BUTTON");
+ button.addActionListener(e -> {
+ DomainFile programFile = VTWizardUtils.chooseDomainFile(SessionConfigurationPanel.this,
+ "a source program", VTWizardUtils.PROGRAM_FILTER, null);
+ if (programFile != null) {
+ setSourceFile(programFile);
+ statusChangedCallback.call();
+ }
+ });
+ return button;
+ }
+
+ private JButton createDestinationBrowseButton() {
+ JButton button = new BrowseButton();
+ button.setName("DESTINATION_BUTTON");
+ button.addActionListener(e -> {
+ DomainFile programFile = VTWizardUtils.chooseDomainFile(SessionConfigurationPanel.this,
+ "a destination program", VTWizardUtils.PROGRAM_FILTER, null);
+ if (programFile != null) {
+ setDestinationFile(programFile);
+ statusChangedCallback.call();
+ }
+ });
+ return button;
+ }
+
+ /**
+ * Presents the user with a tree of the existing project folders and allows
+ * them to pick one
+ */
+ private void browseDataTreeFolders() {
+ final DataTreeDialog dataTreeDialog =
+ new DataTreeDialog(this, "Choose a project folder", CHOOSE_FOLDER);
+
+ dataTreeDialog.addOkActionListener(e -> {
+ dataTreeDialog.close();
+ sessionFolder = dataTreeDialog.getDomainFolder();
+ folderNameField.setText(sessionFolder.toString());
+ statusChangedCallback.call();
+ });
+ dataTreeDialog.showComponent();
+ }
+
+ private void swapPrograms() {
+ DomainFile newSourceFile = destinationFile;
+ DomainFile newDestionationFile = sourceFile;
+ setSourceFile(newSourceFile);
+ setDestinationFile(newDestionationFile);
+ statusChangedCallback.call();
+ }
+
+ public DomainFolder getSessionFolder() {
+ return sessionFolder;
+ }
+
+ public String getSessionName() {
+ return sessionNameField.getText().trim();
+ }
+
+ public DomainFile getSourceFile() {
+ return sourceFile;
+ }
+
+ public DomainFile getDestinationFile() {
+ return destinationFile;
+ }
+
+ private void updateSessionNameIfBlank() {
+ if (!StringUtils.isBlank(sessionNameField.getText())) {
+ return;
+ }
+ if (sourceFile == null || destinationFile == null || sourceFile == destinationFile) {
+ return;
+ }
+
+ String defaultSessionName =
+ createVTSessionName(sourceFile.getName(), destinationFile.getName());
+ sessionNameField.setText(defaultSessionName);
+ }
+
+ private String createVTSessionName(String sourceName, String destinationName) {
+
+ // if together they are within the bounds just return session name with both full names
+ if (sourceName.length() + destinationName.length() <= 2 *
+ VTSESSION_NAME_PROGRAM_NAME_MAX_LENGTH) {
+ return "VT_" + sourceName + "_" + destinationName;
+ }
+
+ // give destination name all space not used by source name
+ if (sourceName.length() < VTSESSION_NAME_PROGRAM_NAME_MAX_LENGTH) {
+ int leftover = VTSESSION_NAME_PROGRAM_NAME_MAX_LENGTH - sourceName.length();
+ destinationName = StringUtilities.trimMiddle(destinationName,
+ VTSESSION_NAME_PROGRAM_NAME_MAX_LENGTH + leftover);
+ return "VT_" + sourceName + "_" + destinationName;
+ }
+
+ // give source name all space not used by destination name
+ if (destinationName.length() < VTSESSION_NAME_PROGRAM_NAME_MAX_LENGTH) {
+ int leftover = VTSESSION_NAME_PROGRAM_NAME_MAX_LENGTH - destinationName.length();
+ sourceName = StringUtilities.trimMiddle(sourceName,
+ VTSESSION_NAME_PROGRAM_NAME_MAX_LENGTH + leftover);
+ return "VT_" + sourceName + "_" + destinationName;
+ }
+
+ // if both too long, shorten both of them
+ sourceName = StringUtilities.trimMiddle(sourceName, VTSESSION_NAME_PROGRAM_NAME_MAX_LENGTH);
+ destinationName =
+ StringUtilities.trimMiddle(destinationName, VTSESSION_NAME_PROGRAM_NAME_MAX_LENGTH);
+
+ return "VT_" + sourceName + "_" + destinationName;
+ }
+
+ public void setSessionFolder(DomainFolder folder) {
+ sessionFolder = folder;
+ folderNameField.setText(sessionFolder.toString());
+ }
+
+}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/session/SessionConfigurationStep.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/session/SessionConfigurationStep.java
new file mode 100644
index 0000000000..6d6b9e62c1
--- /dev/null
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/session/SessionConfigurationStep.java
@@ -0,0 +1,205 @@
+/* ###
+ * 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.feature.vt.gui.wizard.session;
+
+import javax.swing.JComponent;
+
+import org.apache.commons.lang3.StringUtils;
+
+import docking.wizard.WizardModel;
+import docking.wizard.WizardStep;
+import ghidra.app.util.task.OpenProgramRequest;
+import ghidra.app.util.task.OpenProgramTask;
+import ghidra.feature.vt.api.util.VTSessionFileUtil;
+import ghidra.framework.model.DomainFile;
+import ghidra.framework.model.DomainFolder;
+import ghidra.framework.plugintool.PluginTool;
+import ghidra.program.model.listing.Program;
+import ghidra.util.HelpLocation;
+import ghidra.util.InvalidNameException;
+import ghidra.util.task.TaskLauncher;
+
+/**
+ * Wizard step in the new version tracking session wizard for choosing which programs to
+ * track and naming the session.
+ */
+public class SessionConfigurationStep extends WizardStep {
+
+ private PluginTool tool;
+ private SessionConfigurationPanel sessionPanel;
+
+ protected SessionConfigurationStep(WizardModel model, PluginTool tool) {
+ super(model, "New Version Tracking Session",
+ new HelpLocation("VersionTrackingPlugin", "New_Session_Panel"));
+ this.tool = tool;
+ sessionPanel = new SessionConfigurationPanel(this::notifyStatusChanged);
+ }
+
+ @Override
+ public void initialize(NewSessionData data) {
+ sessionPanel.setSessionFolder(data.getSessionFolder());
+ sessionPanel.setSourceFile(data.getSourceFile());
+ sessionPanel.setDestinationFile(data.getDestinationFile());
+ }
+
+ @Override
+ public boolean isValid() {
+ setStatusMessage("");
+ DomainFolder sessionFolder = sessionPanel.getSessionFolder();
+ String sessionName = sessionPanel.getSessionName();
+ DomainFile sourceFile = sessionPanel.getSourceFile();
+ DomainFile destinationFile = sessionPanel.getDestinationFile();
+
+ if (!isValid(sessionFolder, sessionName, sourceFile, destinationFile)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public void populateData(NewSessionData data) {
+ data.setSessionName(sessionPanel.getSessionName());
+ data.setSessionFolder(sessionPanel.getSessionFolder());
+ data.setSourceFile(sessionPanel.getSourceFile(), tool);
+ data.setDestinationFile(sessionPanel.getDestinationFile(), tool);
+ }
+
+ @Override
+ public boolean canFinish(NewSessionData data) {
+ return true;
+ }
+
+ @Override
+ protected void dispose(NewSessionData data) {
+ releaseProgram(data.getSourceProgram());
+ releaseProgram(data.getDestinationProgram());
+ }
+
+ private void releaseProgram(Program program) {
+ if (program != null) {
+ if (program.getConsumerList().contains(tool)) {
+ program.release(tool);
+ }
+ }
+ }
+
+ private boolean isValid(DomainFolder sessionFolder, String sessionName, DomainFile sourceFile,
+ DomainFile destinationFile) {
+ if (sessionFolder == null) {
+ setStatusMessage("Choose a project folder to continue!");
+ return false;
+ }
+ if (sourceFile == null) {
+ setStatusMessage("Please choose a source program.");
+ return false;
+ }
+ if (destinationFile == null) {
+ setStatusMessage("Please choose a destination program.");
+ return false;
+ }
+ if (sourceFile.equals(destinationFile)) {
+ setStatusMessage("Source and destination files must be different.");
+ return false;
+ }
+ if (StringUtils.isBlank(sessionName)) {
+ setStatusMessage("Please enter a name for this session");
+ return false;
+ }
+ try {
+ tool.getProject().getProjectData().testValidName(sessionName, false);
+ }
+ catch (InvalidNameException e) {
+ setStatusMessage("'" + sessionName + "' contains invalid characters");
+ return false;
+ }
+
+ DomainFile file = sessionFolder.getFile(sessionName);
+ if (file != null) {
+ setStatusMessage(
+ "'" + file.getPathname() + "' is the name of an existing project file");
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean apply(NewSessionData data) {
+
+ if (data.getSourceProgram() == null) {
+ Program program = openSourceProgram(data.getSourceFile());
+ if (program == null) {
+ return false;
+ }
+ data.setSourceProgram(program);
+ }
+
+ if (data.getDestinationProgram() == null) {
+ Program program = openDestinationProgram(data.getDestinationFile());
+ if (program == null) {
+ return false;
+ }
+ data.setDestinationProgram(program);
+ }
+ return true;
+ }
+
+ private Program openSourceProgram(DomainFile file) {
+ try {
+ VTSessionFileUtil.validateSourceProgramFile(file, false);
+ }
+ catch (Exception e) {
+ setStatusMessage(e.getMessage());
+ return null;
+ }
+
+ Program program = openProgram(file);
+ if (program == null) {
+ setStatusMessage("Open source program failed for " + file.getPathname());
+ }
+ return program;
+ }
+
+ private Program openDestinationProgram(DomainFile file) {
+ try {
+ VTSessionFileUtil.validateDestinationProgramFile(file, false, false);
+ }
+ catch (Exception e) {
+ setStatusMessage(e.getMessage());
+ return null;
+ }
+
+ Program program = openProgram(file);
+ if (program == null) {
+ setStatusMessage("Open destination program failed for " + file.getPathname());
+ }
+ return program;
+ }
+
+ private Program openProgram(DomainFile domainFile) {
+
+ OpenProgramTask openProgramTask = new OpenProgramTask(domainFile, tool);
+ new TaskLauncher(openProgramTask, tool.getActiveWindow());
+ OpenProgramRequest openProgramRequest = openProgramTask.getOpenProgram();
+ return openProgramRequest != null ? openProgramRequest.getProgram() : null;
+ }
+
+ @Override
+ public JComponent getComponent() {
+ return sessionPanel;
+ }
+
+}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/session/SummaryPanel.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/session/SummaryPanel.java
new file mode 100644
index 0000000000..c82df9b970
--- /dev/null
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/session/SummaryPanel.java
@@ -0,0 +1,48 @@
+/* ###
+ * 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.feature.vt.gui.wizard.session;
+
+import java.awt.BorderLayout;
+
+import javax.swing.*;
+
+import docking.widgets.label.GDHtmlLabel;
+import ghidra.util.layout.PairLayout;
+
+public class SummaryPanel extends JPanel {
+ private JLabel labelLabel;
+ private JLabel summaryLabel;
+
+ public SummaryPanel() {
+
+ labelLabel = new GDHtmlLabel();
+ summaryLabel = new GDHtmlLabel();
+
+ JPanel mainPanel = new JPanel(new PairLayout(5, 10));
+ mainPanel.add(labelLabel);
+ mainPanel.add(summaryLabel);
+
+ setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
+ setLayout(new BorderLayout());
+ add(mainPanel, BorderLayout.CENTER);
+ }
+
+ public void initialize(String labelText, String summaryText) {
+ labelLabel.setText(labelText);
+ summaryLabel.setText(summaryText);
+ }
+
+}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/session/SummaryStep.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/session/SummaryStep.java
new file mode 100644
index 0000000000..e814ada64c
--- /dev/null
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/session/SummaryStep.java
@@ -0,0 +1,117 @@
+/* ###
+ * 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.feature.vt.gui.wizard.session;
+
+import javax.swing.JComponent;
+
+import docking.wizard.WizardModel;
+import docking.wizard.WizardStep;
+import ghidra.framework.model.DomainFile;
+import ghidra.util.HTMLUtilities;
+import ghidra.util.HelpLocation;
+
+/**
+ * Wizard step in the new version tracking session wizard for summarizing the information that
+ * will be used to create a new session.
+ */
+public class SummaryStep extends WizardStep {
+ private SummaryPanel summaryPanel;
+
+ protected SummaryStep(WizardModel model) {
+ super(model, "Summary",
+ new HelpLocation("VersionTrackingPlugin", "New_Session_Summary_Panel"));
+
+ summaryPanel = new SummaryPanel();
+ }
+
+ @Override
+ public void initialize(NewSessionData data) {
+ StringBuilder label = new StringBuilder();
+ StringBuilder summary = new StringBuilder();
+
+ label.append("");
+ summary.append("");
+
+ // session mode
+
+ label.append("Operation:");
+ String opDescription = "New Version Tracking Session";
+ summary.append(opDescription);
+ label.append("
");
+ summary.append("
");
+
+ String sessionName = data.getSessionName();
+
+ label.append("Session Name:");
+ summary.append(sessionName);
+ label.append("
");
+ summary.append("
");
+
+ String sourceProgramName = null;
+ String destinationProgramName = null;
+
+ DomainFile sourceProgram = data.getSourceFile();
+ sourceProgramName = sourceProgram.getName();
+
+ DomainFile destinationProgram = data.getDestinationFile();
+ destinationProgramName = destinationProgram.getName();
+
+ // source program
+
+ label.append("Source Program:");
+ summary.append(HTMLUtilities.escapeHTML(sourceProgramName));
+ label.append("
");
+ summary.append("
");
+
+ // destination program
+
+ label.append("Destination Program:");
+ summary.append(HTMLUtilities.escapeHTML(destinationProgramName));
+ label.append("
");
+ summary.append("
");
+
+ label.append("");
+ summary.append("");
+
+ summaryPanel.initialize(label.toString(), summary.toString());
+ }
+
+ @Override
+ public boolean isValid() {
+ return true;
+ }
+
+ @Override
+ public boolean apply(NewSessionData data) {
+ return true;
+ }
+
+ @Override
+ public JComponent getComponent() {
+ return summaryPanel;
+ }
+
+ @Override
+ public boolean canFinish(NewSessionData data) {
+ return true;
+ }
+
+ @Override
+ public void populateData(NewSessionData data) {
+ // this step is display only
+ }
+
+}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/session/VTNewSessionWizardModel.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/session/VTNewSessionWizardModel.java
new file mode 100644
index 0000000000..8d914cc1ca
--- /dev/null
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/session/VTNewSessionWizardModel.java
@@ -0,0 +1,66 @@
+/* ###
+ * 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.feature.vt.gui.wizard.session;
+
+import java.util.List;
+
+import docking.wizard.WizardModel;
+import docking.wizard.WizardStep;
+import ghidra.feature.vt.gui.plugin.VTController;
+import ghidra.framework.model.DomainFile;
+import ghidra.framework.model.DomainFolder;
+import ghidra.framework.plugintool.PluginTool;
+import ghidra.util.task.Task;
+import ghidra.util.task.TaskLauncher;
+
+/**
+ * Wizard model for creating a new version tracking session.
+ */
+public class VTNewSessionWizardModel extends WizardModel {
+
+ private final VTController controller;
+
+ public VTNewSessionWizardModel(VTController controller) {
+ this(controller, null, null);
+ }
+
+ public VTNewSessionWizardModel(VTController controller, DomainFile sourceFile,
+ DomainFile destinationFile) {
+ super("New Version Tracking Session", new NewSessionData());
+ this.controller = controller;
+ PluginTool tool = controller.getTool();
+ data.setSourceFile(sourceFile, tool);
+ data.setDestinationFile(destinationFile, tool);
+ DomainFolder folder = tool.getProject().getProjectData().getRootFolder();
+ data.setSessionFolder(folder);
+ }
+
+ @Override
+ protected void addWizardSteps(List> list) {
+ list.add(new SessionConfigurationStep(this, controller.getTool()));
+ list.add(new PreconditionsStep(this));
+ list.add(new SummaryStep(this));
+
+ }
+
+ @Override
+ protected boolean doFinish() {
+ Task task = new CreateNewSessionTask(controller, data);
+ new TaskLauncher(task, wizardDialog.getComponent());
+ return true;
+ }
+
+}
diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/VTWizardUtils.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/session/VTWizardUtils.java
similarity index 96%
rename from Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/VTWizardUtils.java
rename to Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/session/VTWizardUtils.java
index b87ddeefef..bd12ffbda2 100644
--- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/VTWizardUtils.java
+++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/wizard/session/VTWizardUtils.java
@@ -4,16 +4,16 @@
* 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.feature.vt.gui.wizard;
+package ghidra.feature.vt.gui.wizard.session;
import static ghidra.framework.main.DataTreeDialogType.*;
@@ -54,7 +54,7 @@ public class VTWizardUtils {
return Program.class.isAssignableFrom(f.getDomainObjectClass());
};
- static DomainFile chooseDomainFile(Component parent, String domainIdentifier,
+ public static DomainFile chooseDomainFile(Component parent, String domainIdentifier,
DomainFileFilter filter, DomainFile fileToSelect) {
final DataTreeDialog dataTreeDialog = filter == null
? new DataTreeDialog(parent, "Choose " + domainIdentifier, OPEN)
diff --git a/Ghidra/Features/VersionTracking/src/screen/java/help/screenshot/VersionTrackingPluginScreenShots.java b/Ghidra/Features/VersionTracking/src/screen/java/help/screenshot/VersionTrackingPluginScreenShots.java
index af86e5ca10..c2181bf555 100644
--- a/Ghidra/Features/VersionTracking/src/screen/java/help/screenshot/VersionTrackingPluginScreenShots.java
+++ b/Ghidra/Features/VersionTracking/src/screen/java/help/screenshot/VersionTrackingPluginScreenShots.java
@@ -4,9 +4,9 @@
* 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.
@@ -51,7 +51,7 @@ import ghidra.feature.vt.gui.provider.onetomany.VTMatchDestinationTableProvider;
import ghidra.feature.vt.gui.provider.onetomany.VTMatchSourceTableProvider;
import ghidra.feature.vt.gui.task.*;
import ghidra.feature.vt.gui.util.MatchInfo;
-import ghidra.feature.vt.gui.wizard.*;
+import ghidra.feature.vt.gui.wizard.add.*;
import ghidra.features.base.codecompare.listing.ListingCodeComparisonPanel;
import ghidra.framework.main.DataTreeDialog;
import ghidra.framework.main.datatree.DataTree;
@@ -228,11 +228,13 @@ public class VersionTrackingPluginScreenShots extends GhidraScreenShotGenerator
selectMatch("Call_strncpy_s");
- dualListingIsVisible(getProvider(VTMarkupItemsTableProvider.class));
+ VTMarkupItemsTableProvider provider = getProvider(VTMarkupItemsTableProvider.class);
+ tool.showComponentProvider(provider, true);
+ assertTrue(dualListingIsVisible(provider));
hideDualListing(VTMarkupItemsTableProvider.class);
- dualListingIsVisible(getProvider(VTMarkupItemsTableProvider.class));
+ assertFalse(dualListingIsVisible(provider));
setToolSize(1300, 750);
@@ -441,6 +443,8 @@ public class VersionTrackingPluginScreenShots extends GhidraScreenShotGenerator
assertNotNull(destinationTool);
tool = sourceTool;
+ ComponentProvider provider = tool.getComponentProvider("Decompiler");
+ tool.showComponentProvider(provider, BATCH_MODE);
setToolSize(1200, 550);
sourceTool.toFront();
captureToolWindow(1200, 550);
@@ -785,7 +789,7 @@ public class VersionTrackingPluginScreenShots extends GhidraScreenShotGenerator
assertNotNull(provider);
ToggleDockingAction action =
- (ToggleDockingAction) getLocalAction(provider, "Dual Listing Toggle Orientation");
+ (ToggleDockingAction) getLocalAction(provider, "Listing View Toggle Orientation");
assertNotNull(action);
setToggleActionSelected(action, new DefaultActionContext(), vertical);
waitForSwing();
@@ -817,12 +821,10 @@ public class VersionTrackingPluginScreenShots extends GhidraScreenShotGenerator
DialogComponentProvider dialog = getDialog();
LimitAddressSetsPanel panel = findComponent(dialog, LimitAddressSetsPanel.class);
- AddressSetPanel destinationPanel =
- (AddressSetPanel) getInstanceField("destinationPanel", panel);
- ChooseAddressSetEditorPanel choosePanel =
- findComponent(destinationPanel, ChooseAddressSetEditorPanel.class);
+ ChooseAddressSetEditorPanel destinationPanel =
+ (ChooseAddressSetEditorPanel) getInstanceField("destinationPanel", panel);
JRadioButton myRangesButton =
- (JRadioButton) getInstanceField("myRangesButton", choosePanel);
+ (JRadioButton) getInstanceField("myRangesButton", destinationPanel);
pressButton(myRangesButton);
}
@@ -833,17 +835,18 @@ public class VersionTrackingPluginScreenShots extends GhidraScreenShotGenerator
DialogComponentProvider dialog = getDialog();
AddressSetOptionsPanel panel = findComponent(dialog, AddressSetOptionsPanel.class);
JCheckBox showAddressSetPanelsCheckbox =
- (JCheckBox) getInstanceField("showAddressSetPanelsCheckbox", panel);
+ (JCheckBox) getInstanceField("limitAddressSetsCheckbox", panel);
showAddressSetPanelsCheckbox.setSelected(true);
}
private void setupVTWizardOptionsPanel() throws Exception {
setupVTWizardCorrelatorPanel();
DialogComponentProvider dialog = getDialog();
- CorrelatorPanel correlatorPanel = findComponent(dialog, CorrelatorPanel.class);
+ CorrelatorChooserPanel correlatorPanel =
+ findComponent(dialog, CorrelatorChooserPanel.class);
VTProgramTableCorrelatorModel model =
(VTProgramTableCorrelatorModel) getInstanceField("model", correlatorPanel);
- model.setValueAt(true, 1, 0);// Set "Exact Function Bytes Match" to selected.
+ runSwing(() -> model.setValueAt(true, 6, 0));// Set "Exact Function Bytes Match" to selected
model.fireTableDataChanged();
waitForSwing();
pressNextButtonWhenEnabled();
diff --git a/Ghidra/Features/VersionTracking/src/test.slow/java/ghidra/feature/vt/api/VTAddToSessionTest.java b/Ghidra/Features/VersionTracking/src/test.slow/java/ghidra/feature/vt/api/VTAddToSessionTest.java
index 0f8cab350a..548632db6c 100644
--- a/Ghidra/Features/VersionTracking/src/test.slow/java/ghidra/feature/vt/api/VTAddToSessionTest.java
+++ b/Ghidra/Features/VersionTracking/src/test.slow/java/ghidra/feature/vt/api/VTAddToSessionTest.java
@@ -4,9 +4,9 @@
* 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.
@@ -24,16 +24,17 @@ import javax.swing.table.TableModel;
import org.junit.*;
-import docking.wizard.WizardManager;
-import docking.wizard.WizardPanel;
+import docking.wizard.WizardDialog;
+import docking.wizard.WizardStep;
import generic.test.TestUtils;
import ghidra.app.services.CodeViewerService;
import ghidra.app.util.AddressInput;
import ghidra.feature.vt.api.db.VTSessionDB;
import ghidra.feature.vt.api.main.VTMatchSet;
import ghidra.feature.vt.gui.plugin.*;
-import ghidra.feature.vt.gui.wizard.*;
-import ghidra.feature.vt.gui.wizard.ChooseAddressSetEditorPanel.AddressSetChoice;
+import ghidra.feature.vt.gui.wizard.add.*;
+import ghidra.feature.vt.gui.wizard.add.AddToSessionData.AddressSetChoice;
+import ghidra.feature.vt.gui.wizard.session.SummaryPanel;
import ghidra.framework.plugintool.PluginTool;
import ghidra.program.database.ProgramDB;
import ghidra.program.model.address.*;
@@ -59,8 +60,8 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
private ProgramDB sourceProgram;
private ProgramDB destinationProgram;
private VTSessionDB session;
- private VTAddToSessionWizardManager vtWizardManager;
- private WizardManager wizardManager;
+ private VTAddToSessionWizardModel wizardModel;
+ private WizardDialog wizardDialog;
private AddressSet sourceSelection;
private AddressSet destinationSelection;
@@ -125,11 +126,11 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
assertNotNull(controller.getSourceProgram());
assertNotNull(controller.getDestinationProgram());
- createWizardManager();
+ createWizardDialog();
- runSwingLater(() -> wizardManager.showWizard(controller.getParentComponent()));
+ runSwingLater(() -> wizardDialog.show(controller.getParentComponent()));
- waitForDialogComponent(WizardManager.class);
+ waitForDialogComponent(WizardDialog.class);
checkWizardButtonEnablement(false, false, false, true);
chooseFromCorrelationPanel("Exact Function Instructions Match", VTWizardPanelAction.NEXT);
@@ -179,11 +180,11 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
assertNotNull(controller.getSourceProgram());
assertNotNull(controller.getDestinationProgram());
- createWizardManager();
+ createWizardDialog();
- runSwingLater(() -> wizardManager.showWizard(controller.getParentComponent()));
+ runSwingLater(() -> wizardDialog.show(controller.getParentComponent()));
- waitForDialogComponent(WizardManager.class);
+ waitForDialogComponent(WizardDialog.class);
checkWizardButtonEnablement(false, false, false, true);
chooseFromCorrelationPanel("Exact Function Instructions Match", VTWizardPanelAction.NEXT);
@@ -239,11 +240,11 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
assertNotNull(controller.getSourceProgram());
assertNotNull(controller.getDestinationProgram());
- createWizardManager();
+ createWizardDialog();
- runSwingLater(() -> wizardManager.showWizard(controller.getParentComponent()));
+ runSwingLater(() -> wizardDialog.show(controller.getParentComponent()));
- waitForDialogComponent(WizardManager.class);
+ waitForDialogComponent(WizardDialog.class);
checkWizardButtonEnablement(false, false, false, true);
chooseFromCorrelationPanel("Exact Function Instructions Match", VTWizardPanelAction.NEXT);
@@ -299,11 +300,11 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
assertNotNull(controller.getSourceProgram());
assertNotNull(controller.getDestinationProgram());
- createWizardManager();
+ createWizardDialog();
- runSwingLater(() -> wizardManager.showWizard(controller.getParentComponent()));
+ runSwingLater(() -> wizardDialog.show(controller.getParentComponent()));
- waitForDialogComponent(WizardManager.class);
+ waitForDialogComponent(WizardDialog.class);
checkWizardButtonEnablement(false, false, false, true);
chooseFromCorrelationPanel("Exact Function Instructions Match", VTWizardPanelAction.NEXT);
@@ -374,11 +375,11 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
createSelectionInSourceAndDestinationTools();
- createWizardManager();
+ createWizardDialog();
- runSwingLater(() -> wizardManager.showWizard(controller.getParentComponent()));
+ runSwingLater(() -> wizardDialog.show(controller.getParentComponent()));
- waitForDialogComponent(WizardManager.class);
+ waitForDialogComponent(WizardDialog.class);
checkWizardButtonEnablement(false, false, false, true);
chooseFromCorrelationPanel("Exact Function Instructions Match", VTWizardPanelAction.NEXT);
@@ -436,11 +437,11 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
createSelectionInSourceAndDestinationTools();
- createWizardManager();
+ createWizardDialog();
- runSwingLater(() -> wizardManager.showWizard(controller.getParentComponent()));
+ runSwingLater(() -> wizardDialog.show(controller.getParentComponent()));
- waitForDialogComponent(WizardManager.class);
+ waitForDialogComponent(WizardDialog.class);
checkWizardButtonEnablement(false, false, false, true);
chooseFromCorrelationPanel("Exact Function Instructions Match", VTWizardPanelAction.NEXT);
@@ -498,11 +499,11 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
createSelectionInSourceAndDestinationTools();
- createWizardManager();
+ createWizardDialog();
- runSwingLater(() -> wizardManager.showWizard(controller.getParentComponent()));
+ runSwingLater(() -> wizardDialog.show(controller.getParentComponent()));
- waitForDialogComponent(WizardManager.class);
+ waitForDialogComponent(WizardDialog.class);
checkWizardButtonEnablement(false, false, false, true);
chooseFromCorrelationPanel("Exact Function Instructions Match", VTWizardPanelAction.NEXT);
@@ -573,11 +574,11 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
createSelectionInSourceAndDestinationTools();
- createWizardManager();
+ createWizardDialog();
- runSwingLater(() -> wizardManager.showWizard(controller.getParentComponent()));
+ runSwingLater(() -> wizardDialog.show(controller.getParentComponent()));
- waitForDialogComponent(WizardManager.class);
+ waitForDialogComponent(WizardDialog.class);
checkWizardButtonEnablement(false, false, false, true);
chooseFromCorrelationPanel("Exact Function Instructions Match", VTWizardPanelAction.NEXT);
@@ -673,11 +674,11 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
assertNotNull(controller.getSourceProgram());
assertNotNull(controller.getDestinationProgram());
- createWizardManager();
+ createWizardDialog();
- runSwingLater(() -> wizardManager.showWizard(controller.getParentComponent()));
+ runSwingLater(() -> wizardDialog.show(controller.getParentComponent()));
- waitForDialogComponent(WizardManager.class);
+ waitForDialogComponent(WizardDialog.class);
checkWizardButtonEnablement(false, false, false, true);
chooseFromCorrelationPanel("Data Reference Match", VTWizardPanelAction.NEXT);
@@ -730,10 +731,10 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
private void chooseFromCorrelationPanel(String correlatorName,
VTWizardPanelAction wizardAction) {
- WizardPanel currentWizardPanel = wizardManager.getCurrentWizardPanel();
- assertNotNull(currentWizardPanel);
- assertTrue(currentWizardPanel instanceof CorrelatorPanel);
- CorrelatorPanel correlatorPanel = (CorrelatorPanel) currentWizardPanel;
+ WizardStep> currentStep = wizardDialog.getCurrentStep();
+ assertNotNull(currentStep);
+ CorrelatorChooserPanel correlatorPanel =
+ (CorrelatorChooserPanel) currentStep.getComponent();
SystemUtilities.runSwingNow(() -> {
GhidraTable table = (GhidraTable) TestUtils.getInstanceField("table", correlatorPanel);
TableModel model = table.getModel();
@@ -750,59 +751,28 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
VTWizardPanelAction wizardAction) {
// Options Panel
- WizardPanel currentWizardPanel = wizardManager.getCurrentWizardPanel();
- assertNotNull(currentWizardPanel);
- assertTrue(currentWizardPanel instanceof OptionsPanel);
- // Nothing else to check in this panel for now.
-
- // TODO Use an OptionsObject or something to pass in correlator options and set them in the panel.
-// // get out the correlator options
-// AddressCorrelatorManager correlator = controller.getCorrelator();
-// assertNotNull("The controller did not find any correlators", correlator);
-//
-// // set some options settings
-// Options options = correlator.getOptions(LCSAddressCorrelator.class);
-// String testDefaultValue = "Test Default Value";
-// String testOptionKey = "Test Option Name";
-// String value = options.getString(testOptionKey, testDefaultValue);
-// assertEquals(value, testDefaultValue);
-//
-// String firstNewOptionValue = "New Option Value";
-// options.putString(testOptionKey, firstNewOptionValue);
-// assertEquals(firstNewOptionValue, options.getString(testOptionKey, null));
-// correlator.setOptions(LCSAddressCorrelator.class, options);
-// // save the options
-// SaveState saveState = new SaveState();
-// controller.writeConfigState(saveState);
-//
-// // change the options
-// String secondNewValue = "Second New Value";
-// options.putString(testOptionKey, secondNewValue);
-// correlator.setOptions(LCSAddressCorrelator.class, options);
-//
-// // pull the values again and make sure they are still correct (that writing the config
-// // state did not change the cached controller and options)
-// correlator = controller.getCorrelator();
-// options = correlator.getOptions(LCSAddressCorrelator.class);
-// assertEquals(secondNewValue, options.getString(testOptionKey, null));
-
+ WizardStep> currentStep = wizardDialog.getCurrentStep();
+ JComponent component = currentStep.getComponent();
+ assertTrue(component instanceof OptionsPanel);
+ OptionsPanel optionsPanel = (OptionsPanel) component;
+ assertNotNull(optionsPanel);
SystemUtilities.runSwingNow(() -> invoke(wizardAction));
}
private void checkAddressSetOptionsPanel(boolean excludeAccepted, boolean limitAddressSets) {
// Address Set Options Panel
- WizardPanel currentWizardPanel = wizardManager.getCurrentWizardPanel();
- assertNotNull(currentWizardPanel);
- assertTrue(currentWizardPanel instanceof AddressSetOptionsPanel);
- AddressSetOptionsPanel addressSetOptionsPanel = (AddressSetOptionsPanel) currentWizardPanel;
+ WizardStep> currentStep = wizardDialog.getCurrentStep();
+ JComponent component = currentStep.getComponent();
+ assertTrue(component instanceof AddressSetOptionsPanel);
+ AddressSetOptionsPanel addressSetOptionsPanel = (AddressSetOptionsPanel) component;
JCheckBox excludeCheckbox =
(JCheckBox) TestUtils.getInstanceField("excludeCheckbox", addressSetOptionsPanel);
assertNotNull(excludeCheckbox);
JCheckBox showAddressSetPanelsCheckbox = (JCheckBox) TestUtils
- .getInstanceField("showAddressSetPanelsCheckbox", addressSetOptionsPanel);
+ .getInstanceField("limitAddressSetsCheckbox", addressSetOptionsPanel);
assertNotNull(showAddressSetPanelsCheckbox);
assertEquals("Exclude Accepted Matches checkbox", excludeAccepted,
@@ -815,17 +785,17 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
VTWizardPanelAction wizardAction) {
// Address Set Options Panel
- WizardPanel currentWizardPanel = wizardManager.getCurrentWizardPanel();
- assertNotNull(currentWizardPanel);
- assertTrue(currentWizardPanel instanceof AddressSetOptionsPanel);
- AddressSetOptionsPanel addressSetOptionsPanel = (AddressSetOptionsPanel) currentWizardPanel;
+ WizardStep> currentStep = wizardDialog.getCurrentStep();
+ JComponent component = currentStep.getComponent();
+ assertTrue(component instanceof AddressSetOptionsPanel);
+ AddressSetOptionsPanel addressSetOptionsPanel = (AddressSetOptionsPanel) component;
JCheckBox excludeCheckbox =
(JCheckBox) TestUtils.getInstanceField("excludeCheckbox", addressSetOptionsPanel);
assertNotNull(excludeCheckbox);
JCheckBox showAddressSetPanelsCheckbox = (JCheckBox) TestUtils
- .getInstanceField("showAddressSetPanelsCheckbox", addressSetOptionsPanel);
+ .getInstanceField("limitAddressSetsCheckbox", addressSetOptionsPanel);
assertNotNull(showAddressSetPanelsCheckbox);
if (excludeCheckbox.isSelected() != excludeAccepted) {
@@ -843,17 +813,18 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
AddressSetChoice destinationChoice) {
// Address Set Options Panel
- WizardPanel currentWizardPanel = wizardManager.getCurrentWizardPanel();
- assertNotNull(currentWizardPanel);
- assertTrue(currentWizardPanel instanceof LimitAddressSetsPanel);
- LimitAddressSetsPanel limitAddressSetsPanel = (LimitAddressSetsPanel) currentWizardPanel;
+ WizardStep> currentStep = wizardDialog.getCurrentStep();
+ JComponent component = currentStep.getComponent();
+ assertTrue(component instanceof LimitAddressSetsPanel);
+ LimitAddressSetsPanel limitAddressSetsPanel = (LimitAddressSetsPanel) component;
+ ChooseAddressSetEditorPanel sourcePanel =
+ (ChooseAddressSetEditorPanel) TestUtils.getInstanceField("sourcePanel",
+ limitAddressSetsPanel);
+ ChooseAddressSetEditorPanel destinationPanel =
+ (ChooseAddressSetEditorPanel) TestUtils.getInstanceField("destinationPanel",
+ limitAddressSetsPanel);
- AddressSetPanel sourcePanel =
- (AddressSetPanel) TestUtils.getInstanceField("sourcePanel", limitAddressSetsPanel);
assertNotNull(sourcePanel);
-
- AddressSetPanel destinationPanel =
- (AddressSetPanel) TestUtils.getInstanceField("destinationPanel", limitAddressSetsPanel);
assertNotNull(destinationPanel);
changeAddressChoice(sourcePanel, sourceChoice);
@@ -864,31 +835,25 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
AddressSetView desiredDestinationSet) {
// Address Set Options Panel
- WizardPanel currentWizardPanel = wizardManager.getCurrentWizardPanel();
- assertNotNull(currentWizardPanel);
- assertTrue(currentWizardPanel instanceof LimitAddressSetsPanel);
- LimitAddressSetsPanel limitAddressSetsPanel = (LimitAddressSetsPanel) currentWizardPanel;
+ WizardStep> currentStep = wizardDialog.getCurrentStep();
+ JComponent component = currentStep.getComponent();
+ assertTrue(component instanceof LimitAddressSetsPanel);
+ LimitAddressSetsPanel limitAddressSetsPanel = (LimitAddressSetsPanel) component;
+
+ ChooseAddressSetEditorPanel sourcePanel =
+ (ChooseAddressSetEditorPanel) TestUtils.getInstanceField("sourcePanel",
+ limitAddressSetsPanel);
+ ChooseAddressSetEditorPanel destinationPanel =
+ (ChooseAddressSetEditorPanel) TestUtils.getInstanceField("destinationPanel",
+ limitAddressSetsPanel);
- AddressSetPanel sourcePanel =
- (AddressSetPanel) TestUtils.getInstanceField("sourcePanel", limitAddressSetsPanel);
assertNotNull(sourcePanel);
-
- AddressSetPanel destinationPanel =
- (AddressSetPanel) TestUtils.getInstanceField("destinationPanel", limitAddressSetsPanel);
assertNotNull(destinationPanel);
- ChooseAddressSetEditorPanel sourceSetPanel =
- (ChooseAddressSetEditorPanel) TestUtils.getInstanceField("panel", sourcePanel);
- assertNotNull(sourceSetPanel);
-
- ChooseAddressSetEditorPanel destinationSetPanel =
- (ChooseAddressSetEditorPanel) TestUtils.getInstanceField("panel", destinationPanel);
- assertNotNull(destinationSetPanel);
-
AddressSetView panelSourceSet =
- (AddressSetView) TestUtils.invokeInstanceMethod("getAddressSetView", sourceSetPanel);
+ (AddressSetView) TestUtils.invokeInstanceMethod("getAddressSetView", sourcePanel);
AddressSetView panelDestinationSet = (AddressSetView) TestUtils
- .invokeInstanceMethod("getAddressSetView", destinationSetPanel);
+ .invokeInstanceMethod("getAddressSetView", destinationPanel);
assertEquals("Source Address Set", desiredSourceSet, panelSourceSet);
assertEquals("Destination Address Set", desiredDestinationSet, panelDestinationSet);
}
@@ -897,17 +862,19 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
AddressSetView desiredDestinationSet) {
// Address Set Options Panel
- WizardPanel currentWizardPanel = wizardManager.getCurrentWizardPanel();
- assertNotNull(currentWizardPanel);
- assertTrue(currentWizardPanel instanceof LimitAddressSetsPanel);
- LimitAddressSetsPanel limitAddressSetsPanel = (LimitAddressSetsPanel) currentWizardPanel;
+ WizardStep> currentStep = wizardDialog.getCurrentStep();
+ JComponent component = currentStep.getComponent();
+ assertTrue(component instanceof LimitAddressSetsPanel);
+ LimitAddressSetsPanel limitAddressSetsPanel = (LimitAddressSetsPanel) component;
+
+ ChooseAddressSetEditorPanel sourcePanel =
+ (ChooseAddressSetEditorPanel) TestUtils.getInstanceField("sourcePanel",
+ limitAddressSetsPanel);
+ ChooseAddressSetEditorPanel destinationPanel =
+ (ChooseAddressSetEditorPanel) TestUtils.getInstanceField("destinationPanel",
+ limitAddressSetsPanel);
- AddressSetPanel sourcePanel =
- (AddressSetPanel) TestUtils.getInstanceField("sourcePanel", limitAddressSetsPanel);
assertNotNull(sourcePanel);
-
- AddressSetPanel destinationPanel =
- (AddressSetPanel) TestUtils.getInstanceField("destinationPanel", limitAddressSetsPanel);
assertNotNull(destinationPanel);
changeAddressSetViaListRemoveRange(true, sourcePanel, desiredSourceSet);
@@ -918,37 +885,35 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
AddressSetChoice destinationChoice) {
// Address Set Options Panel
- WizardPanel currentWizardPanel = wizardManager.getCurrentWizardPanel();
- assertNotNull(currentWizardPanel);
- assertTrue(currentWizardPanel instanceof LimitAddressSetsPanel);
- LimitAddressSetsPanel limitAddressSetsPanel = (LimitAddressSetsPanel) currentWizardPanel;
+ WizardStep> currentStep = wizardDialog.getCurrentStep();
+ JComponent component = currentStep.getComponent();
+ assertTrue(component instanceof LimitAddressSetsPanel);
+ LimitAddressSetsPanel limitAddressSetsPanel = (LimitAddressSetsPanel) component;
- AddressSetPanel sourcePanel =
- (AddressSetPanel) TestUtils.getInstanceField("sourcePanel", limitAddressSetsPanel);
+ ChooseAddressSetEditorPanel sourcePanel =
+ (ChooseAddressSetEditorPanel) TestUtils.getInstanceField("sourcePanel",
+ limitAddressSetsPanel);
assertNotNull(sourcePanel);
- AddressSetPanel destinationPanel =
- (AddressSetPanel) TestUtils.getInstanceField("destinationPanel", limitAddressSetsPanel);
+ ChooseAddressSetEditorPanel destinationPanel =
+ (ChooseAddressSetEditorPanel) TestUtils.getInstanceField("destinationPanel",
+ limitAddressSetsPanel);
assertNotNull(destinationPanel);
checkAddressChoice(sourcePanel, sourceChoice);
checkAddressChoice(destinationPanel, destinationChoice);
}
- private void checkAddressChoice(AddressSetPanel addressSetPanel,
+ private void checkAddressChoice(ChooseAddressSetEditorPanel panel,
AddressSetChoice expectedChoice) {
- ChooseAddressSetEditorPanel panel =
- (ChooseAddressSetEditorPanel) TestUtils.getInstanceField("panel", addressSetPanel);
assertNotNull(panel);
AddressSetChoice addressSetChoice = panel.getAddressSetChoice();
- assertEquals(addressSetPanel.getName() + " Panel address set choice", expectedChoice,
+ assertEquals(panel.getName() + " Panel address set choice", expectedChoice,
addressSetChoice);
}
- private void changeAddressChoice(AddressSetPanel addressSetPanel,
+ private void changeAddressChoice(ChooseAddressSetEditorPanel panel,
AddressSetChoice expectedChoice) {
- ChooseAddressSetEditorPanel panel =
- (ChooseAddressSetEditorPanel) TestUtils.getInstanceField("panel", addressSetPanel);
assertNotNull(panel);
AddressSetChoice addressSetChoice = panel.getAddressSetChoice();
if (expectedChoice != addressSetChoice) {
@@ -976,9 +941,7 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
}
private void changeAddressSetViaListRemoveRange(boolean isSource,
- AddressSetPanel addressSetPanel, AddressSetView desiredAddressSet) {
- ChooseAddressSetEditorPanel panel =
- (ChooseAddressSetEditorPanel) TestUtils.getInstanceField("panel", addressSetPanel);
+ ChooseAddressSetEditorPanel panel, AddressSetView desiredAddressSet) {
assertNotNull(panel);
JButton addRangeButton = (JButton) TestUtils.getInstanceField("addRangeButton", panel);
@@ -1006,9 +969,7 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
}
private void changeAddressSetViaSubtractDialog(boolean isSource,
- AddressSetPanel addressSetPanel, AddressSetView desiredAddressSet) {
- ChooseAddressSetEditorPanel panel =
- (ChooseAddressSetEditorPanel) TestUtils.getInstanceField("panel", addressSetPanel);
+ ChooseAddressSetEditorPanel panel, AddressSetView desiredAddressSet) {
assertNotNull(panel);
JButton addRangeButton = (JButton) TestUtils.getInstanceField("addRangeButton", panel);
@@ -1128,11 +1089,11 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
VTWizardPanelAction wizardAction) {
// Address Set Options Panel
- WizardPanel currentWizardPanel = wizardManager.getCurrentWizardPanel();
- assertNotNull(currentWizardPanel);
- assertTrue(currentWizardPanel instanceof SummaryPanel);
- SummaryPanel summaryPanel = (SummaryPanel) currentWizardPanel;
-
+ WizardStep> currentStep = wizardDialog.getCurrentStep();
+ assertNotNull(currentStep);
+ JComponent component = currentStep.getComponent();
+ assertTrue(component instanceof SummaryPanel);
+ SummaryPanel summaryPanel = (SummaryPanel) component;
JLabel labelLabel = (JLabel) TestUtils.getInstanceField("labelLabel", summaryPanel);
assertNotNull(labelLabel);
@@ -1180,7 +1141,7 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
private void checkWizardButtonEnablement(boolean backEnabled, boolean nextEnabled,
boolean finishEnabled, boolean cancelEnabled) {
- JComponent component = wizardManager.getComponent();
+ JComponent component = wizardDialog.getComponent();
JButton backButton = findButtonByText(component, "<< Back");
JButton nextButton = findButtonByText(component, "Next >>");
JButton finishButton = findButtonByText(component, "Finish");
@@ -1198,16 +1159,16 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
public void invoke(VTWizardPanelAction wizardAction) {
switch (wizardAction) {
case BACK:
- wizardManager.back();
+ wizardModel.goBack();
break;
case NEXT:
- wizardManager.next();
+ wizardModel.goNext();
break;
case FINISH:
- wizardManager.finish();
+ wizardModel.finish();
break;
case CANCEL:
- wizardManager.close();
+ wizardDialog.close();
break;
}
}
@@ -1228,10 +1189,10 @@ public class VTAddToSessionTest extends AbstractGhidraHeadedIntegrationTest {
return destinationProgram.getAddressFactory().getAddress(addressString);
}
- private void createWizardManager() {
+ private void createWizardDialog() {
runSwing(() -> {
- vtWizardManager = new VTAddToSessionWizardManager(controller);
- wizardManager = new WizardManager("Version Tracking Wizard", true, vtWizardManager);
+ wizardModel = new VTAddToSessionWizardModel(controller);
+ wizardDialog = new WizardDialog(wizardModel);
});
}
}
diff --git a/Ghidra/Features/VersionTracking/src/test.slow/java/ghidra/feature/vt/gui/provider/AbstractVTCorrelatorTest.java b/Ghidra/Features/VersionTracking/src/test.slow/java/ghidra/feature/vt/gui/provider/AbstractVTCorrelatorTest.java
index a8e5015797..edf4997551 100644
--- a/Ghidra/Features/VersionTracking/src/test.slow/java/ghidra/feature/vt/gui/provider/AbstractVTCorrelatorTest.java
+++ b/Ghidra/Features/VersionTracking/src/test.slow/java/ghidra/feature/vt/gui/provider/AbstractVTCorrelatorTest.java
@@ -5,9 +5,9 @@
* 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.
@@ -30,8 +30,8 @@ import org.junit.After;
import org.junit.Before;
import docking.options.editor.OptionsEditorPanel;
-import docking.wizard.WizardManager;
-import docking.wizard.WizardPanel;
+import docking.wizard.WizardDialog;
+import docking.wizard.WizardStep;
import generic.lsh.LSHMemoryModel;
import generic.test.TestUtils;
import ghidra.feature.vt.api.correlator.program.VTAbstractReferenceProgramCorrelatorFactory;
@@ -42,7 +42,8 @@ import ghidra.feature.vt.gui.plugin.VTController;
import ghidra.feature.vt.gui.plugin.VTPlugin;
import ghidra.feature.vt.gui.task.AcceptMatchTask;
import ghidra.feature.vt.gui.task.ApplyMatchTask;
-import ghidra.feature.vt.gui.wizard.*;
+import ghidra.feature.vt.gui.wizard.add.*;
+import ghidra.feature.vt.gui.wizard.session.SummaryPanel;
import ghidra.framework.options.*;
import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.address.Address;
@@ -70,8 +71,8 @@ public abstract class AbstractVTCorrelatorTest extends AbstractGhidraHeadedInteg
protected Program destProg;
protected VTController controller;
protected VTPlugin plugin;
- protected VTAddToSessionWizardManager vtWizardManager;
- protected WizardManager wizardManager;
+ protected VTAddToSessionWizardModel wizardModel;
+ protected WizardDialog wizardDialog;
public AbstractVTCorrelatorTest(String sourceProgLoc, String destProgLoc) {
this.sourceProgLoc = sourceProgLoc;
@@ -105,17 +106,17 @@ public abstract class AbstractVTCorrelatorTest extends AbstractGhidraHeadedInteg
private void setupWizardBeforeCorrelatorOptions(String correlatorName) {
runSwing(() -> {
- vtWizardManager = new VTAddToSessionWizardManager(controller);
- wizardManager = new WizardManager("Version Tracking Wizard", true, vtWizardManager);
- wizardManager.showWizard(controller.getParentComponent());
+ wizardModel = new VTAddToSessionWizardModel(controller);
+ wizardDialog = new WizardDialog(wizardModel);
+ wizardDialog.show(controller.getParentComponent());
}, false);
waitForSwing();
- waitForDialogComponent(WizardManager.class);
- assertNotNull(wizardManager);
+ waitForDialogComponent(WizardDialog.class);
+ assertNotNull(wizardDialog);
checkWizardButtonEnablement(false, false, false, true);
- chooseFromCorrelationPanel(correlatorName, wizardManager::next);
+ chooseFromCorrelationPanel(correlatorName, wizardModel::goNext);
checkWizardButtonEnablement(true, true, true, true);
}
@@ -123,7 +124,7 @@ public abstract class AbstractVTCorrelatorTest extends AbstractGhidraHeadedInteg
private void finishWizardAfterCorrelatorOptions(String correlatorName) {
checkAddressSetOptionsPanel(false, false);
checkWizardButtonEnablement(true, true, true, true);
- changeAddressSetOptionsPanel(false, false, wizardManager::next);
+ changeAddressSetOptionsPanel(false, false, wizardModel::goNext);
// Check the summary panel.
checkWizardButtonEnablement(true, false, true, true);
@@ -137,7 +138,7 @@ public abstract class AbstractVTCorrelatorTest extends AbstractGhidraHeadedInteg
String summaryString = "Add to Version Tracking Session
" + session.getName() + "
" +
srcProg.getName() + "
" + destProg.getName() + "
" + correlatorName + "
" +
"No
" + "Entire Source Program
" + "Entire Destination Program
" + "