From e25c7d881acbcdcf378ac23b7e1b7151f79554b7 Mon Sep 17 00:00:00 2001 From: dragonmacher <48328597+dragonmacher@users.noreply.github.com> Date: Fri, 17 Jan 2020 18:51:32 -0500 Subject: [PATCH] GT-3459 - Updated parentless dialogs to use a visible hidden parent --- .../feature/fid/plugin/TextAreaDialog.java | 9 +---- .../DefaultFidPopulateResultReporter.java | 8 ++--- .../src/main/java/docking/DockingDialog.java | 36 +++++++++++++++---- .../main/java/docking/HiddenDockingFrame.java | 15 ++++++-- .../framework/DockingApplicationLayout.java | 9 ++--- .../java/docking/framework/SplashScreen.java | 3 +- .../framework/main/UserAgreementDialog.java | 9 ++++- .../framework/ApplicationProperties.java | 8 +++-- .../ghidra/framework/ApplicationVersion.java | 4 ++- 9 files changed, 69 insertions(+), 32 deletions(-) diff --git a/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/plugin/TextAreaDialog.java b/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/plugin/TextAreaDialog.java index 199657a658..4f55941dcb 100644 --- a/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/plugin/TextAreaDialog.java +++ b/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/plugin/TextAreaDialog.java @@ -38,15 +38,8 @@ public class TextAreaDialog extends DialogComponentProvider { return sp; } - public void setOuterDialog(JDialog outerDialog) { - this.outerDialog = outerDialog; - } - @Override protected void okCallback() { - if (outerDialog != null) { - outerDialog.setVisible(false); - outerDialog = null; - } + close(); } } diff --git a/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/service/DefaultFidPopulateResultReporter.java b/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/service/DefaultFidPopulateResultReporter.java index e4b4b1bec1..c8ffa823bc 100644 --- a/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/service/DefaultFidPopulateResultReporter.java +++ b/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/service/DefaultFidPopulateResultReporter.java @@ -17,9 +17,7 @@ package ghidra.feature.fid.service; import java.util.Map.Entry; -import javax.swing.JDialog; - -import docking.DockingDialog; +import docking.DockingWindowManager; import ghidra.feature.fid.plugin.TextAreaDialog; import ghidra.feature.fid.service.FidPopulateResult.Disposition; @@ -70,9 +68,7 @@ public class DefaultFidPopulateResultReporter implements FidPopulateResultReport } TextAreaDialog dialog = new TextAreaDialog("FidDb Popluate Results", buffer.toString(), true); - JDialog d = new DockingDialog(dialog, null); - dialog.setOuterDialog(d); - d.setVisible(true); + DockingWindowManager.showDialog(dialog); } } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/DockingDialog.java b/Ghidra/Framework/Docking/src/main/java/docking/DockingDialog.java index 7bf44e886b..919fba4d0d 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/DockingDialog.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/DockingDialog.java @@ -18,13 +18,16 @@ package docking; import java.awt.*; import java.awt.event.*; import java.util.*; +import java.util.List; import javax.swing.*; import org.apache.commons.collections4.map.LazyMap; +import docking.framework.ApplicationInformationDisplayFactory; import docking.help.HelpDescriptor; import generic.util.WindowUtilities; +import ghidra.framework.Application; import ghidra.util.bean.GGlassPane; // NOTE: this class has a static focus component variable that is set whenever the dialog gets @@ -51,18 +54,39 @@ public class DockingDialog extends JDialog implements HelpDescriptor { private WindowAdapter modalFixWindowAdapter; + /** + * Creates a default parent frame that will appear in the OS's task bar. Having this frame + * gives the user something to click when their dialog is lost. We attempt to hide this + * frame offscreen. + * + * Note: we expect to only get here when there is no parent window found. This usually + * only happens during tests and one-off main methods that are not part of a + * running tool. + * + * @param componentProvider the dialog content for this dialog + * @return the hidden frame + */ private static JFrame createHiddenParentFrame(DialogComponentProvider componentProvider) { - HiddenDockingFrame frame = new HiddenDockingFrame(componentProvider.getTitle()); - frame.setBounds(-500, -500, 10, 10); - // we currently don't support icons from DialogComponentProvider - // frame.setIconImage( ... ) + // + // Note: we expect to only get here when there is no parent window found. This usually + // only happens during tests and one-off main methods that are not part of a + // running tool + // + HiddenDockingFrame hiddenFrame = new HiddenDockingFrame(Application.getName()); + hiddenFrame.setShowingAllowed(true); + List list = ApplicationInformationDisplayFactory.getWindowIcons(); + hiddenFrame.setIconImages(list); + hiddenFrame.setUndecorated(true); + + hiddenFrame.setBounds(-500, -500, 10, 10); // This prevents a window from showing in the taskbar; it is assumed that we the // window to appear in the taskbar. If clients need this in the future, then we would // have to make it a value on the DialogComponentProvider // frame.setHidden( true ); // make invisible - return frame; + hiddenFrame.setVisible(true); + return hiddenFrame; } public static DockingDialog createDialog(Window parent, DialogComponentProvider comp, @@ -94,7 +118,7 @@ public class DockingDialog extends JDialog implements HelpDescriptor { initializeLocationAndSize(centeredOnComponent); } - public DockingDialog(DialogComponentProvider comp, Component centeredOnComponent) { + private DockingDialog(DialogComponentProvider comp, Component centeredOnComponent) { super(createHiddenParentFrame(comp), comp.getTitle(), comp.isModal()); init(comp); initializeLocationAndSize(centeredOnComponent); diff --git a/Ghidra/Framework/Docking/src/main/java/docking/HiddenDockingFrame.java b/Ghidra/Framework/Docking/src/main/java/docking/HiddenDockingFrame.java index 3aa97c1f14..a3ee57915d 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/HiddenDockingFrame.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/HiddenDockingFrame.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,13 +23,23 @@ package docking; */ public class HiddenDockingFrame extends DockingFrame { + private boolean showingAllowed; + public HiddenDockingFrame(String name) { super(name); } - @Override + void setShowingAllowed(boolean showingAllowed) { + this.showingAllowed = showingAllowed; + } + + @SuppressWarnings("deprecation") + @Override public void show() { - // overridden to make sure nobody ever sees this frame when it's hidden + // overridden to make sure only some clients can show this frame + if (showingAllowed) { + super.show(); + } } } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/framework/DockingApplicationLayout.java b/Ghidra/Framework/Docking/src/main/java/docking/framework/DockingApplicationLayout.java index acd11e6372..7e0975539c 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/framework/DockingApplicationLayout.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/framework/DockingApplicationLayout.java @@ -16,7 +16,6 @@ package docking.framework; import java.io.FileNotFoundException; -import java.io.IOException; import java.util.ArrayList; import java.util.Objects; @@ -33,14 +32,16 @@ import utility.module.ModuleUtilities; */ public class DockingApplicationLayout extends ApplicationLayout { + private static final String NO_RELEASE_NAME = "NO_RELEASE"; + /** * Constructs a new docking application layout object with the given name. * * @param name The name of the application. * @throws FileNotFoundException if there was a problem getting a user directory. */ - public DockingApplicationLayout(String name) throws FileNotFoundException, IOException { - this(name, null); + public DockingApplicationLayout(String name) throws FileNotFoundException { + this(name, "0.1"); } /** @@ -51,7 +52,7 @@ public class DockingApplicationLayout extends ApplicationLayout { * @throws FileNotFoundException if there was a problem getting a user directory. */ public DockingApplicationLayout(String name, String version) throws FileNotFoundException { - this(new ApplicationProperties(name, version)); + this(new ApplicationProperties(name, version, NO_RELEASE_NAME)); } /** diff --git a/Ghidra/Framework/Docking/src/main/java/docking/framework/SplashScreen.java b/Ghidra/Framework/Docking/src/main/java/docking/framework/SplashScreen.java index 4ca8cdb3bd..25f4bd343b 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/framework/SplashScreen.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/framework/SplashScreen.java @@ -344,8 +344,9 @@ public class SplashScreen extends JWindow { } public static void main(String[] args) throws Exception { - ApplicationLayout layout = new DockingApplicationLayout("SplashScreen"); + ApplicationLayout layout = new DockingApplicationLayout("Splash Screen Main", "1.0"); DockingApplicationConfiguration config = new DockingApplicationConfiguration(); + config.setShowSplashScreen(false); Application.initializeApplication(layout, config); showSplashScreen(); diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/UserAgreementDialog.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/UserAgreementDialog.java index 8610612d3c..b2cc8fb9d4 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/UserAgreementDialog.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/UserAgreementDialog.java @@ -23,12 +23,16 @@ import javax.swing.text.html.HTMLEditorKit; import docking.DialogComponentProvider; import docking.DockingWindowManager; +import docking.framework.DockingApplicationConfiguration; +import docking.framework.DockingApplicationLayout; import docking.widgets.label.GDLabel; +import ghidra.framework.Application; import ghidra.util.HTMLUtilities; import ghidra.util.Msg; import ghidra.util.layout.VerticalLayout; import resources.ResourceManager; import utilities.util.FileUtilities; +import utility.application.ApplicationLayout; public class UserAgreementDialog extends DialogComponentProvider { private static final String USER_AGREEMENT_FILENAME = "UserAgreement.html"; @@ -108,7 +112,10 @@ public class UserAgreementDialog extends DialogComponentProvider { close(); } - public static void main(String[] args) { + public static void main(String[] args) throws Exception { + ApplicationLayout layout = new DockingApplicationLayout("User Agreement Main", "1.0"); + DockingApplicationConfiguration config = new DockingApplicationConfiguration(); + Application.initializeApplication(layout, config); UserAgreementDialog dialog = new UserAgreementDialog(true, true); DockingWindowManager.showDialog(null, dialog); } diff --git a/Ghidra/Framework/Utility/src/main/java/ghidra/framework/ApplicationProperties.java b/Ghidra/Framework/Utility/src/main/java/ghidra/framework/ApplicationProperties.java index 75f8aa6858..81eac06658 100644 --- a/Ghidra/Framework/Utility/src/main/java/ghidra/framework/ApplicationProperties.java +++ b/Ghidra/Framework/Utility/src/main/java/ghidra/framework/ApplicationProperties.java @@ -151,11 +151,15 @@ public class ApplicationProperties extends Properties { * * @param name The application's name. * @param version The application's version. + * @param releaseName The application's release name. */ - public ApplicationProperties(String name, String version) { + public ApplicationProperties(String name, String version, String releaseName) { Objects.requireNonNull(name, "Application name cannot be null"); setProperty(APPLICATION_NAME_PROPERTY, name); + Objects.requireNonNull(releaseName, "Release name cannot be null"); + setProperty(RELEASE_NAME_PROPERTY, releaseName); + if (version != null) { setProperty(APPLICATION_VERSION_PROPERTY, version); } @@ -245,7 +249,7 @@ public class ApplicationProperties extends Properties { } return appVersion; } - + /** * Gets the application's release name. * diff --git a/Ghidra/Framework/Utility/src/main/java/ghidra/framework/ApplicationVersion.java b/Ghidra/Framework/Utility/src/main/java/ghidra/framework/ApplicationVersion.java index 51da17df99..b549c37003 100644 --- a/Ghidra/Framework/Utility/src/main/java/ghidra/framework/ApplicationVersion.java +++ b/Ghidra/Framework/Utility/src/main/java/ghidra/framework/ApplicationVersion.java @@ -195,8 +195,10 @@ public class ApplicationVersion implements Comparable { patch = parse(versionParts[2], "patch"); } else { + String plural = version.length() > 1 ? "s" : ""; throw new IllegalArgumentException( - "Version has " + versionParts.length + " parts but 2 or 3 are required"); + "Version '" + version + "' has " + versionParts.length + + " part" + plural + " but 2 or 3 are required"); } }