Started refactoring the ImageElement. Improved feedback when starting application...
[taxeditor.git] / taxeditor-store / src / main / java / eu / etaxonomy / taxeditor / model / AbstractUtility.java
index 3c7c03f4263f8cb6158402f86f48bd83c65119aa..aebc45ab737f91c346054e1ebc96b58a1e3a12f7 100644 (file)
 
 package eu.etaxonomy.taxeditor.model;
 
+import java.lang.reflect.InvocationTargetException;
+
 import org.apache.log4j.Logger;
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.commands.operations.IOperationHistory;
-import org.eclipse.core.commands.operations.IUndoableOperation;
+import org.eclipse.core.runtime.IAdaptable;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
 import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
 import org.eclipse.jface.action.IStatusLineManager;
 import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.jface.resource.ColorRegistry;
 import org.eclipse.jface.resource.FontRegistry;
+import org.eclipse.jface.window.ApplicationWindow;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IViewReference;
+import org.eclipse.ui.IWorkbench;
 import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.ui.PartInitException;
 import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.ide.undo.WorkspaceUndoUtil;
+import org.eclipse.ui.progress.IProgressService;
+import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
 import org.eclipse.ui.themes.ITheme;
 import org.eclipse.ui.themes.IThemeManager;
 
+import eu.etaxonomy.taxeditor.operations.AbstractPostOperation;
+import eu.etaxonomy.taxeditor.operations.IPostOperationEnabled;
 import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
 
 /**
@@ -51,18 +69,49 @@ public abstract class AbstractUtility {
        }
        
        public static IWorkbenchPage getActivePage(){
+               
                return TaxeditorStorePlugin.getDefault().getWorkbench()
                        .getActiveWorkbenchWindow().getActivePage();
        }
        
-       public static IViewPart getView(String id) throws PartInitException{
-               return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView(id);
+       public static IWorkbenchPart getActivePart(){
+               return getActivePage() != null ? getActivePage().getActivePart() : null;
+       }
+       
+       public static ApplicationWindow getWorkbenchWindow(){
+               if(TaxeditorStorePlugin.getDefault().getWorkbench().getWorkbenchWindowCount() > 1){
+                       throw new IllegalStateException("More than one workbench window");
+               }
+               return (ApplicationWindow) TaxeditorStorePlugin.getDefault().getWorkbench().getWorkbenchWindows()[0];
+       }
+       
+       public static IViewPart showView(String id){
+               try {
+                       return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView(id);
+               } catch (PartInitException e) {
+                       logger.error("Could not open view: " + id, e);
+                       throw new RuntimeException(e);
+               }
+       }
+       
+       public static void hideView(IViewPart view){
+               PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().hideView(view);
        }
        
+       public static IViewPart getView(String id, boolean restore){
+               IViewReference[] references = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getViewReferences();
+               for (IViewReference reference : references){
+                       if(reference.getId().equals(id)){
+                               return reference.getView(restore);
+                       }
+               }
+               return null;
+       }
+               
        public static boolean closeAll() {
                return getActivePage().closeAllEditors(true);
        }
-
+       
        /**
         * 
         * @param api
@@ -87,6 +136,10 @@ public abstract class AbstractUtility {
                return getCurrentTheme().getFontRegistry();
        }
        
+       public static Font getFont(String symbolicName){
+               return getFontRegistry().get(symbolicName);
+       }
+       
        /**
         * Color registered to the plugin may be obtained with the Eclipse themeing functionality.
         * Thus colors are editable by the user via Preferences->General->Appearance->Colors and Fonts
@@ -97,6 +150,15 @@ public abstract class AbstractUtility {
                return getCurrentTheme().getColorRegistry();
        }
        
+       /**
+        * 
+        * @param symbolicName
+        * @return
+        */
+       public static Color getColor(String symbolicName){
+               return getColorRegistry().get(symbolicName);
+       }
+       
        /**
         * Open a message box that informs the user about unimplemented functionality.
         * This method is for developer convenience.
@@ -105,29 +167,102 @@ public abstract class AbstractUtility {
                warningDialog("Not yet implemented", "This functionality is not yet implemented.");
        }
        
-       public static void warningDialog(String title, String message){
-               MessageDialog.openWarning(getShell(), title, message);
+       public static void informationDialog(final String title, final String message){
+               Display.getDefault().asyncExec(new Runnable(){
+
+                       public void run() {
+                               MessageDialog.openInformation(getShell(), title, message);
+                       }
+               });
+       }
+       
+       public static void warningDialog(final String title, final String message){
+               Display.getDefault().asyncExec(new Runnable(){
+
+                       public void run() {
+                               MessageDialog.openWarning(getShell(), title, message);
+                       }
+               });
        }
        
-       public static void errorDialog(String title, String message){
-               MessageDialog.openError(getShell(), title, message);
+       public static void errorDialog(final String title, final String message){
+               Display.getDefault().asyncExec(new Runnable(){
+
+                       public void run() {
+                               MessageDialog.openError(getShell(), title, message);
+                       }
+               });
+       }
+
+       public static boolean confirmDialog(String title, String message) {
+               return MessageDialog.openQuestion(getShell(), title, message);
        }
        
-       public static IStatus executeOperation(IUndoableOperation operation){
+       public static IStatus executeOperation(final AbstractPostOperation operation){
                if(getOperationHistory() == null){
-                       throw new IllegalArgumentException("Ther is no operation history for this context");
+                       throw new IllegalArgumentException("There is no operation history for this context");
                }
                
+               final IAdaptable uiInfoAdapter = WorkspaceUndoUtil.getUIInfoAdapter(getShell());
+               
+               
+               
+               IRunnableWithProgress runnable = new IRunnableWithProgress() {
+                       
+                       public void run(IProgressMonitor monitor) throws InvocationTargetException,
+                                       InterruptedException {
+                               monitor.beginTask(operation.getLabel(), 100);
+                               IStatus status;
+                               try {
+                                       status = getOperationHistory().execute(operation, monitor, uiInfoAdapter);
+                               } catch (ExecutionException e) {
+                                       throw new RuntimeException(e);
+                               }
+                               monitor.done();
+                       String statusString = status.equals(Status.OK_STATUS) ? "completed" : "cancelled";
+                               setStatusLine(operation.getLabel() + " " + statusString + ".");
+                               
+                       }
+               };
+               
                try {
-                       IStatus status = getOperationHistory().execute(operation, getMonitor(),
-                                                               WorkspaceUndoUtil.getUIInfoAdapter(getShell()));
-                       String statusString = status.equals(Status.OK_STATUS) ? "completed" : "cancelled";
-                       setStatusLine(operation.getLabel() + " " + statusString + ".");
-                       return status;
-               } catch (ExecutionException e) {
-                       logger.error("Error executing operation: " + operation.getLabel(), e);
+                       runInUI(runnable, null);
+               } catch (InvocationTargetException e) {
+                       throw new RuntimeException(e);
+               } catch (InterruptedException e) {
+                       throw new RuntimeException(e);
                }
-               return null;
+               
+//             // Start the main progress monitor.
+//        IProgressMonitor newMonitor = startMainMonitor(getMonitor(),operation.getLabel(), 100);
+//
+//             // Check whether operation was canceled and do some steps.
+//        workedChecked(newMonitor, 10);
+//
+//        try {
+//                     IStatus status = getOperationHistory().execute(operation, newMonitor,
+//                                     WorkspaceUndoUtil.getUIInfoAdapter(getShell()));
+//
+//                     // Check whether operation was canceled and do some steps.
+//                     workedChecked(newMonitor, 30);
+//
+//             String statusString = status.equals(Status.OK_STATUS) ? "completed" : "cancelled";
+//                     setStatusLine(operation.getLabel() + " " + statusString + ".");
+//
+//             return status;
+//             } catch (ExecutionException e) {
+//                     logger.error("Error executing operation: " + operation.getLabel(), e);
+//                     errorDialog("Error executing operation: " + operation.getLabel(), "Please refer to the error log.");
+//             }
+//        finally {
+//             
+//             // Stop the progress monitor.
+//            newMonitor.done();
+//        }
+               
+               IPostOperationEnabled postOperationEnabled = operation.getPostOperationEnabled();
+               postOperationEnabled.onComplete();
+               return Status.OK_STATUS;
        }
        
        public static IOperationHistory getOperationHistory(){
@@ -135,12 +270,97 @@ public abstract class AbstractUtility {
                                                        getOperationSupport().getOperationHistory();
        }
        
-       public static void setStatusLine(String message) {
-               statusLineManager.setMessage(message);
+       public static void setStatusLine(final String message) {
+               Display.getDefault().asyncExec(new Runnable(){
+
+                       public void run() {
+                               statusLineManager.setMessage(message);
+                       }
+                       
+               });
+               
        }
        
-       protected static IProgressMonitor getMonitor() {
+       public static IProgressMonitor getMonitor() {
                statusLineManager.setCancelEnabled(false);
                return statusLineManager.getProgressMonitor();
        }
+       
+       /**
+        * Starts either the given {@link IProgressMonitor} if it's not <code>null</code> or a new {@link NullProgressMonitor}.
+        * 
+        * @param progressMonitor The {@link IProgressMonitor} or <code>null</code> if no progress should be reported.
+        * @param taskName The name of the main task.
+        * @param steps The number of steps this task is subdivided into.
+        * @return The {@link IProgressMonitor}.
+        */
+    public static IProgressMonitor startMainMonitor(IProgressMonitor progressMonitor, String taskName, int steps) {
+        IProgressMonitor newMonitor = progressMonitor;
+        if (newMonitor == null) {
+            newMonitor = new NullProgressMonitor();
+        }
+        newMonitor.beginTask(taskName == null ? "" : taskName, steps);
+        newMonitor.subTask(" ");
+        return newMonitor;
+    }
+
+    /**
+     * Creates a {@link SubProgressMonitor} if the given {@link IProgressMonitor} is not <code>null</code> and not a {@link NullProgressMonitor}.
+        * @param progressMonitor The parent {@link IProgressMonitor} of the {@link SubProgressMonitor} to be created.
+     * @param ticks The number of steps this subtask is subdivided into. Must be a positive number and must not be {@link IProgressMonitor#UNKNOWN}.
+     * @return The {@link IProgressMonitor}.
+     */
+    public static IProgressMonitor getSubProgressMonitor(IProgressMonitor progressMonitor, int ticks) {
+        if (progressMonitor == null) {
+            return new NullProgressMonitor();
+        }
+        if (progressMonitor instanceof NullProgressMonitor) {
+            return progressMonitor;
+        }
+        
+        return new SubProgressMonitor(progressMonitor, ticks, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
+    }
+    
+       /**
+        * Checks whether the user canceled this operation. If not canceled, the given number of steps are declared as done.
+        * @param newMonitor
+        * @return 
+        */
+       public static void workedChecked(IProgressMonitor newMonitor, int steps) {
+               // In case the progress monitor was canceled throw an exception.
+               if (newMonitor.isCanceled()) {
+                       throw new OperationCanceledException();
+               }
+               // Otherwise declare this step as done.
+               newMonitor.worked(steps);
+       }
+
+       /**
+        * Present a progress dialog to the user. This dialog will block the UI
+        * 
+        * @param runnable an implementation of {@link IRunnableWithProgress}
+        * @throws InterruptedException 
+        * @throws InvocationTargetException 
+        */
+       public static void busyCursorWhile(IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException{
+               getProgressService().busyCursorWhile(runnable);
+       }
+       
+       public static void runInUI(IRunnableWithProgress runnable, ISchedulingRule rule) throws InvocationTargetException, InterruptedException{
+               getProgressService().runInUI(getWorkbenchWindow(), runnable, rule);             
+       }
+       
+       public static void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException{
+               getProgressService().run(fork, cancelable, runnable);
+       }
+       
+       public static IProgressService getProgressService(){
+               IWorkbench workbench = PlatformUI.getWorkbench();
+               return workbench.getProgressService();
+       }
+       
+       public static IWorkbenchSiteProgressService getProgressService2(){
+               return (IWorkbenchSiteProgressService) getService(IWorkbenchSiteProgressService.class);
+       }
+
 }