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