From a555a161109c5e05f65c020727e862cbf0977007 Mon Sep 17 00:00:00 2001 From: adamopolous Date: Wed, 8 May 2019 16:13:11 -0400 Subject: [PATCH 1/4] GT-2376: fixed hack with preferred size --- .../src/main/java/docking/widgets/HyperlinkComponent.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/HyperlinkComponent.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/HyperlinkComponent.java index 168dd1b7b3..1077beff74 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/widgets/HyperlinkComponent.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/HyperlinkComponent.java @@ -114,6 +114,7 @@ public class HyperlinkComponent extends JPanel { // Also, if we call getPreferredSize(), then it will work. // textPane.getPreferredSize(); + getPreferredSize(); } public String getText() { From d03b715f39514c4249d57ae963f70badc081f82a Mon Sep 17 00:00:00 2001 From: ghidra1 Date: Wed, 8 May 2019 17:33:13 -0400 Subject: [PATCH 2/4] GT-2856 Corrected SPE caused by project restore of non-checked-out file --- .../core/progmgr/ProgramManagerPlugin.java | 6 +++- .../ghidra/app/util/task/OpenProgramTask.java | 35 ++++++++++++++----- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/progmgr/ProgramManagerPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/progmgr/ProgramManagerPlugin.java index aaac0d6095..bfc828ac6f 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/progmgr/ProgramManagerPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/progmgr/ProgramManagerPlugin.java @@ -45,7 +45,8 @@ import ghidra.framework.main.OpenVersionedFileDialog; import ghidra.framework.model.*; import ghidra.framework.options.*; import ghidra.framework.plugintool.*; -import ghidra.framework.plugintool.util.*; +import ghidra.framework.plugintool.util.PluginStatus; +import ghidra.framework.plugintool.util.ToolConstants; import ghidra.framework.protocol.ghidra.*; import ghidra.program.database.ProgramContentHandler; import ghidra.program.model.address.*; @@ -1017,6 +1018,9 @@ public class ProgramManagerPlugin extends Plugin implements ProgramManager { return; } + // restore state should not ask about checking out + openTask.setNoCheckout(); + try { new TaskLauncher(openTask, tool.getToolFrame(), 100); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/task/OpenProgramTask.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/task/OpenProgramTask.java index 55bfe2a4c7..a12bf496ea 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/task/OpenProgramTask.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/task/OpenProgramTask.java @@ -42,7 +42,8 @@ public class OpenProgramTask extends Task { private List programList = new ArrayList<>(); private TaskMonitor monitor; private final Object consumer; - private boolean silent; + private boolean silent; // if true operation does not permit interaction + private boolean noCheckout; // if true operation should not perform optional checkout private String openPromptText = "Open"; @@ -91,10 +92,25 @@ public class OpenProgramTask extends Task { domainFileInfoList.add(new DomainFileInfo(domainFile, version, forceReadOnly)); } + /** + * Invoking this method prior to task execution will prevent + * any confirmation interaction with the user (e.g., + * optional checkout, snapshot recovery, etc.). Errors + * may still be displayed if they occur. + */ public void setSilent() { this.silent = true; } + /** + * Invoking this method prior to task execution will prevent + * the use of optional checkout which require prompting the + * user. + */ + public void setNoCheckout() { + this.noCheckout = true; + } + public List getOpenPrograms() { return programList; } @@ -189,10 +205,7 @@ public class OpenProgramTask extends Task { private void openUnversionedFile(DomainFile domainFile) { String filename = domainFile.getName(); monitor.setMessage("Opening " + filename); - if (!silent && domainFile.canCheckout() && domainFile.isInWritableProject()) { - checkout(domainFile); - } - + performOptionalCheckout(domainFile); try { openFileMaybeUgrade(domainFile); } @@ -260,15 +273,20 @@ public class OpenProgramTask extends Task { return result.get(); } - private boolean checkout(DomainFile domainFile) { - User user = AppInfo.getActiveProject().getProjectData().getUser(); + private void performOptionalCheckout(DomainFile domainFile) { + + if (silent || noCheckout || !domainFile.canCheckout()) { + return; + } + + User user = domainFile.getParent().getProjectData().getUser(); CheckoutDialog dialog = new CheckoutDialog(domainFile, user); if (dialog.showDialog() == CheckoutDialog.CHECKOUT) { try { monitor.setMessage("Checking Out " + domainFile.getName()); if (domainFile.checkout(dialog.exclusiveCheckout(), monitor)) { - return true; + return; } Msg.showError(this, null, "Checkout Failed", "Exclusive checkout failed for: " + domainFile.getName() + "\nOne or more users have file checked out!"); @@ -283,7 +301,6 @@ public class OpenProgramTask extends Task { Msg.showError(this, null, "Error on Check Out", e.getMessage(), e); } } - return false; } static class DomainFileInfo { From 85d11cc6baabef6603dd01917fcfc074e92c7f2d Mon Sep 17 00:00:00 2001 From: ghidra1 Date: Wed, 8 May 2019 18:09:28 -0400 Subject: [PATCH 3/4] GT-2856 Updated comment --- .../ghidra/app/plugin/core/progmgr/ProgramManagerPlugin.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/progmgr/ProgramManagerPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/progmgr/ProgramManagerPlugin.java index bfc828ac6f..b82f0243cc 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/progmgr/ProgramManagerPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/progmgr/ProgramManagerPlugin.java @@ -1018,7 +1018,9 @@ public class ProgramManagerPlugin extends Plugin implements ProgramManager { return; } - // restore state should not ask about checking out + // Restore state should not ask about checking out since + // hopefully it is in the same state it was in when project + // was closed and state was saved. openTask.setNoCheckout(); try { From 1444b0c27b4f2dfdcdee65dd1a059dd2a7f43a37 Mon Sep 17 00:00:00 2001 From: ghidra1 Date: Thu, 9 May 2019 11:43:11 -0400 Subject: [PATCH 4/4] GT-2856 Corrected restore project NPE observed when using large repository. --- .../main/datatable/ProjectDataTablePanel.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatable/ProjectDataTablePanel.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatable/ProjectDataTablePanel.java index 0f7ab9b912..8c2bcb4c7d 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatable/ProjectDataTablePanel.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatable/ProjectDataTablePanel.java @@ -36,6 +36,7 @@ import ghidra.framework.main.FrontEndPlugin; import ghidra.framework.model.*; import ghidra.framework.plugintool.PluginTool; import ghidra.util.HelpLocation; +import ghidra.util.SystemUtilities; import ghidra.util.bean.GGlassPane; import ghidra.util.bean.GGlassPanePainter; @@ -79,12 +80,12 @@ public class ProjectDataTablePanel extends JPanel { private void buildContent() { model = new ProjectDataTableModel(tool); model.addThreadedTableModelListener(new SelectPendingFilesListener()); - table = new GFilterTable(model) { + table = new GFilterTable<>(model) { @Override protected GThreadedTablePanel createThreadedTablePanel( ThreadedTableModel threadedModel) { - return new GThreadedTablePanel(threadedModel) { + return new GThreadedTablePanel<>(threadedModel) { @Override protected GTable createTable(ThreadedTableModel m) { // the table's default actions aren't that useful in the Front End @@ -267,10 +268,11 @@ public class ProjectDataTablePanel extends JPanel { capacityExceeded = true; this.projectData.removeDomainFolderChangeListener(changeListener); model.setProjectData(null); - - GGlassPane glassPane = (GGlassPane) gTable.getRootPane().getGlassPane(); - glassPane.removePainter(painter); - glassPane.addPainter(painter); + SystemUtilities.runSwingLater(() -> { + GGlassPane glassPane = (GGlassPane) gTable.getRootPane().getGlassPane(); + glassPane.removePainter(painter); + glassPane.addPainter(painter); + }); } }