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
);
319 * The object where the warning was generated (used by log4j)
321 * An informative String to be presented to the user
323 public static void warningDialog(final String title
, final Object source
,
324 final String message
) {
325 Display
.getDefault().asyncExec(new Runnable() {
328 MessageDialog
.openWarning(getShell(), title
, message
);
329 Class
<?
extends Object
> clazz
= source
!= null ? source
330 .getClass() : AbstractUtility
.class;
331 warn(clazz
, message
);
344 * The object where the warning was generated (used by log4j)
346 * An informative String to be presented to the user
350 * a Throwable if one exists or null
352 public static void errorDialog(final String title
, final Object source
,
353 final String message
, final Throwable t
) {
354 Display
.getDefault().asyncExec(new Runnable() {
357 MessageDialog
.openError(getShell(), title
, message
+ getCauseRecursively(t
));
358 Class
<?
extends Object
> clazz
= source
!= null ? source
359 .getClass() : this.getClass();
360 error(clazz
, message
, t
);
363 private String
getCauseRecursively(Throwable t
) {
368 if(t
.getCause() != null){
369 return getCauseRecursively(t
.getCause());
371 return String
.format("\n\nException: %s\nMessage: %s", t
.getClass().getSimpleName(), t
.getMessage());
378 public static void errorDialog(final String title
, final Object source
,
379 final String message
){
380 errorDialog(title
, source
, message
, null);
389 * a {@link java.lang.String} object.
391 * a {@link java.lang.Object} object.
393 * a {@link org.eclipse.core.runtime.IStatus} object.
395 public static void errorDialog(final String title
, final Object source
,
396 final IStatus status
) {
397 Display
.getDefault().asyncExec(new Runnable() {
400 MessageDialog
.openError(getShell(), title
, status
.getMessage());
401 Class
<?
extends Object
> clazz
= source
!= null ? source
402 .getClass() : this.getClass();
403 error(clazz
, status
.getMessage(), status
.getException());
414 * a {@link java.lang.String} object.
416 * a {@link java.lang.String} object.
419 public static boolean confirmDialog(String title
, String message
) {
420 return MessageDialog
.openQuestion(getShell(), title
, message
);
430 * {@link eu.etaxonomy.taxeditor.operation.AbstractPostOperation}
432 * @return a {@link org.eclipse.core.runtime.IStatus} object.
434 public static IStatus
executeOperation(final AbstractPostOperation operation
) {
435 if (getOperationHistory() == null) {
436 throw new IllegalArgumentException(
437 "There is no operation history for this context");
440 final IAdaptable uiInfoAdapter
= WorkspaceUndoUtil
441 .getUIInfoAdapter(getShell());
443 IRunnableWithProgress runnable
= new IRunnableWithProgress() {
445 public void run(IProgressMonitor monitor
)
446 throws InvocationTargetException
, InterruptedException
{
447 monitor
.beginTask(operation
.getLabel(), 100);
448 IStatus status
= Status
.CANCEL_STATUS
;
450 operation
.addContext(IOperationHistory
.GLOBAL_UNDO_CONTEXT
);
451 status
= getOperationHistory().execute(operation
, monitor
,
453 } catch (ExecutionException e
) {
454 errorDialog("Error executing operation", getClass(), String
.format("An error occured while executing %s.", operation
.getLabel()), e
);
459 String statusString
= status
.equals(Status
.OK_STATUS
) ?
"completed"
461 setStatusLine(operation
.getLabel() + " " + statusString
+ ".");
467 runInUI(runnable
, null);
468 } catch (Exception e
) {
469 errorDialog("Error executing operation", AbstractUtility
.class, "An error occured while executing " + operation
.getLabel(), e
);
472 // // Start the main progress monitor.
473 // IProgressMonitor newMonitor =
474 // startMainMonitor(getMonitor(),operation.getLabel(), 100);
476 // // Check whether operation was canceled and do some steps.
477 // workedChecked(newMonitor, 10);
480 // IStatus status = getOperationHistory().execute(operation, newMonitor,
481 // WorkspaceUndoUtil.getUIInfoAdapter(getShell()));
483 // // Check whether operation was canceled and do some steps.
484 // workedChecked(newMonitor, 30);
486 // String statusString = status.equals(Status.OK_STATUS) ? "completed" :
488 // setStatusLine(operation.getLabel() + " " + statusString + ".");
491 // } catch (ExecutionException e) {
492 // logger.error("Error executing operation: " + operation.getLabel(),
494 // errorDialog("Error executing operation: " + operation.getLabel(),
495 // "Please refer to the error log.");
499 // // Stop the progress monitor.
500 // newMonitor.done();
503 IPostOperationEnabled postOperationEnabled
= operation
504 .getPostOperationEnabled();
505 if (postOperationEnabled
!= null) {
506 postOperationEnabled
.onComplete();
508 return Status
.OK_STATUS
;
513 * getOperationHistory
516 * @return a {@link org.eclipse.core.commands.operations.IOperationHistory}
519 public static IOperationHistory
getOperationHistory() {
520 return getWorkbench().getOperationSupport().getOperationHistory();
529 * a {@link java.lang.String} object.
531 public static void setStatusLine(final String message
) {
532 Display
.getDefault().asyncExec(new Runnable() {
535 statusLineManager
.setMessage(message
);
547 * @return a {@link org.eclipse.core.runtime.IProgressMonitor} object.
549 public static IProgressMonitor
getMonitor() {
550 statusLineManager
.setCancelEnabled(false);
551 return statusLineManager
.getProgressMonitor();
555 * Starts either the given {@link IProgressMonitor} if it's not
556 * <code>null</code> or a new {@link NullProgressMonitor}.
558 * @param progressMonitor
559 * The {@link IProgressMonitor} or <code>null</code> if no
560 * progress should be reported.
562 * The name of the main task.
564 * The number of steps this task is subdivided into.
565 * @return The {@link IProgressMonitor}.
567 public static IProgressMonitor
startMainMonitor(
568 IProgressMonitor progressMonitor
, String taskName
, int steps
) {
569 IProgressMonitor newMonitor
= progressMonitor
;
570 if (newMonitor
== null) {
571 newMonitor
= new NullProgressMonitor();
573 newMonitor
.beginTask(taskName
== null ?
"" : taskName
, steps
);
574 newMonitor
.subTask(" ");
579 * Creates a {@link SubProgressMonitor} if the given
580 * {@link IProgressMonitor} is not <code>null</code> and not a
581 * {@link NullProgressMonitor}.
583 * @param progressMonitor
584 * The parent {@link IProgressMonitor} of the
585 * {@link SubProgressMonitor} to be created.
587 * The number of steps this subtask is subdivided into. Must be a
588 * positive number and must not be
589 * {@link IProgressMonitor#UNKNOWN}.
590 * @return The {@link IProgressMonitor}.
592 public static IProgressMonitor
getSubProgressMonitor(
593 IProgressMonitor progressMonitor
, int ticks
) {
594 if (progressMonitor
== null) {
595 return new NullProgressMonitor();
597 if (progressMonitor
instanceof NullProgressMonitor
) {
598 return progressMonitor
;
601 return new SubProgressMonitor(progressMonitor
, ticks
);
605 * Checks whether the user canceled this operation. If not canceled, the
606 * given number of steps are declared as done.
609 * a {@link org.eclipse.core.runtime.IProgressMonitor} object.
613 public static void workedChecked(IProgressMonitor newMonitor
, int steps
) {
614 // In case the progress monitor was canceled throw an exception.
615 if (newMonitor
.isCanceled()) {
616 throw new OperationCanceledException();
618 // Otherwise declare this step as done.
619 newMonitor
.worked(steps
);
623 * Present a progress dialog to the user. This dialog will block the UI
626 * an implementation of {@link IRunnableWithProgress}
627 * @throws java.lang.InterruptedException
629 * @throws java.lang.reflect.InvocationTargetException
632 public static void busyCursorWhile(IRunnableWithProgress runnable
)
633 throws InvocationTargetException
, InterruptedException
{
634 getProgressService().busyCursorWhile(runnable
);
642 * @see {@link IProgressService#runInUI(org.eclipse.jface.operation.IRunnableContext, IRunnableWithProgress, ISchedulingRule)}
644 * a {@link org.eclipse.jface.operation.IRunnableWithProgress}
647 * a {@link org.eclipse.core.runtime.jobs.ISchedulingRule}
649 * @throws java.lang.reflect.InvocationTargetException
651 * @throws java.lang.InterruptedException
654 public static void runInUI(IRunnableWithProgress runnable
,
655 ISchedulingRule rule
) throws InvocationTargetException
,
656 InterruptedException
{
657 getProgressService().runInUI(getWorkbenchWindow(), runnable
, rule
);
670 * a {@link org.eclipse.jface.operation.IRunnableWithProgress}
672 * @throws java.lang.reflect.InvocationTargetException
674 * @throws java.lang.InterruptedException
677 public static void run(boolean fork
, boolean cancelable
,
678 IRunnableWithProgress runnable
) throws InvocationTargetException
,
679 InterruptedException
{
680 getProgressService().run(fork
, cancelable
, runnable
);
688 * @return a {@link org.eclipse.ui.progress.IProgressService} object.
690 public static IProgressService
getProgressService() {
691 IWorkbench workbench
= PlatformUI
.getWorkbench();
692 return workbench
.getProgressService();
697 * getProgressService2
700 * @return a {@link org.eclipse.ui.progress.IWorkbenchSiteProgressService}
703 public static IWorkbenchSiteProgressService
getProgressService2() {
704 return (IWorkbenchSiteProgressService
) getService(IWorkbenchSiteProgressService
.class);
713 * a {@link java.lang.String} object.
715 public static void info(String message
) {
716 IStatus status
= new Status(IStatus
.INFO
, getPluginId(), message
);
726 * a {@link org.eclipse.core.runtime.IStatus} object.
728 public static void info(IStatus status
) {
738 * a {@link java.lang.Class} object.
740 * a {@link java.lang.String} object.
742 public static void warn(Class source
, String message
) {
743 IStatus status
= new Status(IStatus
.WARNING
, getPluginId(), message
);
744 getLog4JLogger(source
).warn(message
);
748 public static void warn(Class source
, Throwable t
) {
749 IStatus status
= new Status(IStatus
.WARNING
, getPluginId(), t
.getMessage(), t
);
750 getLog4JLogger(source
).warn(t
);
760 * a {@link java.lang.Class} object.
762 * a {@link java.lang.Throwable} object.
764 public static void error(Class source
, Throwable t
) {
765 error(source
.getClass(), t
.getMessage(), t
);
774 * a {@link java.lang.Class} object.
776 * a {@link java.lang.String} object.
778 * a {@link java.lang.Throwable} object.
780 public static void error(Class source
, String message
, Throwable t
) {
781 IStatus status
= new Status(IStatus
.ERROR
, getPluginId(), message
, t
);
782 error(source
, status
);
791 * a {@link java.lang.Class} object.
793 * a {@link org.eclipse.core.runtime.IStatus} object.
795 public static void error(Class source
, IStatus status
) {
796 getLog4JLogger(source
)
797 .error(status
.getMessage(), status
.getException());
807 * a {@link java.lang.Class} object.
808 * @return a {@link org.apache.log4j.Logger} object.
810 public static Logger
getLog4JLogger(Class clazz
) {
811 return Logger
.getLogger(clazz
);
815 * @see {@link ILog#log(IStatus)}
819 private static void log(IStatus status
) {
820 TaxeditorStorePlugin
.getDefault().getLog().log(status
);
828 * @return a {@link java.lang.String} object.
830 protected static String
getPluginId() {
831 return "eu.taxeditor";
839 * @return a {@link org.eclipse.ui.IEditorPart} object.
841 public static IEditorPart
getActiveEditor() {
842 return getActivePage() != null ?
getActivePage().getActiveEditor()
851 * @return a {@link eu.etaxonomy.taxeditor.view.detail.DetailsViewPart}
854 public static DetailsViewPart
getDetailsView() {
855 return (DetailsViewPart
) getView(DetailsViewPart
.ID
, false);
860 * refreshDetailsViewer
863 public static void refreshDetailsViewer() {
864 if (getDetailsView() != null) {
865 ((AbstractCdmDataViewer
) getDetailsView().getViewer()).refresh();
871 * reflowDetailsViewer
874 public static void reflowDetailsViewer() {
875 if (getDetailsView() != null) {
876 ((AbstractCdmDataViewer
) getDetailsView().getViewer()).reflow();
880 public static SupplementalDataViewPart
getSupplementalDataView() {
881 return (SupplementalDataViewPart
) getView(SupplementalDataViewPart
.ID
,
885 public static void reflowSupplementalViewer() {
886 if (getSupplementalDataView() != null) {
887 ((AbstractCdmDataViewer
) getSupplementalDataView().getViewer())