/*******************************************************************************
* Copyright (c) 2014 Red Hat, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* lufimtse : Leo Ufimtsev lufimtse@redhat.com
*******************************************************************************/
package org.eclipse.linuxtools.profiling.ui;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
/**
* <h1>UI sycned Message Dialogue </h1>
* <p>
* This class is for launching common messages <b>from background threads</b> and <b>getting a return value</b>.
* </p>
* <p>
* When you're not in a U.I thread, getting the 'shell' causes a runtime exception. <br>
* Never the less, sometimes you need user feedback when executing a background job. <br>
* (e.g missing flags when launching a profiling tools, ask the user if he wants the flag to be added). <br>
* This class aims to implement wrappers for the standard openTYPE message dialogues so that <br>
* they could be launched from any background thread.
* </p>
*
* <p> Note, methods in this subclass have a postfix of 'SyncedRunnable'.
* @since 3.1
*/
public class MessageDialogSyncedRunnable extends MessageDialog {
/**
* Calls parent, identical to parent implementation in all respects. <br>
* <p> Neccessary to supress compiler warnings. Use static methods in this class instead </p>
* <p> For details and paramater description, please see: <br> </p>
* {@link org.eclipse.jface.dialogs.MessageDialog#MessageDialog(Shell, String, Image, String, int, String[], int) }
*
*
* @param parentShell
* the parent shell
* @param dialogTitle
* the dialog title, or <code>null</code> if none
* @param dialogTitleImage
* the dialog title image, or <code>null</code> if none
* @param dialogMessage
* the dialog message
* @param dialogImageType
* one of the following values:
* <ul>
* <li><code>MessageDialog.NONE</code> for a dialog with no
* image</li>
* <li><code>MessageDialog.ERROR</code> for a dialog with an
* error image</li>
* <li><code>MessageDialog.INFORMATION</code> for a dialog
* with an information image</li>
* <li><code>MessageDialog.QUESTION </code> for a dialog with a
* question image</li>
* <li><code>MessageDialog.WARNING</code> for a dialog with a
* warning image</li>
* </ul>
* @param dialogButtonLabels
* an array of labels for the buttons in the button bar
* @param defaultIndex
* the index in the button label array of the default button
*/
protected MessageDialogSyncedRunnable(Shell parentShell, String dialogTitle,
Image dialogTitleImage, String dialogMessage, int dialogImageType,
String[] dialogButtonLabels, int defaultIndex) {
super(parentShell, dialogTitle, dialogTitleImage, dialogMessage, dialogImageType,
dialogButtonLabels, defaultIndex);
}
/**
* <h1>Open Question Dialogue.</h1>
* <p>
* Identical to parent implementation {@link MessageDialog#openQuestion(Shell, String, String) openQuestion} <br>
* except that you do not need to provide a shell.
* </p>
* <p>
* Convenience method to open a simple Yes/No question dialog.
* </p>
*
* @param title the dialog's title, or <code>null</code> if none
* @param message the message
* @return <code>true </code> if the user presses the Yes button,
* <code>false</code> otherwise
*/
public static boolean openQuestionSyncedRunnable(final String title, final String message) {
return openInSyncedRunnable(DialogueType.QUESTION, title, message);
}
/**
* <h1>Open Confirmation Dialogue. </h1>
* <p>
* Identical to parent implementation {@link MessageDialog#openConfirm(Shell, String, String) openConfirm}<br>
* except that you do not need to provide a shell.
* </p>
*
* <p> Convenience method to open a simple confirm (OK/Cancel) dialog. </p>
*
* @param title the dialog's title, or <code>null</code> if none
* @param message the message
* @return <code>true</code> if the user presses the OK button,
* <code>false</code> otherwise
*/
public static boolean openConfirmSyncedRunnable(final String title, final String message) {
return openInSyncedRunnable(DialogueType.CONFIRMATION, title, message);
}
/**
* <h1>Open Information Dialogue.</h1>
* <p>
* Identical to parent implementation {@link MessageDialog#openInformation(Shell, String, String) openInformation} <br>
* except that you do not need to provide a shell.
* </p>
* <p>
* Convenience method to open a simple confirm (OK/Cancel) dialog.
* </p>
*
* @param title the dialog's title, or <code>null</code> if none
* @param message the message
*/
public static void openInformationSyncedRunnable(final String title, final String message) {
//We discard boolean and don't return anything.
openInSyncedRunnable(DialogueType.INFO, title, message);
}
/**
* <h1>Open Error Dialogue.</h1>
* <p>
* Identical to parent implementation {@link MessageDialog#openError(Shell, String, String) openError}<br>
* except that you do not need to provide a shell:
* </p>
*<p>
*Convenience method to open a standard error dialog.
*</p>
*
* @param title the dialog's title, or <code>null</code> if none
* @param message the message
*/
public static void openErrorSyncedRunnable(final String title, final String message) {
//We discard boolean and don't return anything.
openInSyncedRunnable(DialogueType.ERROR, title, message);
}
private static enum DialogueType {INFO, ERROR, CONFIRMATION, QUESTION}
/* To prevent code duplication... */
private static boolean openInSyncedRunnable(final DialogueType type, final String title, final String message) {
//We define a 'final' variable that will be accessible in the runnable object.
final BooleanWithGetSet userChoiceBool = new BooleanWithGetSet(false);
//To generate U.I, we make a syncronised call the U.I thread,
//otherwise we get an U.I exception.
PlatformUI.getWorkbench().getDisplay().syncExec(() -> {
Shell parent = PlatformUI.getWorkbench().getDisplay().getActiveShell();
switch (type) {
case INFO:
MessageDialog.openInformation(parent, title, message);
break;
case ERROR:
MessageDialog.openError(parent, title, message);
break;
case CONFIRMATION:
boolean okPressed = MessageDialog.openConfirm(parent, title, message);
userChoiceBool.setVal(okPressed);
break;
case QUESTION:
boolean okPressedQ = MessageDialog.openQuestion(parent, title, message);
userChoiceBool.setVal(okPressedQ);
break;
default:
break;
}
return;
});
return userChoiceBool.getVal();
}
}