/com.atlassian.connector.eclipse.crucible.ui/src/com/atlassian/connector/eclipse/ui/dialogs/ProgressDialog.java
Java | 283 lines | 177 code | 32 blank | 74 comment | 23 complexity | 7df5806b55b7edc1723bbdc738673c1c MD5 | raw file
- /*******************************************************************************
- * Copyright (c) 2009 Atlassian and others.
- * 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:
- * Atlassian - initial API and implementation
- ******************************************************************************/
-
- package com.atlassian.connector.eclipse.ui.dialogs;
-
- import org.eclipse.core.runtime.IProgressMonitor;
- import org.eclipse.core.runtime.IStatus;
- import org.eclipse.jface.dialogs.TitleAreaDialog;
- import org.eclipse.jface.operation.IRunnableWithProgress;
- import org.eclipse.jface.operation.ModalContext;
- import org.eclipse.jface.resource.JFaceResources;
- import org.eclipse.jface.wizard.ProgressMonitorPart;
- import org.eclipse.swt.SWT;
- import org.eclipse.swt.events.SelectionAdapter;
- import org.eclipse.swt.events.SelectionEvent;
- import org.eclipse.swt.graphics.Cursor;
- import org.eclipse.swt.layout.GridData;
- import org.eclipse.swt.layout.GridLayout;
- import org.eclipse.swt.widgets.Button;
- import org.eclipse.swt.widgets.Composite;
- import org.eclipse.swt.widgets.Control;
- import org.eclipse.swt.widgets.Display;
- import org.eclipse.swt.widgets.Label;
- import org.eclipse.swt.widgets.Shell;
-
- import java.lang.reflect.InvocationTargetException;
- import java.util.Collection;
- import java.util.HashMap;
-
- /**
- * Dialog that can display progress
- *
- * @author Shawn Minto
- */
- public abstract class ProgressDialog extends TitleAreaDialog {
-
- private boolean lockedUI = false;
-
- private Composite pageContainer;
-
- private Cursor waitCursor;
-
- private ProgressMonitorPart progressMonitorPart;
-
- private long activeRunningOperations = 0;
-
- private final HashMap<Integer, Button> buttons = new HashMap<Integer, Button>();
-
- public ProgressDialog(Shell parentShell) {
- super(parentShell);
- setDialogHelpAvailable(false);
- setHelpAvailable(false);
- }
-
- /*
- * (non-Javadoc) Method declared on Dialog.
- */
- @Override
- protected Control createDialogArea(Composite parent) {
- Composite composite = (Composite) super.createDialogArea(parent);
- // Build the Page container
- pageContainer = new Composite(composite, SWT.NONE);
- pageContainer.setLayout(new GridLayout());
- GridData gd = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL);
- pageContainer.setLayoutData(gd);
- pageContainer.setFont(parent.getFont());
- createPageControls(pageContainer);
-
- // Insert a progress monitor
- GridLayout pmlayout = new GridLayout();
- pmlayout.numColumns = 1;
- progressMonitorPart = createProgressMonitorPart(composite, pmlayout);
- GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
- progressMonitorPart.setLayoutData(gridData);
- progressMonitorPart.setVisible(true);
- // Build the separator line
- Label separator = new Label(parent, SWT.HORIZONTAL | SWT.SEPARATOR);
- separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
- applyDialogFont(progressMonitorPart);
- return composite;
- }
-
- protected abstract Control createPageControls(Composite parent);
-
- protected Collection<? extends Control> getDisableableControls() {
- return buttons.values();
- }
-
- /**
- * About to start a long running operation triggered through the wizard. Shows the progress monitor and disables the
- * wizard's buttons and controls.
- *
- * @param enableCancelButton
- * <code>true</code> if the Cancel button should be enabled, and <code>false</code> if it should be
- * disabled
- * @return the saved UI state
- */
- private void aboutToStart(boolean enableCancelButton) {
- if (getShell() != null) {
- // Save focus control
- Control focusControl = getShell().getDisplay().getFocusControl();
- if (focusControl != null && focusControl.getShell() != getShell()) {
- focusControl = null;
- }
- // Set the busy cursor to all shells.
- Display d = getShell().getDisplay();
- waitCursor = new Cursor(d, SWT.CURSOR_WAIT);
- setDisplayCursor(waitCursor);
-
- for (Control button : getDisableableControls()) {
- button.setEnabled(false);
- }
-
- progressMonitorPart.setVisible(true);
- }
- }
-
- /**
- * A long running operation triggered through the wizard was stopped either by user input or by normal end. Hides
- * the progress monitor and restores the enable state wizard's buttons and controls.
- *
- * @param savedState
- * the saved UI state as returned by <code>aboutToStart</code>
- * @see #aboutToStart
- */
- private void stopped(Object savedState) {
- if (getShell() != null) {
- progressMonitorPart.setVisible(false);
- setDisplayCursor(null);
- waitCursor.dispose();
- waitCursor = null;
-
- for (Control button : getDisableableControls()) {
- button.setEnabled(true);
- }
- }
- }
-
- @Override
- protected void createButtonsForButtonBar(Composite parent) {
- }
-
- /**
- * Create the progress monitor part in the receiver.
- *
- * @param composite
- * @param pmlayout
- * @return ProgressMonitorPart
- */
- protected ProgressMonitorPart createProgressMonitorPart(Composite composite, GridLayout pmlayout) {
- return new ProgressMonitorPart(composite, pmlayout, SWT.DEFAULT) {
- private String currentTask = null;
-
- @Override
- public void setBlocked(IStatus reason) {
- super.setBlocked(reason);
- if (!lockedUI) {
- getBlockedHandler().showBlocked(getShell(), this, reason, currentTask);
- }
- }
-
- @Override
- public void clearBlocked() {
- super.clearBlocked();
- if (!lockedUI) {
- getBlockedHandler().clearBlocked();
- }
- }
-
- @Override
- public void beginTask(String name, int totalWork) {
- super.beginTask(name, totalWork);
- currentTask = name;
- }
-
- @Override
- public void setTaskName(String name) {
- super.setTaskName(name);
- currentTask = name;
- }
-
- @Override
- public void subTask(String name) {
- super.subTask(name);
- if (currentTask == null) {
- currentTask = name;
- }
- }
- };
- }
-
- /**
- * This implementation of IRunnableContext#run(boolean, boolean, IRunnableWithProgress) blocks until the runnable
- * has been run, regardless of the value of <code>fork</code>. It is recommended that <code>fork</code> is set to
- * true in most cases. If <code>fork</code> is set to <code>false</code>, the runnable will run in the UI thread and
- * it is the runnable's responsibility to call <code>Display.readAndDispatch()</code> to ensure UI responsiveness.
- *
- * UI state is saved prior to executing the long-running operation and is restored after the long-running operation
- * completes executing. Any attempt to change the UI state of the wizard in the long-running operation will be
- * nullified when original UI state is restored.
- *
- */
- public void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable) throws InvocationTargetException,
- InterruptedException {
- // The operation can only be canceled if it is executed in a separate
- // thread.
- // Otherwise the UI is blocked anyway.
- Object state = null;
- if (activeRunningOperations == 0) {
- aboutToStart(fork && cancelable);
- }
- activeRunningOperations++;
- try {
- if (!fork) {
- lockedUI = true;
- }
- ModalContext.run(runnable, fork, getProgressMonitor(), getShell().getDisplay());
- lockedUI = false;
- } finally {
- activeRunningOperations--;
- // Stop if this is the last one
- if (activeRunningOperations <= 0) {
- stopped(state);
- }
- }
- }
-
- /**
- * Returns the progress monitor for this wizard dialog (if it has one).
- *
- * @return the progress monitor, or <code>null</code> if this wizard dialog does not have one
- */
- protected IProgressMonitor getProgressMonitor() {
- return progressMonitorPart;
- }
-
- /**
- * Sets the given cursor for all shells currently active for this window's display.
- *
- * @param c
- * the cursor
- */
- private void setDisplayCursor(Cursor c) {
- Shell[] shells = getShell().getDisplay().getShells();
- for (Shell element : shells) {
- element.setCursor(c);
- }
- }
-
- @Override
- protected Button createButton(Composite parent, int id, String label, boolean defaultButton) {
- // increment the number of columns in the button bar
- ((GridLayout) parent.getLayout()).numColumns++;
- Button button = new Button(parent, SWT.PUSH);
- button.setText(label);
- button.setFont(JFaceResources.getDialogFont());
- button.setData(new Integer(id));
- button.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent event) {
- buttonPressed(((Integer) event.widget.getData()).intValue());
- }
- });
- if (defaultButton) {
- Shell shell = parent.getShell();
- if (shell != null) {
- shell.setDefaultButton(button);
- }
- }
- buttons.put(new Integer(id), button);
- setButtonLayoutData(button);
- return button;
- }
- }