PageRenderTime 22ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/com.atlassian.connector.eclipse.crucible.ui/src/com/atlassian/connector/eclipse/ui/dialogs/ProgressDialog.java

https://github.com/spingel/mylyn-reviews
Java | 283 lines | 177 code | 32 blank | 74 comment | 23 complexity | 7df5806b55b7edc1723bbdc738673c1c MD5 | raw file
  1. /*******************************************************************************
  2. * Copyright (c) 2009 Atlassian and others.
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * http://www.eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors:
  9. * Atlassian - initial API and implementation
  10. ******************************************************************************/
  11. package com.atlassian.connector.eclipse.ui.dialogs;
  12. import org.eclipse.core.runtime.IProgressMonitor;
  13. import org.eclipse.core.runtime.IStatus;
  14. import org.eclipse.jface.dialogs.TitleAreaDialog;
  15. import org.eclipse.jface.operation.IRunnableWithProgress;
  16. import org.eclipse.jface.operation.ModalContext;
  17. import org.eclipse.jface.resource.JFaceResources;
  18. import org.eclipse.jface.wizard.ProgressMonitorPart;
  19. import org.eclipse.swt.SWT;
  20. import org.eclipse.swt.events.SelectionAdapter;
  21. import org.eclipse.swt.events.SelectionEvent;
  22. import org.eclipse.swt.graphics.Cursor;
  23. import org.eclipse.swt.layout.GridData;
  24. import org.eclipse.swt.layout.GridLayout;
  25. import org.eclipse.swt.widgets.Button;
  26. import org.eclipse.swt.widgets.Composite;
  27. import org.eclipse.swt.widgets.Control;
  28. import org.eclipse.swt.widgets.Display;
  29. import org.eclipse.swt.widgets.Label;
  30. import org.eclipse.swt.widgets.Shell;
  31. import java.lang.reflect.InvocationTargetException;
  32. import java.util.Collection;
  33. import java.util.HashMap;
  34. /**
  35. * Dialog that can display progress
  36. *
  37. * @author Shawn Minto
  38. */
  39. public abstract class ProgressDialog extends TitleAreaDialog {
  40. private boolean lockedUI = false;
  41. private Composite pageContainer;
  42. private Cursor waitCursor;
  43. private ProgressMonitorPart progressMonitorPart;
  44. private long activeRunningOperations = 0;
  45. private final HashMap<Integer, Button> buttons = new HashMap<Integer, Button>();
  46. public ProgressDialog(Shell parentShell) {
  47. super(parentShell);
  48. setDialogHelpAvailable(false);
  49. setHelpAvailable(false);
  50. }
  51. /*
  52. * (non-Javadoc) Method declared on Dialog.
  53. */
  54. @Override
  55. protected Control createDialogArea(Composite parent) {
  56. Composite composite = (Composite) super.createDialogArea(parent);
  57. // Build the Page container
  58. pageContainer = new Composite(composite, SWT.NONE);
  59. pageContainer.setLayout(new GridLayout());
  60. GridData gd = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL);
  61. pageContainer.setLayoutData(gd);
  62. pageContainer.setFont(parent.getFont());
  63. createPageControls(pageContainer);
  64. // Insert a progress monitor
  65. GridLayout pmlayout = new GridLayout();
  66. pmlayout.numColumns = 1;
  67. progressMonitorPart = createProgressMonitorPart(composite, pmlayout);
  68. GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
  69. progressMonitorPart.setLayoutData(gridData);
  70. progressMonitorPart.setVisible(true);
  71. // Build the separator line
  72. Label separator = new Label(parent, SWT.HORIZONTAL | SWT.SEPARATOR);
  73. separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
  74. applyDialogFont(progressMonitorPart);
  75. return composite;
  76. }
  77. protected abstract Control createPageControls(Composite parent);
  78. protected Collection<? extends Control> getDisableableControls() {
  79. return buttons.values();
  80. }
  81. /**
  82. * About to start a long running operation triggered through the wizard. Shows the progress monitor and disables the
  83. * wizard's buttons and controls.
  84. *
  85. * @param enableCancelButton
  86. * <code>true</code> if the Cancel button should be enabled, and <code>false</code> if it should be
  87. * disabled
  88. * @return the saved UI state
  89. */
  90. private void aboutToStart(boolean enableCancelButton) {
  91. if (getShell() != null) {
  92. // Save focus control
  93. Control focusControl = getShell().getDisplay().getFocusControl();
  94. if (focusControl != null && focusControl.getShell() != getShell()) {
  95. focusControl = null;
  96. }
  97. // Set the busy cursor to all shells.
  98. Display d = getShell().getDisplay();
  99. waitCursor = new Cursor(d, SWT.CURSOR_WAIT);
  100. setDisplayCursor(waitCursor);
  101. for (Control button : getDisableableControls()) {
  102. button.setEnabled(false);
  103. }
  104. progressMonitorPart.setVisible(true);
  105. }
  106. }
  107. /**
  108. * A long running operation triggered through the wizard was stopped either by user input or by normal end. Hides
  109. * the progress monitor and restores the enable state wizard's buttons and controls.
  110. *
  111. * @param savedState
  112. * the saved UI state as returned by <code>aboutToStart</code>
  113. * @see #aboutToStart
  114. */
  115. private void stopped(Object savedState) {
  116. if (getShell() != null) {
  117. progressMonitorPart.setVisible(false);
  118. setDisplayCursor(null);
  119. waitCursor.dispose();
  120. waitCursor = null;
  121. for (Control button : getDisableableControls()) {
  122. button.setEnabled(true);
  123. }
  124. }
  125. }
  126. @Override
  127. protected void createButtonsForButtonBar(Composite parent) {
  128. }
  129. /**
  130. * Create the progress monitor part in the receiver.
  131. *
  132. * @param composite
  133. * @param pmlayout
  134. * @return ProgressMonitorPart
  135. */
  136. protected ProgressMonitorPart createProgressMonitorPart(Composite composite, GridLayout pmlayout) {
  137. return new ProgressMonitorPart(composite, pmlayout, SWT.DEFAULT) {
  138. private String currentTask = null;
  139. @Override
  140. public void setBlocked(IStatus reason) {
  141. super.setBlocked(reason);
  142. if (!lockedUI) {
  143. getBlockedHandler().showBlocked(getShell(), this, reason, currentTask);
  144. }
  145. }
  146. @Override
  147. public void clearBlocked() {
  148. super.clearBlocked();
  149. if (!lockedUI) {
  150. getBlockedHandler().clearBlocked();
  151. }
  152. }
  153. @Override
  154. public void beginTask(String name, int totalWork) {
  155. super.beginTask(name, totalWork);
  156. currentTask = name;
  157. }
  158. @Override
  159. public void setTaskName(String name) {
  160. super.setTaskName(name);
  161. currentTask = name;
  162. }
  163. @Override
  164. public void subTask(String name) {
  165. super.subTask(name);
  166. if (currentTask == null) {
  167. currentTask = name;
  168. }
  169. }
  170. };
  171. }
  172. /**
  173. * This implementation of IRunnableContext#run(boolean, boolean, IRunnableWithProgress) blocks until the runnable
  174. * has been run, regardless of the value of <code>fork</code>. It is recommended that <code>fork</code> is set to
  175. * true in most cases. If <code>fork</code> is set to <code>false</code>, the runnable will run in the UI thread and
  176. * it is the runnable's responsibility to call <code>Display.readAndDispatch()</code> to ensure UI responsiveness.
  177. *
  178. * UI state is saved prior to executing the long-running operation and is restored after the long-running operation
  179. * completes executing. Any attempt to change the UI state of the wizard in the long-running operation will be
  180. * nullified when original UI state is restored.
  181. *
  182. */
  183. public void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable) throws InvocationTargetException,
  184. InterruptedException {
  185. // The operation can only be canceled if it is executed in a separate
  186. // thread.
  187. // Otherwise the UI is blocked anyway.
  188. Object state = null;
  189. if (activeRunningOperations == 0) {
  190. aboutToStart(fork && cancelable);
  191. }
  192. activeRunningOperations++;
  193. try {
  194. if (!fork) {
  195. lockedUI = true;
  196. }
  197. ModalContext.run(runnable, fork, getProgressMonitor(), getShell().getDisplay());
  198. lockedUI = false;
  199. } finally {
  200. activeRunningOperations--;
  201. // Stop if this is the last one
  202. if (activeRunningOperations <= 0) {
  203. stopped(state);
  204. }
  205. }
  206. }
  207. /**
  208. * Returns the progress monitor for this wizard dialog (if it has one).
  209. *
  210. * @return the progress monitor, or <code>null</code> if this wizard dialog does not have one
  211. */
  212. protected IProgressMonitor getProgressMonitor() {
  213. return progressMonitorPart;
  214. }
  215. /**
  216. * Sets the given cursor for all shells currently active for this window's display.
  217. *
  218. * @param c
  219. * the cursor
  220. */
  221. private void setDisplayCursor(Cursor c) {
  222. Shell[] shells = getShell().getDisplay().getShells();
  223. for (Shell element : shells) {
  224. element.setCursor(c);
  225. }
  226. }
  227. @Override
  228. protected Button createButton(Composite parent, int id, String label, boolean defaultButton) {
  229. // increment the number of columns in the button bar
  230. ((GridLayout) parent.getLayout()).numColumns++;
  231. Button button = new Button(parent, SWT.PUSH);
  232. button.setText(label);
  233. button.setFont(JFaceResources.getDialogFont());
  234. button.setData(new Integer(id));
  235. button.addSelectionListener(new SelectionAdapter() {
  236. @Override
  237. public void widgetSelected(SelectionEvent event) {
  238. buttonPressed(((Integer) event.widget.getData()).intValue());
  239. }
  240. });
  241. if (defaultButton) {
  242. Shell shell = parent.getShell();
  243. if (shell != null) {
  244. shell.setDefaultButton(button);
  245. }
  246. }
  247. buttons.put(new Integer(id), button);
  248. setButtonLayoutData(button);
  249. return button;
  250. }
  251. }