Bug 578716 - Make p2's UIServices implementation work without a
workbench

In ValidationDialogServiceUI, provide a way to specify the shell
provider used to get the parent shell for dialogs about to be opened.
The default behavior is to continue to use
ProvUI.getDefaultParentShell().

Change-Id: I1640f7c544e17520daba48c60dd1577812ebb602
Signed-off-by: Ed Merks <ed.merks@gmail.com>
Reviewed-on: https://git.eclipse.org/r/c/equinox/rt.equinox.p2/+/190760
diff --git a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/ValidationDialogServiceUI.java b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/ValidationDialogServiceUI.java
index d801b1c..ae451f4 100644
--- a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/ValidationDialogServiceUI.java
+++ b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/ValidationDialogServiceUI.java
@@ -36,6 +36,7 @@
 import org.eclipse.equinox.p2.ui.LoadMetadataRepositoryJob;
 import org.eclipse.jface.dialogs.*;
 import org.eclipse.jface.viewers.TreeNode;
+import org.eclipse.jface.window.IShellProvider;
 import org.eclipse.jface.window.Window;
 import org.eclipse.osgi.util.NLS;
 import org.eclipse.swt.SWT;
@@ -67,6 +68,8 @@
 		}
 	};
 
+	private IShellProvider shellProvider = () -> ProvUI.getDefaultParentShell();
+
 	public ValidationDialogServiceUI() {
 		this(null);
 	}
@@ -127,7 +130,7 @@
 		final AuthenticationInfo[] result = new AuthenticationInfo[1];
 		if (!suppressAuthentication() && !isHeadless()) {
 			getDisplay().syncExec(() -> {
-				Shell shell = ProvUI.getDefaultParentShell();
+				Shell shell = shellProvider.getShell();
 				String message = NLS.bind(ProvUIMessages.ServiceUI_LoginDetails, location);
 				UserValidationDialog dialog = new UserValidationDialog(shell, ProvUIMessages.ServiceUI_LoginRequired,
 						null, message);
@@ -174,7 +177,7 @@
 			getDisplay().syncExec(new Runnable() {
 				@Override
 				public void run() {
-					Shell shell = ProvUI.getDefaultParentShell();
+					Shell shell = shellProvider.getShell();
 					OkCancelErrorDialog dialog = new OkCancelErrorDialog(shell, ProvUIMessages.ServiceUI_warning_title,
 							null, createStatus(), IStatus.WARNING);
 					result[0] = dialog.open() == IDialogConstants.OK_ID;
@@ -227,7 +230,7 @@
 				trustUnsigned = unsignedArtifacts == null || unsignedArtifacts.isEmpty();
 				List<Object> result = new ArrayList<>();
 				getDisplay().syncExec(() -> {
-					Shell shell = ProvUI.getDefaultParentShell();
+					Shell shell = shellProvider.getShell();
 					TrustCertificateDialog trustCertificateDialog = new TrustCertificateDialog(shell, input);
 					if (trustCertificateDialog.open() == Window.OK) {
 						Object[] dialogResult = trustCertificateDialog.getResult();
@@ -332,7 +335,7 @@
 		final AuthenticationInfo[] result = new AuthenticationInfo[1];
 		if (!suppressAuthentication() && !isHeadless()) {
 			getDisplay().syncExec(() -> {
-				Shell shell = ProvUI.getDefaultParentShell();
+				Shell shell = shellProvider.getShell();
 				String message = null;
 				if (previousInfo.saveResult())
 					message = NLS.bind(ProvUIMessages.ProvUIMessages_SavedNotAccepted_EnterFor_0, location);
@@ -359,7 +362,7 @@
 			return;
 		}
 		getDisplay().syncExec(() -> {
-			MessageDialog dialog = new MessageDialogWithLink(ProvUI.getDefaultParentShell(), title, null, text,
+			MessageDialog dialog = new MessageDialogWithLink(shellProvider.getShell(), title, null, text,
 					MessageDialog.INFORMATION, new String[] { IDialogConstants.OK_LABEL }, 0, linkText, linkHandler);
 			dialog.open();
 		});
@@ -392,6 +395,32 @@
 	}
 
 	/**
+	 * Returns a shell that is appropriate to use as the parent for a modal dialog
+	 * about to be opened.
+	 *
+	 * @return a shell that is appropriate to use as the parent for a modal dialog
+	 *         about to be opened.
+	 *
+	 * @see ProvUI#getDefaultParentShell()
+	 *
+	 * @since 2.7.400
+	 */
+	public IShellProvider getShellProvider() {
+		return shellProvider;
+	}
+
+	/**
+	 * Set the provider that yields a shell that is appropriate to use as the parent
+	 * for a modal dialog about to be opened.
+	 *
+	 * @param shellProvider the provider of a shell that is appropriate to use as
+	 *                      the parent for a modal dialog about to be opened.
+	 */
+	public void setShellProvider(IShellProvider shellProvider) {
+		this.shellProvider = shellProvider;
+	}
+
+	/**
 	 * Returns the display of the workbench or the display set by
 	 * {@link #setDisplay(Display)} in a non-workbench application.
 	 *