Implemented MobotOpenUrl UI
[taxeditor.git] / taxeditor-store / src / main / java / eu / etaxonomy / taxeditor / model / AbstractUtility.java
1 // $Id$
2 /**
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10
11 package eu.etaxonomy.taxeditor.model;
12
13 import java.lang.reflect.InvocationTargetException;
14
15 import org.apache.log4j.Logger;
16 import org.eclipse.core.commands.ExecutionException;
17 import org.eclipse.core.commands.operations.IOperationHistory;
18 import org.eclipse.core.runtime.IAdaptable;
19 import org.eclipse.core.runtime.ILog;
20 import org.eclipse.core.runtime.IProgressMonitor;
21 import org.eclipse.core.runtime.IStatus;
22 import org.eclipse.core.runtime.NullProgressMonitor;
23 import org.eclipse.core.runtime.OperationCanceledException;
24 import org.eclipse.core.runtime.Status;
25 import org.eclipse.core.runtime.SubProgressMonitor;
26 import org.eclipse.core.runtime.jobs.ISchedulingRule;
27 import org.eclipse.jface.action.IStatusLineManager;
28 import org.eclipse.jface.dialogs.MessageDialog;
29 import org.eclipse.jface.operation.IRunnableWithProgress;
30 import org.eclipse.jface.resource.ColorRegistry;
31 import org.eclipse.jface.resource.FontRegistry;
32 import org.eclipse.jface.window.ApplicationWindow;
33 import org.eclipse.swt.graphics.Color;
34 import org.eclipse.swt.graphics.Font;
35 import org.eclipse.swt.widgets.Display;
36 import org.eclipse.swt.widgets.Shell;
37 import org.eclipse.ui.IViewPart;
38 import org.eclipse.ui.IViewReference;
39 import org.eclipse.ui.IWorkbench;
40 import org.eclipse.ui.IWorkbenchPage;
41 import org.eclipse.ui.IWorkbenchPart;
42 import org.eclipse.ui.PartInitException;
43 import org.eclipse.ui.PlatformUI;
44 import org.eclipse.ui.ide.undo.WorkspaceUndoUtil;
45 import org.eclipse.ui.part.EditorPart;
46 import org.eclipse.ui.progress.IProgressService;
47 import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
48 import org.eclipse.ui.themes.ITheme;
49 import org.eclipse.ui.themes.IThemeManager;
50
51 import eu.etaxonomy.taxeditor.operation.AbstractPostOperation;
52 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
53 import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
54
55 /**
56 * <p>Abstract AbstractUtility class.</p>
57 *
58 * @author n.hoffmann
59 * @created 11.05.2009
60 * @version 1.0
61 */
62 public abstract class AbstractUtility {
63
64 /** Constant <code>statusLineManager</code> */
65 protected static IStatusLineManager statusLineManager;
66
67
68 /**
69 * <p>closeAll</p>
70 *
71 * @return a boolean.
72 */
73 public static boolean closeAll() {
74 return getActivePage().closeAllEditors(true);
75 }
76
77 /**
78 * Close the given editor.
79 *
80 * @param editor The <tt>MultipageTaxonEditor</tt> to close.
81 * @return <tt>true</tt> on success
82 */
83 public static boolean close(EditorPart editor) {
84 return getActivePage().closeEditor(editor, true);
85 }
86
87 /**
88 * <p>getShell</p>
89 *
90 * @return a {@link org.eclipse.swt.widgets.Shell} object.
91 */
92 public static Shell getShell() {
93
94 return TaxeditorStorePlugin.getDefault().getWorkbench()
95 .getActiveWorkbenchWindow().getShell();
96 }
97
98 /**
99 * <p>getActivePage</p>
100 *
101 * @return a {@link org.eclipse.ui.IWorkbenchPage} object.
102 */
103 public static IWorkbenchPage getActivePage(){
104
105 return TaxeditorStorePlugin.getDefault().getWorkbench()
106 .getActiveWorkbenchWindow().getActivePage();
107 }
108
109 /**
110 * <p>getActivePart</p>
111 *
112 * @return a {@link org.eclipse.ui.IWorkbenchPart} object.
113 */
114 public static IWorkbenchPart getActivePart(){
115 return getActivePage() != null ? getActivePage().getActivePart() : null;
116 }
117
118 /**
119 * <p>getWorkbenchWindow</p>
120 *
121 * @return a {@link org.eclipse.jface.window.ApplicationWindow} object.
122 */
123 public static ApplicationWindow getWorkbenchWindow(){
124 if(TaxeditorStorePlugin.getDefault().getWorkbench().getWorkbenchWindowCount() > 1){
125 throw new IllegalStateException("More than one workbench window");
126 }
127 return (ApplicationWindow) TaxeditorStorePlugin.getDefault().getWorkbench().getWorkbenchWindows()[0];
128 }
129
130 /**
131 * <p>showView</p>
132 *
133 * @param id a {@link java.lang.String} object.
134 * @return a {@link org.eclipse.ui.IViewPart} object.
135 */
136 public static IViewPart showView(String id){
137 try {
138 return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView(id, null, IWorkbenchPage.VIEW_VISIBLE);
139 } catch (PartInitException e) {
140 error(AbstractUtility.class, "Could not open view: " + id, e);
141 throw new RuntimeException(e);
142 }
143 }
144
145 /**
146 * <p>hideView</p>
147 *
148 * @param view a {@link org.eclipse.ui.IViewPart} object.
149 */
150 public static void hideView(IViewPart view){
151 PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().hideView(view);
152 }
153
154
155 /**
156 * <p>getView</p>
157 *
158 * @param id a {@link java.lang.String} object.
159 * @param restore a boolean.
160 * @return a {@link org.eclipse.ui.IViewPart} object.
161 */
162 public static IViewPart getView(String id, boolean restore){
163 IViewReference[] references = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getViewReferences();
164 for (IViewReference reference : references){
165 if(reference.getId().equals(id)){
166 return reference.getView(restore);
167 }
168 }
169 return null;
170 }
171
172 /**
173 * <p>getService</p>
174 *
175 * @param api a {@link java.lang.Class} object.
176 * @return a {@link java.lang.Object} object.
177 */
178 public static Object getService(Class api){
179 return TaxeditorStorePlugin.getDefault().getWorkbench().getService(api);
180 }
181
182 /**
183 * <p>getCurrentTheme</p>
184 *
185 * @return a {@link org.eclipse.ui.themes.ITheme} object.
186 */
187 public static ITheme getCurrentTheme(){
188 IThemeManager themeManager = TaxeditorStorePlugin.getDefault().getWorkbench().getThemeManager();
189 return themeManager.getCurrentTheme();
190 }
191
192 /**
193 * Fonts registered to the plugin may be obtained with the Eclipse themeing functionality.
194 * Thus fonts are chooseable by the user via Preferences->General->Appearance->Colors and Fonts
195 *
196 * @return the FontRegistry for the current theme
197 */
198 public static FontRegistry getFontRegistry(){
199 return getCurrentTheme().getFontRegistry();
200 }
201
202 /**
203 * <p>getFont</p>
204 *
205 * @param symbolicName a {@link java.lang.String} object.
206 * @return a {@link org.eclipse.swt.graphics.Font} object.
207 */
208 public static Font getFont(String symbolicName){
209 return getFontRegistry().get(symbolicName);
210 }
211
212 /**
213 * Color registered to the plugin may be obtained with the Eclipse themeing functionality.
214 * Thus colors are editable by the user via Preferences->General->Appearance->Colors and Fonts
215 *
216 * @return the ColorRegistry for the current theme
217 */
218 public static ColorRegistry getColorRegistry(){
219 return getCurrentTheme().getColorRegistry();
220 }
221
222 /**
223 * <p>getColor</p>
224 *
225 * @param symbolicName a {@link java.lang.String} object.
226 * @return a {@link org.eclipse.swt.graphics.Color} object.
227 */
228 public static Color getColor(String symbolicName){
229 return getColorRegistry().get(symbolicName);
230 }
231
232 /**
233 * Open a message box that informs the user about unimplemented functionality.
234 * This method is for developer convenience.
235 *
236 * @param source a {@link java.lang.Object} object.
237 */
238 public static void notImplementedMessage(Object source){
239 warningDialog("Not yet implemented", source, "This functionality is not yet implemented.");
240 }
241
242 /**
243 * <p>informationDialog</p>
244 *
245 * @param title a {@link java.lang.String} object.
246 * @param message a {@link java.lang.String} object.
247 */
248 public static void informationDialog(final String title, final String message){
249 Display.getDefault().asyncExec(new Runnable(){
250
251 public void run() {
252 MessageDialog.openInformation(getShell(), title, message);
253 }
254 });
255 }
256
257 /**
258 * <p>warningDialog</p>
259 *
260 * @param title The dialogs title
261 * @param source The object where the warning was generated (used by log4j)
262 * @param message An informative String to be presented to the user
263 */
264 public static void warningDialog(final String title, final Object source, final String message){
265 Display.getDefault().asyncExec(new Runnable(){
266
267 public void run() {
268 MessageDialog.openWarning(getShell(), title, message);
269 Class<? extends Object> clazz = source != null ? source.getClass() : AbstractUtility.class;
270 warn(clazz, message);
271 }
272 });
273 }
274
275 /**
276 * <p>errorDialog</p>
277 *
278 * @param title The dialogs title
279 * @param source The object where the warning was generated (used by log4j)
280 * @param message An informative String to be presented to the user
281 * @param title The dialogs title
282 * @param t a Throwable if one exists or null
283 */
284 public static void errorDialog(final String title, final Object source, final String message, final Throwable t){
285 Display.getDefault().asyncExec(new Runnable(){
286
287 public void run() {
288 MessageDialog.openError(getShell(), title, message);
289 Class<? extends Object> clazz = source != null ? source.getClass() : this.getClass();
290 error(clazz, message, t);
291 }
292 });
293 }
294
295 /**
296 * <p>errorDialog</p>
297 *
298 * @param title a {@link java.lang.String} object.
299 * @param source a {@link java.lang.Object} object.
300 * @param status a {@link org.eclipse.core.runtime.IStatus} object.
301 */
302 public static void errorDialog(final String title, final Object source, final IStatus status){
303 Display.getDefault().asyncExec(new Runnable(){
304
305 public void run() {
306 MessageDialog.openError(getShell(), title, status.getMessage());
307 Class<? extends Object> clazz = source != null ? source.getClass() : this.getClass();
308 error(clazz, status.getMessage(), status.getException());
309 }
310 });
311 }
312
313 /**
314 * <p>confirmDialog</p>
315 *
316 * @param title a {@link java.lang.String} object.
317 * @param message a {@link java.lang.String} object.
318 * @return a boolean.
319 */
320 public static boolean confirmDialog(String title, String message) {
321 return MessageDialog.openQuestion(getShell(), title, message);
322 }
323
324 /**
325 * <p>executeOperation</p>
326 *
327 * @param operation a {@link eu.etaxonomy.taxeditor.operation.AbstractPostOperation} object.
328 * @return a {@link org.eclipse.core.runtime.IStatus} object.
329 */
330 public static IStatus executeOperation(final AbstractPostOperation operation){
331 if(getOperationHistory() == null){
332 throw new IllegalArgumentException("There is no operation history for this context");
333 }
334
335 final IAdaptable uiInfoAdapter = WorkspaceUndoUtil.getUIInfoAdapter(getShell());
336
337
338
339 IRunnableWithProgress runnable = new IRunnableWithProgress() {
340
341 public void run(IProgressMonitor monitor) throws InvocationTargetException,
342 InterruptedException {
343 monitor.beginTask(operation.getLabel(), 100);
344 IStatus status;
345 try {
346 status = getOperationHistory().execute(operation, monitor, uiInfoAdapter);
347 } catch (ExecutionException e) {
348 throw new RuntimeException(e);
349 }
350 monitor.done();
351 String statusString = status.equals(Status.OK_STATUS) ? "completed" : "cancelled";
352 setStatusLine(operation.getLabel() + " " + statusString + ".");
353
354 }
355 };
356
357 try {
358 runInUI(runnable, null);
359 } catch (InvocationTargetException e) {
360 throw new RuntimeException(e);
361 } catch (InterruptedException e) {
362 throw new RuntimeException(e);
363 }
364
365 // // Start the main progress monitor.
366 // IProgressMonitor newMonitor = startMainMonitor(getMonitor(),operation.getLabel(), 100);
367 //
368 // // Check whether operation was canceled and do some steps.
369 // workedChecked(newMonitor, 10);
370 //
371 // try {
372 // IStatus status = getOperationHistory().execute(operation, newMonitor,
373 // WorkspaceUndoUtil.getUIInfoAdapter(getShell()));
374 //
375 // // Check whether operation was canceled and do some steps.
376 // workedChecked(newMonitor, 30);
377 //
378 // String statusString = status.equals(Status.OK_STATUS) ? "completed" : "cancelled";
379 // setStatusLine(operation.getLabel() + " " + statusString + ".");
380 //
381 // return status;
382 // } catch (ExecutionException e) {
383 // logger.error("Error executing operation: " + operation.getLabel(), e);
384 // errorDialog("Error executing operation: " + operation.getLabel(), "Please refer to the error log.");
385 // }
386 // finally {
387 //
388 // // Stop the progress monitor.
389 // newMonitor.done();
390 // }
391
392 IPostOperationEnabled postOperationEnabled = operation.getPostOperationEnabled();
393 postOperationEnabled.onComplete();
394 return Status.OK_STATUS;
395 }
396
397 /**
398 * <p>getOperationHistory</p>
399 *
400 * @return a {@link org.eclipse.core.commands.operations.IOperationHistory} object.
401 */
402 public static IOperationHistory getOperationHistory(){
403 return TaxeditorStorePlugin.getDefault().getWorkbench().
404 getOperationSupport().getOperationHistory();
405 }
406
407 /**
408 * <p>setStatusLine</p>
409 *
410 * @param message a {@link java.lang.String} object.
411 */
412 public static void setStatusLine(final String message) {
413 Display.getDefault().asyncExec(new Runnable(){
414
415 public void run() {
416 statusLineManager.setMessage(message);
417 }
418
419 });
420
421 }
422
423 /**
424 * <p>getMonitor</p>
425 *
426 * @return a {@link org.eclipse.core.runtime.IProgressMonitor} object.
427 */
428 public static IProgressMonitor getMonitor() {
429 statusLineManager.setCancelEnabled(false);
430 return statusLineManager.getProgressMonitor();
431 }
432
433 /**
434 * Starts either the given {@link IProgressMonitor} if it's not <code>null</code> or a new {@link NullProgressMonitor}.
435 *
436 * @param progressMonitor The {@link IProgressMonitor} or <code>null</code> if no progress should be reported.
437 * @param taskName The name of the main task.
438 * @param steps The number of steps this task is subdivided into.
439 * @return The {@link IProgressMonitor}.
440 */
441 public static IProgressMonitor startMainMonitor(IProgressMonitor progressMonitor, String taskName, int steps) {
442 IProgressMonitor newMonitor = progressMonitor;
443 if (newMonitor == null) {
444 newMonitor = new NullProgressMonitor();
445 }
446 newMonitor.beginTask(taskName == null ? "" : taskName, steps);
447 newMonitor.subTask(" ");
448 return newMonitor;
449 }
450
451 /**
452 * Creates a {@link SubProgressMonitor} if the given {@link IProgressMonitor} is not <code>null</code> and not a {@link NullProgressMonitor}.
453 *
454 * @param progressMonitor The parent {@link IProgressMonitor} of the {@link SubProgressMonitor} to be created.
455 * @param ticks The number of steps this subtask is subdivided into. Must be a positive number and must not be {@link IProgressMonitor#UNKNOWN}.
456 * @return The {@link IProgressMonitor}.
457 */
458 public static IProgressMonitor getSubProgressMonitor(IProgressMonitor progressMonitor, int ticks) {
459 if (progressMonitor == null) {
460 return new NullProgressMonitor();
461 }
462 if (progressMonitor instanceof NullProgressMonitor) {
463 return progressMonitor;
464 }
465
466 return new SubProgressMonitor(progressMonitor, ticks);
467 }
468
469 /**
470 * Checks whether the user canceled this operation. If not canceled, the given number of steps are declared as done.
471 *
472 * @param newMonitor a {@link org.eclipse.core.runtime.IProgressMonitor} object.
473 * @param steps a int.
474 */
475 public static void workedChecked(IProgressMonitor newMonitor, int steps) {
476 // In case the progress monitor was canceled throw an exception.
477 if (newMonitor.isCanceled()) {
478 throw new OperationCanceledException();
479 }
480 // Otherwise declare this step as done.
481 newMonitor.worked(steps);
482 }
483
484 /**
485 * Present a progress dialog to the user. This dialog will block the UI
486 *
487 * @param runnable an implementation of {@link IRunnableWithProgress}
488 * @throws java.lang.InterruptedException if any.
489 * @throws java.lang.reflect.InvocationTargetException if any.
490 */
491 public static void busyCursorWhile(IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException{
492 getProgressService().busyCursorWhile(runnable);
493 }
494
495 /**
496 * <p>runInUI</p>
497 *
498 * @see {@link IProgressService#runInUI(org.eclipse.jface.operation.IRunnableContext, IRunnableWithProgress, ISchedulingRule)}
499 * @param runnable a {@link org.eclipse.jface.operation.IRunnableWithProgress} object.
500 * @param rule a {@link org.eclipse.core.runtime.jobs.ISchedulingRule} object.
501 * @throws java.lang.reflect.InvocationTargetException if any.
502 * @throws java.lang.InterruptedException if any.
503 */
504 public static void runInUI(IRunnableWithProgress runnable, ISchedulingRule rule) throws InvocationTargetException, InterruptedException{
505 getProgressService().runInUI(getWorkbenchWindow(), runnable, rule);
506 }
507
508 /**
509 * <p>run</p>
510 *
511 * @param fork a boolean.
512 * @param cancelable a boolean.
513 * @param runnable a {@link org.eclipse.jface.operation.IRunnableWithProgress} object.
514 * @throws java.lang.reflect.InvocationTargetException if any.
515 * @throws java.lang.InterruptedException if any.
516 */
517 public static void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException{
518 getProgressService().run(fork, cancelable, runnable);
519 }
520
521 /**
522 * <p>getProgressService</p>
523 *
524 * @return a {@link org.eclipse.ui.progress.IProgressService} object.
525 */
526 public static IProgressService getProgressService(){
527 IWorkbench workbench = PlatformUI.getWorkbench();
528 return workbench.getProgressService();
529 }
530
531 /**
532 * <p>getProgressService2</p>
533 *
534 * @return a {@link org.eclipse.ui.progress.IWorkbenchSiteProgressService} object.
535 */
536 public static IWorkbenchSiteProgressService getProgressService2(){
537 return (IWorkbenchSiteProgressService) getService(IWorkbenchSiteProgressService.class);
538 }
539
540 /**
541 * <p>info</p>
542 *
543 * @param message a {@link java.lang.String} object.
544 */
545 public static void info(String message){
546 IStatus status = new Status(IStatus.INFO, getPluginId(), message);
547 info(status);
548 }
549
550 /**
551 * <p>info</p>
552 *
553 * @param status a {@link org.eclipse.core.runtime.IStatus} object.
554 */
555 public static void info(IStatus status){
556 log(status);
557 }
558
559 /**
560 * <p>warn</p>
561 *
562 * @param source a {@link java.lang.Class} object.
563 * @param message a {@link java.lang.String} object.
564 */
565 public static void warn(Class source, String message){
566 IStatus status = new Status(IStatus.WARNING, getPluginId(), message);
567 getLog4JLogger(source).warn(message);
568 log(status);
569 }
570
571 /**
572 * <p>error</p>
573 *
574 * @param source a {@link java.lang.Class} object.
575 * @param t a {@link java.lang.Throwable} object.
576 */
577 public static void error(Class source, Throwable t){
578 error(source.getClass(), t.getMessage(), t);
579 }
580
581 /**
582 * <p>error</p>
583 *
584 * @param source a {@link java.lang.Class} object.
585 * @param message a {@link java.lang.String} object.
586 * @param t a {@link java.lang.Throwable} object.
587 */
588 public static void error(Class source, String message, Throwable t){
589 IStatus status = new Status(IStatus.ERROR, getPluginId(), message, t);
590 error(source, status);
591 }
592
593 /**
594 * <p>error</p>
595 *
596 * @param source a {@link java.lang.Class} object.
597 * @param status a {@link org.eclipse.core.runtime.IStatus} object.
598 */
599 public static void error(Class source, IStatus status){
600 getLog4JLogger(source).error(status.getMessage(), status.getException());
601 log(status);
602 }
603
604
605 /**
606 * <p>getLog4JLogger</p>
607 *
608 * @param clazz a {@link java.lang.Class} object.
609 * @return a {@link org.apache.log4j.Logger} object.
610 */
611 public static Logger getLog4JLogger(
612 Class clazz) {
613 return Logger.getLogger(clazz);
614 }
615
616 /**
617 * @see {@link ILog#log(IStatus)}
618 *
619 * @param status
620 */
621 private static void log(IStatus status){
622 TaxeditorStorePlugin.getDefault().getLog().log(status);
623 }
624
625 /**
626 * <p>getPluginId</p>
627 *
628 * @return a {@link java.lang.String} object.
629 */
630 protected static String getPluginId(){
631 return "eu.taxeditor";
632 }
633 }