KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2003, 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 java.net.MalformedURLException JavaDoc;
14 import java.net.URL JavaDoc;
15
16 import org.eclipse.core.runtime.IStatus;
17 import org.eclipse.core.runtime.QualifiedName;
18 import org.eclipse.core.runtime.jobs.Job;
19 import org.eclipse.jface.viewers.Viewer;
20 import org.eclipse.jface.viewers.ViewerComparator;
21 import org.eclipse.jface.window.IShellProvider;
22 import org.eclipse.swt.SWT;
23 import org.eclipse.swt.graphics.GC;
24 import org.eclipse.swt.graphics.Point;
25 import org.eclipse.swt.graphics.Rectangle;
26 import org.eclipse.swt.widgets.Control;
27 import org.eclipse.swt.widgets.Shell;
28 import org.eclipse.ui.IWorkbench;
29 import org.eclipse.ui.IWorkbenchPage;
30 import org.eclipse.ui.IWorkbenchWindow;
31 import org.eclipse.ui.PartInitException;
32 import org.eclipse.ui.PlatformUI;
33 import org.eclipse.ui.internal.RectangleAnimation;
34 import org.eclipse.ui.internal.WorkbenchPlugin;
35 import org.eclipse.ui.internal.WorkbenchWindow;
36 import org.eclipse.ui.internal.misc.StatusUtil;
37 import org.eclipse.ui.internal.util.BundleUtility;
38 import org.eclipse.ui.progress.IProgressConstants;
39 import org.eclipse.ui.views.IViewDescriptor;
40
41 /**
42  * The ProgressUtil is a class that contains static utility methods used for the
43  * progress API.
44  */

45
46 public class ProgressManagerUtil {
47     /**
48      * A constant used by the progress support to determine if an operation is
49      * too short to show progress.
50      */

51     public static long SHORT_OPERATION_TIME = 250;
52
53     static final QualifiedName KEEP_PROPERTY = IProgressConstants.KEEP_PROPERTY;
54
55     static final QualifiedName KEEPONE_PROPERTY = IProgressConstants.KEEPONE_PROPERTY;
56
57     static final Object JavaDoc[] EMPTY_OBJECT_ARRAY = new Object JavaDoc[0];
58     
59     static final QualifiedName INFRASTRUCTURE_PROPERTY = new QualifiedName(WorkbenchPlugin.PI_WORKBENCH,"INFRASTRUCTURE_PROPERTY");//$NON-NLS-1$
60

61
62     private static String JavaDoc ellipsis = ProgressMessages.ProgressFloatingWindow_EllipsisValue;
63
64     /**
65      * Return a status for the exception.
66      *
67      * @param exception
68      * @return IStatus
69      */

70     static IStatus exceptionStatus(Throwable JavaDoc exception) {
71         return StatusUtil.newStatus(IStatus.ERROR,
72                 exception.getMessage() == null ? "" : exception.getMessage(), //$NON-NLS-1$
73
exception);
74     }
75
76     /**
77      * Log the exception for debugging.
78      *
79      * @param exception
80      */

81     static void logException(Throwable JavaDoc exception) {
82         BundleUtility.log(PlatformUI.PLUGIN_ID, exception);
83     }
84
85     // /**
86
// * Sets the label provider for the viewer.
87
// *
88
// * @param viewer
89
// */
90
// static void initLabelProvider(ProgressTreeViewer viewer) {
91
// viewer.setLabelProvider(new ProgressLabelProvider());
92
// }
93
/**
94      * Return a viewer comparator for looking at the jobs.
95      *
96      * @return ViewerComparator
97      */

98     static ViewerComparator getProgressViewerComparator() {
99         return new ViewerComparator() {
100             /*
101              * (non-Javadoc)
102              *
103              * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer,
104              * java.lang.Object, java.lang.Object)
105              */

106             public int compare(Viewer testViewer, Object JavaDoc e1, Object JavaDoc e2) {
107                 return ((Comparable JavaDoc) e1).compareTo(e2);
108             }
109         };
110     }
111
112     /**
113      * Open the progress view in the supplied window.
114      *
115      * @param window
116      */

117     static void openProgressView(WorkbenchWindow window) {
118         IWorkbenchPage page = window.getActivePage();
119         if (page == null) {
120             return;
121         }
122         try {
123             IViewDescriptor reference = WorkbenchPlugin.getDefault()
124                     .getViewRegistry()
125                     .find(IProgressConstants.PROGRESS_VIEW_ID);
126
127             if (reference == null) {
128                 return;
129             }
130             page.showView(IProgressConstants.PROGRESS_VIEW_ID);
131         } catch (PartInitException exception) {
132             logException(exception);
133         }
134     }
135
136     /**
137      * Shorten the given text <code>t</code> so that its length doesn't exceed
138      * the given width. The default implementation replaces characters in the
139      * center of the original string with an ellipsis ("..."). Override if you
140      * need a different strategy.
141      *
142      * @param textValue
143      * @param control
144      * @return String
145      */

146     static String JavaDoc shortenText(String JavaDoc textValue, Control control) {
147         if (textValue == null) {
148             return null;
149         }
150         GC gc = new GC(control);
151         int maxWidth = control.getBounds().width - 5;
152         if (gc.textExtent(textValue).x < maxWidth) {
153             gc.dispose();
154             return textValue;
155         }
156         int length = textValue.length();
157         int ellipsisWidth = gc.textExtent(ellipsis).x;
158         // Find the second space seperator and start from there
159
int secondWord = findSecondWhitespace(textValue, gc, maxWidth);
160         int pivot = ((length - secondWord) / 2) + secondWord;
161         int start = pivot;
162         int end = pivot + 1;
163         while (start >= secondWord && end < length) {
164             String JavaDoc s1 = textValue.substring(0, start);
165             String JavaDoc s2 = textValue.substring(end, length);
166             int l1 = gc.textExtent(s1).x;
167             int l2 = gc.textExtent(s2).x;
168             if (l1 + ellipsisWidth + l2 < maxWidth) {
169                 gc.dispose();
170                 return s1 + ellipsis + s2;
171             }
172             start--;
173             end++;
174         }
175         gc.dispose();
176         return textValue;
177     }
178
179     /**
180      * Find the second index of a whitespace. Return the first index if there
181      * isn't one or 0 if there is no space at all.
182      *
183      * @param textValue
184      * @param gc
185      * The GC to test max length
186      * @param maxWidth
187      * The maximim extent
188      * @return int
189      */

190     private static int findSecondWhitespace(String JavaDoc textValue, GC gc,
191             int maxWidth) {
192         int firstCharacter = 0;
193         char[] chars = textValue.toCharArray();
194         // Find the first whitespace
195
for (int i = 0; i < chars.length; i++) {
196             if (Character.isWhitespace(chars[i])) {
197                 firstCharacter = i;
198                 break;
199             }
200         }
201         // If we didn't find it once don't continue
202
if (firstCharacter == 0) {
203             return 0;
204         }
205         // Initialize to firstCharacter in case there is no more whitespace
206
int secondCharacter = firstCharacter;
207         // Find the second whitespace
208
for (int i = firstCharacter; i < chars.length; i++) {
209             if (Character.isWhitespace(chars[i])) {
210                 secondCharacter = i;
211                 break;
212             }
213         }
214         // Check that we haven't gone over max width. Throw
215
// out an index that is too high
216
if (gc.textExtent(textValue.substring(0, secondCharacter)).x > maxWidth) {
217             if (gc.textExtent(textValue.substring(0, firstCharacter)).x > maxWidth) {
218                 return 0;
219             }
220             return firstCharacter;
221         }
222         return secondCharacter;
223     }
224
225     /**
226      * If there are any modal shells open reschedule openJob to wait until they
227      * are closed. Return true if it rescheduled, false if there is nothing
228      * blocking it.
229      *
230      * @param openJob
231      * @return boolean. true if the job was rescheduled due to modal dialogs.
232      */

233     public static boolean rescheduleIfModalShellOpen(Job openJob) {
234         Shell modal = getModalShellExcluding(null);
235         if (modal == null) {
236             return false;
237         }
238
239         // try again in a few seconds
240
openJob.schedule(PlatformUI.getWorkbench().getProgressService()
241                 .getLongOperationTime());
242         return true;
243     }
244
245     /**
246      * Return whether or not it is safe to open this dialog. If so then return
247      * <code>true</code>. If not then set it to open itself when it has had
248      * ProgressManager#longOperationTime worth of ticks.
249      *
250      * @param dialog
251      * ProgressMonitorJobsDialog that will be opening
252      * @param excludedShell
253      * The shell
254      * @return boolean. <code>true</code> if it can open. Otherwise return
255      * false and set the dialog to tick.
256      */

257     public static boolean safeToOpen(ProgressMonitorJobsDialog dialog,
258             Shell excludedShell) {
259         Shell modal = getModalShellExcluding(excludedShell);
260         if (modal == null) {
261             return true;
262         }
263
264         dialog.watchTicks();
265         return false;
266     }
267
268     /**
269      * Return the modal shell that is currently open. If there isn't one then
270      * return null.
271      *
272      * @param shell
273      * A shell to exclude from the search. May be <code>null</code>.
274      *
275      * @return Shell or <code>null</code>.
276      */

277     public static Shell getModalShellExcluding(Shell shell) {
278         IWorkbench workbench = PlatformUI.getWorkbench();
279         Shell[] shells = workbench.getDisplay().getShells();
280         int modal = SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL
281                 | SWT.PRIMARY_MODAL;
282         for (int i = 0; i < shells.length; i++) {
283             if (shells[i].equals(shell)) {
284                 break;
285             }
286             // Do not worry about shells that will not block the user.
287
if (shells[i].isVisible()) {
288                 int style = shells[i].getStyle();
289                 if ((style & modal) != 0) {
290                     return shells[i];
291                 }
292             }
293         }
294         return null;
295     }
296
297     /**
298      * Utility method to get the best parenting possible for a dialog. If there
299      * is a modal shell create it so as to avoid two modal dialogs. If not then
300      * return the shell of the active workbench window. If neither can be found
301      * return null.
302      *
303      * @return Shell or <code>null</code>
304      */

305     public static Shell getDefaultParent() {
306         Shell modal = getModalShellExcluding(null);
307         if (modal != null) {
308             return modal;
309         }
310
311         return getNonModalShell();
312     }
313
314     /**
315      * Get the active non modal shell. If there isn't one return null.
316      *
317      * @return Shell
318      */

319     public static Shell getNonModalShell() {
320         IWorkbenchWindow window = PlatformUI.getWorkbench()
321                 .getActiveWorkbenchWindow();
322         if (window == null) {
323             IWorkbenchWindow[] windows = PlatformUI.getWorkbench()
324                     .getWorkbenchWindows();
325             if (windows.length > 0)
326                 return windows[0].getShell();
327         } else
328             return window.getShell();
329
330         return null;
331     }
332
333     /**
334      * Animate the closing of a window given the start position down to the
335      * progress region.
336      *
337      * @param startPosition
338      * Rectangle. The position to start drawing from.
339      */

340     public static void animateDown(Rectangle startPosition) {
341         IWorkbenchWindow currentWindow = PlatformUI.getWorkbench()
342                 .getActiveWorkbenchWindow();
343         if (currentWindow == null) {
344             return;
345         }
346         WorkbenchWindow internalWindow = (WorkbenchWindow) currentWindow;
347
348         ProgressRegion progressRegion = internalWindow.getProgressRegion();
349         if (progressRegion == null) {
350             return;
351         }
352         Rectangle endPosition = progressRegion.getControl().getBounds();
353
354         Point windowLocation = internalWindow.getShell().getLocation();
355         endPosition.x += windowLocation.x;
356         endPosition.y += windowLocation.y;
357         RectangleAnimation animation = new RectangleAnimation(internalWindow
358                 .getShell(), startPosition, endPosition);
359         animation.schedule();
360     }
361
362     /**
363      * Animate the opening of a window given the start position down to the
364      * progress region.
365      *
366      * @param endPosition
367      * Rectangle. The position to end drawing at.
368      */

369     public static void animateUp(Rectangle endPosition) {
370         IWorkbenchWindow currentWindow = PlatformUI.getWorkbench()
371                 .getActiveWorkbenchWindow();
372         if (currentWindow == null) {
373             return;
374         }
375         WorkbenchWindow internalWindow = (WorkbenchWindow) currentWindow;
376         Point windowLocation = internalWindow.getShell().getLocation();
377
378         ProgressRegion progressRegion = internalWindow.getProgressRegion();
379         if (progressRegion == null) {
380             return;
381         }
382         Rectangle startPosition = progressRegion.getControl().getBounds();
383         startPosition.x += windowLocation.x;
384         startPosition.y += windowLocation.y;
385
386         RectangleAnimation animation = new RectangleAnimation(internalWindow
387                 .getShell(), startPosition, endPosition);
388         animation.schedule();
389     }
390
391     /**
392      * Get the shell provider to use in the progress support dialogs. This
393      * provider will try to always parent off of an existing modal shell. If
394      * there isn't one it will use the current workbench window.
395      *
396      * @return IShellProvider
397      */

398     static IShellProvider getShellProvider() {
399         return new IShellProvider() {
400
401             /*
402              * (non-Javadoc)
403              *
404              * @see org.eclipse.jface.window.IShellProvider#getShell()
405              */

406             public Shell getShell() {
407                 return getDefaultParent();
408             }
409         };
410     }
411
412     /**
413      * Get the icons root for the progress support.
414      * @return URL
415      */

416     public static URL JavaDoc getIconsRoot() {
417         return BundleUtility.find(PlatformUI.PLUGIN_ID,
418                 ProgressManager.PROGRESS_FOLDER);
419     }
420     
421     /**
422      * Return the location of the progress spinner.
423      * @return URL or <code>null</code> if it cannot be found
424      */

425     public static URL JavaDoc getProgressSpinnerLocation(){
426         try {
427             return new URL JavaDoc(getIconsRoot(), "progress_spinner.gif");//$NON-NLS-1$
428
} catch (MalformedURLException JavaDoc e) {
429             return null;
430         }
431     }
432 }
433
Popular Tags