3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
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.
11 package eu
.etaxonomy
.taxeditor
.model
;
13 import java
.lang
.reflect
.InvocationTargetException
;
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
;
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
;
61 * Abstract AbstractUtility class.
68 public abstract class AbstractUtility
{
70 /** Constant <code>statusLineManager</code> */
71 protected static IStatusLineManager statusLineManager
;
80 public static boolean closeAll() {
81 return getActivePage().closeAllEditors(true);
85 * Close the given editor.
88 * The <tt>MultipageTaxonEditor</tt> to close.
89 * @return <tt>true</tt> on success
91 public static boolean close(EditorPart editor
) {
92 return getActivePage().closeEditor(editor
, true);
100 * @return a {@link org.eclipse.swt.widgets.Shell} object.
102 public static Shell
getShell() {
104 return TaxeditorStorePlugin
.getDefault().getWorkbench()
105 .getActiveWorkbenchWindow().getShell();
113 * @return a {@link org.eclipse.ui.IWorkbenchPage} object.
115 public static IWorkbenchPage
getActivePage() {
117 return TaxeditorStorePlugin
.getDefault().getWorkbench()
118 .getActiveWorkbenchWindow().getActivePage();
126 * @return a {@link org.eclipse.ui.IWorkbenchPart} object.
128 public static IWorkbenchPart
getActivePart() {
129 return getActivePage() != null ?
getActivePage().getActivePart() : null;
132 public static IWorkbench
getWorkbench() {
133 return TaxeditorStorePlugin
.getDefault().getWorkbench();
141 * @return a {@link org.eclipse.jface.window.ApplicationWindow} object.
143 public static ApplicationWindow
getWorkbenchWindow() {
144 if (getWorkbench().getWorkbenchWindowCount() > 1) {
145 throw new IllegalStateException("More than one workbench window");
147 return (ApplicationWindow
) getWorkbench().getWorkbenchWindows()[0];
156 * a {@link java.lang.String} object.
157 * @return a {@link org.eclipse.ui.IViewPart} object.
159 public static IViewPart
showView(String id
) {
161 return PlatformUI
.getWorkbench().getActiveWorkbenchWindow()
163 .showView(id
, null, IWorkbenchPage
.VIEW_VISIBLE
);
164 } catch (PartInitException e
) {
165 errorDialog("Error opening view", AbstractUtility
.class, "Could not open view: " + id
, e
);
176 * a {@link org.eclipse.ui.IViewPart} object.
178 public static void hideView(IViewPart view
) {
179 PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getActivePage()
189 * a {@link java.lang.String} object.
192 * @return a {@link org.eclipse.ui.IViewPart} object.
194 public static IViewPart
getView(String id
, boolean restore
) {
195 IViewReference
[] references
= PlatformUI
.getWorkbench()
196 .getActiveWorkbenchWindow().getActivePage().getViewReferences();
197 for (IViewReference reference
: references
) {
198 if (reference
.getId().equals(id
)) {
199 return reference
.getView(restore
);
211 * a {@link java.lang.Class} object.
212 * @return a {@link java.lang.Object} object.
214 public static Object
getService(Class api
) {
215 return TaxeditorStorePlugin
.getDefault().getWorkbench().getService(api
);
223 * @return a {@link org.eclipse.ui.themes.ITheme} object.
225 public static ITheme
getCurrentTheme() {
226 IThemeManager themeManager
= TaxeditorStorePlugin
.getDefault()
227 .getWorkbench().getThemeManager();
228 return themeManager
.getCurrentTheme();
232 * Fonts registered to the plugin may be obtained with the Eclipse themeing
233 * functionality. Thus fonts are chooseable by the user via
234 * Preferences->General->Appearance->Colors and Fonts
236 * @return the FontRegistry for the current theme
238 public static FontRegistry
getFontRegistry() {
239 return getCurrentTheme().getFontRegistry();
247 * @param symbolicName
248 * a {@link java.lang.String} object.
249 * @return a {@link org.eclipse.swt.graphics.Font} object.
251 public static Font
getFont(String symbolicName
) {
252 return getFontRegistry().get(symbolicName
);
256 * Color registered to the plugin may be obtained with the Eclipse themeing
257 * functionality. Thus colors are editable by the user via
258 * Preferences->General->Appearance->Colors and Fonts
260 * @return the ColorRegistry for the current theme
262 public static ColorRegistry
getColorRegistry() {
263 return getCurrentTheme().getColorRegistry();
271 * @param symbolicName
272 * a {@link java.lang.String} object.
273 * @return a {@link org.eclipse.swt.graphics.Color} object.
275 public static Color
getColor(String symbolicName
) {
276 return getColorRegistry().get(symbolicName
);
280 * Open a message box that informs the user about unimplemented
281 * functionality. This method is for developer convenience.
284 * a {@link java.lang.Object} object.
286 public static void notImplementedMessage(Object source
) {
287 warningDialog("Not yet implemented", source
,
288 "This functionality is not yet implemented.");
297 * a {@link java.lang.String} object.
299 * a {@link java.lang.String} object.
301 public static void informationDialog(final String title
,
302 final String message
) {
303 Display
.getDefault().asyncExec(new Runnable() {
306 MessageDialog
.openInformation(getShell(), title
, message
);
311 public static void informationDialog(final String title
,
312 final IStatus status
) {
313 informationDialog(title
, status
.getMessage());
324 * The object where the warning was generated (used by log4j)
326 * An informative String to be presented to the user
328 public static void warningDialog(final String title
, final Object source
,
329 final String message
) {
330 Display
.getDefault().asyncExec(new Runnable() {
333 MessageDialog
.openWarning(getShell(), title
, message
);
334 Class
<?
extends Object
> clazz
= source
!= null ? source
335 .getClass() : AbstractUtility
.class;
336 warn(clazz
, message
);
346 public static void warningDialog(String title
, Object source
,
348 warningDialog(title
, source
, status
.getMessage());
359 * The object where the warning was generated (used by log4j)
361 * An informative String to be presented to the user
365 * a Throwable if one exists or null
367 public static void errorDialog(final String title
, final Object source
,
368 final String message
, final Throwable t
) {
369 Display
.getDefault().asyncExec(new Runnable() {
372 MessageDialog
.openError(getShell(), title
, message
+ getCauseRecursively(t
));
373 Class
<?
extends Object
> clazz
= source
!= null ? source
374 .getClass() : this.getClass();
375 error(clazz
, message
, t
);
378 private String
getCauseRecursively(Throwable t
) {
383 if(t
.getCause() != null){
384 return getCauseRecursively(t
.getCause());
386 return String
.format("\n\nException: %s\nMessage: %s", t
.getClass().getSimpleName(), t
.getMessage());
393 public static void errorDialog(final String title
, final Object source
,
394 final String message
){
395 errorDialog(title
, source
, message
, null);
404 * a {@link java.lang.String} object.
406 * a {@link java.lang.Object} object.
408 * a {@link org.eclipse.core.runtime.IStatus} object.
410 public static void errorDialog(final String title
, final Object source
,
411 final IStatus status
) {
412 Display
.getDefault().asyncExec(new Runnable() {
415 MessageDialog
.openError(getShell(), title
, status
.getMessage());
416 Class
<?
extends Object
> clazz
= source
!= null ? source
417 .getClass() : this.getClass();
418 error(clazz
, status
.getMessage(), status
.getException());
429 * a {@link java.lang.String} object.
431 * a {@link java.lang.String} object.
434 public static boolean confirmDialog(String title
, String message
) {
435 return MessageDialog
.openQuestion(getShell(), title
, message
);
445 * {@link eu.etaxonomy.taxeditor.operation.AbstractPostOperation}
447 * @return a {@link org.eclipse.core.runtime.IStatus} object.
449 public static IStatus
executeOperation(final AbstractPostOperation operation
) {
450 if (getOperationHistory() == null) {
451 throw new IllegalArgumentException(
452 "There is no operation history for this context");
455 final IAdaptable uiInfoAdapter
= WorkspaceUndoUtil
456 .getUIInfoAdapter(getShell());
458 IRunnableWithProgress runnable
= new IRunnableWithProgress() {
460 public void run(IProgressMonitor monitor
)
461 throws InvocationTargetException
, InterruptedException
{
462 monitor
.beginTask(operation
.getLabel(), 100);
463 IStatus status
= Status
.CANCEL_STATUS
;
465 operation
.addContext(IOperationHistory
.GLOBAL_UNDO_CONTEXT
);
466 status
= getOperationHistory().execute(operation
, monitor
,
468 } catch (ExecutionException e
) {
469 errorDialog("Error executing operation", getClass(), String
.format("An error occured while executing %s.", operation
.getLabel()), e
);
474 String statusString
= status
.equals(Status
.OK_STATUS
) ?
"completed"
476 setStatusLine(operation
.getLabel() + " " + statusString
+ ".");
482 runInUI(runnable
, null);
483 } catch (Exception e
) {
484 errorDialog("Error executing operation", AbstractUtility
.class, "An error occured while executing " + operation
.getLabel(), e
);
487 // // Start the main progress monitor.
488 // IProgressMonitor newMonitor =
489 // startMainMonitor(getMonitor(),operation.getLabel(), 100);
491 // // Check whether operation was canceled and do some steps.
492 // workedChecked(newMonitor, 10);
495 // IStatus status = getOperationHistory().execute(operation, newMonitor,
496 // WorkspaceUndoUtil.getUIInfoAdapter(getShell()));
498 // // Check whether operation was canceled and do some steps.
499 // workedChecked(newMonitor, 30);
501 // String statusString = status.equals(Status.OK_STATUS) ? "completed" :
503 // setStatusLine(operation.getLabel() + " " + statusString + ".");
506 // } catch (ExecutionException e) {
507 // logger.error("Error executing operation: " + operation.getLabel(),
509 // errorDialog("Error executing operation: " + operation.getLabel(),
510 // "Please refer to the error log.");
514 // // Stop the progress monitor.
515 // newMonitor.done();
518 IPostOperationEnabled postOperationEnabled
= operation
519 .getPostOperationEnabled();
520 if (postOperationEnabled
!= null) {
521 postOperationEnabled
.onComplete();
523 return Status
.OK_STATUS
;
528 * getOperationHistory
531 * @return a {@link org.eclipse.core.commands.operations.IOperationHistory}
534 public static IOperationHistory
getOperationHistory() {
535 return getWorkbench().getOperationSupport().getOperationHistory();
544 * a {@link java.lang.String} object.
546 public static void setStatusLine(final String message
) {
547 Display
.getDefault().asyncExec(new Runnable() {
550 statusLineManager
.setMessage(message
);
562 * @return a {@link org.eclipse.core.runtime.IProgressMonitor} object.
564 public static IProgressMonitor
getMonitor() {
565 statusLineManager
.setCancelEnabled(false);
566 return statusLineManager
.getProgressMonitor();
570 * Starts either the given {@link IProgressMonitor} if it's not
571 * <code>null</code> or a new {@link NullProgressMonitor}.
573 * @param progressMonitor
574 * The {@link IProgressMonitor} or <code>null</code> if no
575 * progress should be reported.
577 * The name of the main task.
579 * The number of steps this task is subdivided into.
580 * @return The {@link IProgressMonitor}.
582 public static IProgressMonitor
startMainMonitor(
583 IProgressMonitor progressMonitor
, String taskName
, int steps
) {
584 IProgressMonitor newMonitor
= progressMonitor
;
585 if (newMonitor
== null) {
586 newMonitor
= new NullProgressMonitor();
588 newMonitor
.beginTask(taskName
== null ?
"" : taskName
, steps
);
589 newMonitor
.subTask(" ");
594 * Creates a {@link SubProgressMonitor} if the given
595 * {@link IProgressMonitor} is not <code>null</code> and not a
596 * {@link NullProgressMonitor}.
598 * @param progressMonitor
599 * The parent {@link IProgressMonitor} of the
600 * {@link SubProgressMonitor} to be created.
602 * The number of steps this subtask is subdivided into. Must be a
603 * positive number and must not be
604 * {@link IProgressMonitor#UNKNOWN}.
605 * @return The {@link IProgressMonitor}.
607 public static IProgressMonitor
getSubProgressMonitor(
608 IProgressMonitor progressMonitor
, int ticks
) {
609 if (progressMonitor
== null) {
610 return new NullProgressMonitor();
612 if (progressMonitor
instanceof NullProgressMonitor
) {
613 return progressMonitor
;
616 return new SubProgressMonitor(progressMonitor
, ticks
);
620 * Checks whether the user canceled this operation. If not canceled, the
621 * given number of steps are declared as done.
624 * a {@link org.eclipse.core.runtime.IProgressMonitor} object.
628 public static void workedChecked(IProgressMonitor newMonitor
, int steps
) {
629 // In case the progress monitor was canceled throw an exception.
630 if (newMonitor
.isCanceled()) {
631 throw new OperationCanceledException();
633 // Otherwise declare this step as done.
634 newMonitor
.worked(steps
);
638 * Present a progress dialog to the user. This dialog will block the UI
641 * an implementation of {@link IRunnableWithProgress}
642 * @throws java.lang.InterruptedException
644 * @throws java.lang.reflect.InvocationTargetException
647 public static void busyCursorWhile(IRunnableWithProgress runnable
)
648 throws InvocationTargetException
, InterruptedException
{
649 getProgressService().busyCursorWhile(runnable
);
657 * @see {@link IProgressService#runInUI(org.eclipse.jface.operation.IRunnableContext, IRunnableWithProgress, ISchedulingRule)}
659 * a {@link org.eclipse.jface.operation.IRunnableWithProgress}
662 * a {@link org.eclipse.core.runtime.jobs.ISchedulingRule}
664 * @throws java.lang.reflect.InvocationTargetException
666 * @throws java.lang.InterruptedException
669 public static void runInUI(IRunnableWithProgress runnable
,
670 ISchedulingRule rule
) throws InvocationTargetException
,
671 InterruptedException
{
672 getProgressService().runInUI(getWorkbenchWindow(), runnable
, rule
);
685 * a {@link org.eclipse.jface.operation.IRunnableWithProgress}
687 * @throws java.lang.reflect.InvocationTargetException
689 * @throws java.lang.InterruptedException
692 public static void run(boolean fork
, boolean cancelable
,
693 IRunnableWithProgress runnable
) throws InvocationTargetException
,
694 InterruptedException
{
695 getProgressService().run(fork
, cancelable
, runnable
);
703 * @return a {@link org.eclipse.ui.progress.IProgressService} object.
705 public static IProgressService
getProgressService() {
706 IWorkbench workbench
= PlatformUI
.getWorkbench();
707 return workbench
.getProgressService();
712 * getProgressService2
715 * @return a {@link org.eclipse.ui.progress.IWorkbenchSiteProgressService}
718 public static IWorkbenchSiteProgressService
getProgressService2() {
719 return (IWorkbenchSiteProgressService
) getService(IWorkbenchSiteProgressService
.class);
728 * a {@link java.lang.String} object.
730 public static void info(String message
) {
731 IStatus status
= new Status(IStatus
.INFO
, getPluginId(), message
);
741 * a {@link org.eclipse.core.runtime.IStatus} object.
743 public static void info(IStatus status
) {
753 * a {@link java.lang.Class} object.
755 * a {@link java.lang.String} object.
757 public static void warn(Class source
, String message
) {
758 IStatus status
= new Status(IStatus
.WARNING
, getPluginId(), message
);
759 getLog4JLogger(source
).warn(message
);
763 public static void warn(Class source
, IStatus status
) {
764 getLog4JLogger(source
).warn(status
.getMessage(), status
.getException());
768 public static void warn(Class source
, Throwable t
) {
769 IStatus status
= new Status(IStatus
.WARNING
, getPluginId(), t
.getMessage(), t
);
770 getLog4JLogger(source
).warn(t
);
780 * a {@link java.lang.Class} object.
782 * a {@link java.lang.Throwable} object.
784 public static void error(Class source
, Throwable t
) {
785 error(source
.getClass(), t
.getMessage(), t
);
794 * a {@link java.lang.Class} object.
796 * a {@link java.lang.String} object.
798 * a {@link java.lang.Throwable} object.
800 public static void error(Class source
, String message
, Throwable t
) {
801 IStatus status
= new Status(IStatus
.ERROR
, getPluginId(), message
, t
);
802 error(source
, status
);
811 * a {@link java.lang.Class} object.
813 * a {@link org.eclipse.core.runtime.IStatus} object.
815 public static void error(Class source
, IStatus status
) {
816 getLog4JLogger(source
)
817 .error(status
.getMessage(), status
.getException());
827 * a {@link java.lang.Class} object.
828 * @return a {@link org.apache.log4j.Logger} object.
830 public static Logger
getLog4JLogger(Class clazz
) {
831 return Logger
.getLogger(clazz
);
835 * @see {@link ILog#log(IStatus)}
839 private static void log(IStatus status
) {
840 TaxeditorStorePlugin
.getDefault().getLog().log(status
);
848 * @return a {@link java.lang.String} object.
850 public static String
getPluginId() {
851 return "eu.taxeditor";
859 * @return a {@link org.eclipse.ui.IEditorPart} object.
861 public static IEditorPart
getActiveEditor() {
862 return getActivePage() != null ?
getActivePage().getActiveEditor()
871 * @return a {@link eu.etaxonomy.taxeditor.view.detail.DetailsViewPart}
874 public static DetailsViewPart
getDetailsView() {
875 return (DetailsViewPart
) getView(DetailsViewPart
.ID
, false);
880 * refreshDetailsViewer
883 public static void refreshDetailsViewer() {
884 if (getDetailsView() != null) {
885 ((AbstractCdmDataViewer
) getDetailsView().getViewer()).refresh();
891 * reflowDetailsViewer
894 public static void reflowDetailsViewer() {
895 if (getDetailsView() != null) {
896 ((AbstractCdmDataViewer
) getDetailsView().getViewer()).reflow();
900 public static SupplementalDataViewPart
getSupplementalDataView() {
901 return (SupplementalDataViewPart
) getView(SupplementalDataViewPart
.ID
,
905 public static void reflowSupplementalViewer() {
906 if (getSupplementalDataView() != null) {
907 ((AbstractCdmDataViewer
) getSupplementalDataView().getViewer())