KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > progress > BlockedJobsDialog


1 /*******************************************************************************
2  * Copyright (c) 2004, 2007 IBM Corporation 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  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.ui.internal.progress;
12
13 import org.eclipse.core.runtime.IProgressMonitor;
14 import org.eclipse.core.runtime.IStatus;
15 import org.eclipse.core.runtime.Status;
16 import org.eclipse.jface.dialogs.IconAndMessageDialog;
17 import org.eclipse.jface.resource.JFaceResources;
18 import org.eclipse.jface.viewers.Viewer;
19 import org.eclipse.jface.viewers.ViewerComparator;
20 import org.eclipse.swt.SWT;
21 import org.eclipse.swt.graphics.Cursor;
22 import org.eclipse.swt.graphics.Image;
23 import org.eclipse.swt.layout.GridData;
24 import org.eclipse.swt.widgets.Button;
25 import org.eclipse.swt.widgets.Composite;
26 import org.eclipse.swt.widgets.Control;
27 import org.eclipse.swt.widgets.Shell;
28 import org.eclipse.ui.PlatformUI;
29 import org.eclipse.ui.internal.WorkbenchMessages;
30 import org.eclipse.ui.progress.WorkbenchJob;
31
32 /**
33  * The BlockedJobsDialog class displays a dialog that provides information on
34  * the running jobs.
35  */

36 public class BlockedJobsDialog extends IconAndMessageDialog {
37     /**
38      * The singleton dialog instance. A singleton avoids the possibility of
39      * recursive dialogs being created. The singleton is created when a dialog
40      * is requested, and cleared when the dialog is disposed.
41      */

42     protected static BlockedJobsDialog singleton;
43
44     /**
45      * The running jobs progress viewer.
46      */

47     private DetailedProgressViewer viewer;
48
49     /**
50      * The name of the task that is being blocked.
51      */

52     private String JavaDoc blockedTaskName = null;
53
54     /**
55      * The Cancel button control.
56      */

57     private Button cancelSelected;
58
59     /**
60      * The cursor for the buttons.
61      */

62     private Cursor arrowCursor;
63
64     /**
65      * The cursor for the Shell.
66      */

67     private Cursor waitCursor;
68
69     private IProgressMonitor blockingMonitor;
70
71     private JobTreeElement blockedElement = new BlockedUIElement();
72
73     /**
74      * The BlockedUIElement is the JobTreeElement that represents the blocked
75      * job in the dialog.
76      */

77     private class BlockedUIElement extends JobTreeElement {
78
79         /*
80          * (non-Javadoc)
81          *
82          * @see org.eclipse.ui.internal.progress.JobTreeElement#getChildren()
83          */

84         Object JavaDoc[] getChildren() {
85             return ProgressManagerUtil.EMPTY_OBJECT_ARRAY;
86         }
87
88         /*
89          * (non-Javadoc)
90          *
91          * @see org.eclipse.ui.internal.progress.JobTreeElement#getDisplayString()
92          */

93         String JavaDoc getDisplayString() {
94             if (blockedTaskName == null || blockedTaskName.length() == 0) {
95                 return ProgressMessages.BlockedJobsDialog_UserInterfaceTreeElement;
96             }
97             return blockedTaskName;
98         }
99
100         /*
101          * (non-Javadoc)
102          *
103          * @see org.eclipse.ui.internal.progress.JobTreeElement#getDisplayImage()
104          */

105         public Image getDisplayImage() {
106             return JFaceResources.getImage(ProgressManager.WAITING_JOB_KEY);
107         }
108
109         /*
110          * (non-Javadoc)
111          *
112          * @see org.eclipse.ui.internal.progress.JobTreeElement#getParent()
113          */

114         Object JavaDoc getParent() {
115             return null;
116         }
117
118         /*
119          * (non-Javadoc)
120          *
121          * @see org.eclipse.ui.internal.progress.JobTreeElement#hasChildren()
122          */

123         boolean hasChildren() {
124             return false;
125         }
126
127         /*
128          * (non-Javadoc)
129          *
130          * @see org.eclipse.ui.internal.progress.JobTreeElement#isActive()
131          */

132         boolean isActive() {
133             return true;
134         }
135
136         /*
137          * (non-Javadoc)
138          *
139          * @see org.eclipse.ui.internal.progress.JobTreeElement#isJobInfo()
140          */

141         boolean isJobInfo() {
142             return false;
143         }
144
145         /*
146          * (non-Javadoc)
147          *
148          * @see org.eclipse.ui.internal.progress.JobTreeElement#cancel()
149          */

150         public void cancel() {
151             blockingMonitor.setCanceled(true);
152         }
153
154         /*
155          * (non-Javadoc)
156          *
157          * @see org.eclipse.ui.internal.progress.JobTreeElement#isCancellable()
158          */

159         public boolean isCancellable() {
160             return true;
161         }
162     }
163
164     /**
165      * Creates a progress monitor dialog under the given shell. It also sets the
166      * dialog's message. The dialog is opened automatically after a reasonable
167      * delay. When no longer needed, the dialog must be closed by calling
168      * <code>close(IProgressMonitor)</code>, where the supplied monitor is
169      * the same monitor passed to this factory method.
170      *
171      * @param parentShell
172      * The parent shell, or <code>null</code> to create a top-level
173      * shell. If the parentShell is not null we will open immediately
174      * as parenting has been determined. If it is <code>null</code>
175      * then the dialog will not open until there is no modal shell
176      * blocking it.
177      * @param blockedMonitor
178      * The monitor that is currently blocked
179      * @param reason
180      * A status describing why the monitor is blocked
181      * @param taskName
182      * A name to give the blocking task in the dialog
183      * @return BlockedJobsDialog
184      */

185     public static BlockedJobsDialog createBlockedDialog(Shell parentShell,
186             IProgressMonitor blockedMonitor, IStatus reason, String JavaDoc taskName) {
187         // use an existing dialog if available
188
if (singleton != null) {
189             return singleton;
190         }
191         singleton = new BlockedJobsDialog(parentShell, blockedMonitor, reason);
192
193         if (taskName == null || taskName.length() == 0)
194             singleton
195                     .setBlockedTaskName(ProgressMessages.BlockedJobsDialog_UserInterfaceTreeElement);
196         else
197             singleton.setBlockedTaskName(taskName);
198
199         /**
200          * If there is no parent shell we have not been asked for a parent so we
201          * want to avoid blocking. If there is a parent then it is OK to open.
202          */

203         if (parentShell == null) {
204             // create the job that will open the dialog after a delay.
205
WorkbenchJob dialogJob = new WorkbenchJob(
206                     WorkbenchMessages.EventLoopProgressMonitor_OpenDialogJobName) {
207                 /*
208                  * (non-Javadoc)
209                  *
210                  * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
211                  */

212                 public IStatus runInUIThread(IProgressMonitor monitor) {
213                     if (singleton == null) {
214                         return Status.CANCEL_STATUS;
215                     }
216                     if (ProgressManagerUtil.rescheduleIfModalShellOpen(this)) {
217                         return Status.CANCEL_STATUS;
218                     }
219                     singleton.open();
220                     return Status.OK_STATUS;
221                 }
222             };
223             // Wait for long operation time to prevent a proliferation
224
// of dialogs
225
dialogJob.setSystem(true);
226             dialogJob.schedule(PlatformUI.getWorkbench().getProgressService()
227                     .getLongOperationTime());
228         } else {
229             singleton.open();
230         }
231
232         return singleton;
233     }
234
235     /**
236      * monitor is done. Clear the receiver.
237      *
238      * @param monitor
239      * The monitor that is now cleared.
240      */

241     public static void clear(IProgressMonitor monitor) {
242         if (singleton == null) {
243             return;
244         }
245         singleton.close(monitor);
246
247     }
248
249     /**
250      * Creates a progress monitor dialog under the given shell. It also sets the
251      * dialog's\ message. <code>open</code> is non-blocking.
252      *
253      * @param parentShell
254      * The parent shell, or <code>null</code> to create a top-level
255      * shell.
256      * @param blocking
257      * The monitor that is blocking the job
258      * @param blockingStatus
259      * A status describing why the monitor is blocked
260      */

261     private BlockedJobsDialog(Shell parentShell, IProgressMonitor blocking,
262             IStatus blockingStatus) {
263         super(parentShell == null ? ProgressManagerUtil.getDefaultParent()
264                 : parentShell);
265         blockingMonitor = blocking;
266         setShellStyle(SWT.BORDER | SWT.TITLE | SWT.APPLICATION_MODAL
267                 | SWT.RESIZE | getDefaultOrientation());
268         // no close button
269
setBlockOnOpen(false);
270         setMessage(blockingStatus.getMessage());
271     }
272
273     /**
274      * This method creates the dialog area under the parent composite.
275      *
276      * @param parent
277      * The parent Composite.
278      *
279      * @return parent The parent Composite.
280      */

281     protected Control createDialogArea(Composite parent) {
282         setMessage(message);
283         createMessageArea(parent);
284         showJobDetails(parent);
285         return parent;
286     }
287
288     /**
289      * This method creates a dialog area in the parent composite and displays a
290      * progress tree viewer of the running jobs.
291      *
292      * @param parent
293      * The parent Composite.
294      */

295     void showJobDetails(Composite parent) {
296         viewer = new DetailedProgressViewer(parent, SWT.MULTI | SWT.H_SCROLL
297                 | SWT.V_SCROLL | SWT.BORDER);
298         viewer.setComparator(new ViewerComparator() {
299             /*
300              * (non-Javadoc)
301              *
302              * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer,
303              * java.lang.Object, java.lang.Object)
304              */

305             public int compare(Viewer testViewer, Object JavaDoc e1, Object JavaDoc e2) {
306                 return ((Comparable JavaDoc) e1).compareTo(e2);
307             }
308         });
309         ProgressViewerContentProvider provider = getContentProvider();
310         viewer.setContentProvider(provider);
311         viewer.setInput(provider);
312         viewer.setLabelProvider(new ProgressLabelProvider());
313         GridData data = new GridData(GridData.GRAB_HORIZONTAL
314                 | GridData.GRAB_VERTICAL | GridData.FILL_BOTH);
315         data.horizontalSpan = 2;
316         int heightHint = convertHeightInCharsToPixels(10);
317         data.heightHint = heightHint;
318         viewer.getControl().setLayoutData(data);
319     }
320
321     /**
322      * Return the content provider used for the receiver.
323      *
324      * @return ProgressTreeContentProvider
325      */

326     private ProgressViewerContentProvider getContentProvider() {
327         return new ProgressViewerContentProvider(viewer, true, false) {
328
329             /*
330              * (non-Javadoc)
331              *
332              * @see org.eclipse.ui.internal.progress.ProgressViewerContentProvider#getElements(java.lang.Object)
333              */

334             public Object JavaDoc[] getElements(Object JavaDoc inputElement) {
335                 Object JavaDoc[] elements = super.getElements(inputElement);
336                 Object JavaDoc[] result = new Object JavaDoc[elements.length + 1];
337                 System.arraycopy(elements, 0, result, 1, elements.length);
338                 result[0] = blockedElement;
339                 return result;
340             }
341         };
342     }
343
344     /**
345      * Clear the cursors in the dialog.
346      */

347     private void clearCursors() {
348         clearCursor(cancelSelected);
349         clearCursor(getShell());
350         if (arrowCursor != null) {
351             arrowCursor.dispose();
352         }
353         if (waitCursor != null) {
354             waitCursor.dispose();
355         }
356         arrowCursor = null;
357         waitCursor = null;
358     }
359
360     /**
361      * Clear the cursor on the supplied control.
362      *
363      * @param control
364      */

365     private void clearCursor(Control control) {
366         if (control != null && !control.isDisposed()) {
367             control.setCursor(null);
368         }
369     }
370
371     /*
372      * (non-Javadoc)
373      *
374      * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
375      */

376     protected void configureShell(Shell shell) {
377         super.configureShell(shell);
378         shell.setText(ProgressMessages.BlockedJobsDialog_BlockedTitle);
379         if (waitCursor == null) {
380             waitCursor = new Cursor(shell.getDisplay(), SWT.CURSOR_WAIT);
381         }
382         shell.setCursor(waitCursor);
383     }
384
385     /**
386      * This method sets the message in the message label.
387      *
388      * @param messageString -
389      * the String for the message area
390      */

391     private void setMessage(String JavaDoc messageString) {
392         // must not set null text in a label
393
message = messageString == null ? "" : messageString; //$NON-NLS-1$
394
if (messageLabel == null || messageLabel.isDisposed()) {
395             return;
396         }
397         messageLabel.setText(message);
398     }
399
400     /*
401      * (non-Javadoc)
402      *
403      * @see org.eclipse.jface.dialogs.IconAndMessageDialog#getImage()
404      */

405     protected Image getImage() {
406         return getInfoImage();
407     }
408
409     /**
410      * Returns the progress monitor being used for this dialog. This allows
411      * recursive blockages to also respond to cancelation.
412      *
413      * @return IProgressMonitor
414      */

415     public IProgressMonitor getProgressMonitor() {
416         return blockingMonitor;
417     }
418
419     /**
420      * Requests that the blocked jobs dialog be closed. The supplied monitor
421      * must be the same one that was passed to the createBlockedDialog method.
422      *
423      * @param monitor
424      * @return IProgressMonitor
425      */

426     public boolean close(IProgressMonitor monitor) {
427         // ignore requests to close the dialog from all but the first monitor
428
if (blockingMonitor != monitor) {
429             return false;
430         }
431         return close();
432     }
433
434     /*
435      * (non-Javadoc)
436      *
437      * @see org.eclipse.jface.dialogs.Dialog#close()
438      */

439     public boolean close() {
440         // Clear the singleton first
441
singleton = null;
442         clearCursors();
443         return super.close();
444     }
445
446     /*
447      * (non-Javadoc)
448      *
449      * @see org.eclipse.jface.dialogs.IconAndMessageDialog#createButtonBar(org.eclipse.swt.widgets.Composite)
450      */

451     protected Control createButtonBar(Composite parent) {
452         // Do nothing here as we want no buttons
453
return parent;
454     }
455
456     /**
457      * @param taskName
458      * The blockedTaskName to set.
459      */

460     void setBlockedTaskName(String JavaDoc taskName) {
461         this.blockedTaskName = taskName;
462     }
463
464 }
465
Popular Tags