diff dwtx/jface/action/ExternalActionManager.d @ 70:46a6e0e6ccd4

Merge with d-fied sources of 3.4M7
author Frank Benoit <benoit@tionex.de>
date Thu, 22 May 2008 01:36:46 +0200
parents 7a3e6c1a4eae
children 4878bef4a38e
line wrap: on
line diff
--- a/dwtx/jface/action/ExternalActionManager.d	Mon May 19 13:41:06 2008 +0200
+++ b/dwtx/jface/action/ExternalActionManager.d	Thu May 22 01:36:46 2008 +0200
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -20,12 +20,18 @@
 import tango.util.collection.model.Map;
 import tango.util.collection.model.Set;
 
+import dwt.widgets.Event;
 import dwtx.core.commands.Command;
 import dwtx.core.commands.CommandEvent;
 import dwtx.core.commands.CommandManager;
+import dwtx.core.commands.ExecutionEvent;
+import dwtx.core.commands.ExecutionException;
 import dwtx.core.commands.ICommandListener;
+import dwtx.core.commands.NotEnabledException;
 import dwtx.core.commands.ParameterizedCommand;
+import dwtx.core.commands.common.NotDefinedException;
 import dwtx.core.runtime.IStatus;
+import dwtx.core.runtime.ListenerList;
 import dwtx.core.runtime.Status;
 import dwtx.jface.bindings.BindingManager;
 import dwtx.jface.bindings.BindingManagerEvent;
@@ -71,11 +77,14 @@
      * A simple implementation of the <code>ICallback</code> mechanism that
      * simply takes a <code>BindingManager</code> and a
      * <code>CommandManager</code>.
+     * <p>
+     * <b>Note:</b> this class is not intended to be subclassed by clients.
+     * </p>
      *
      * @since 3.1
      */
-    public static final class CommandCallback :
-            IBindingManagerListener, IBindingManagerCallback {
+    public static class CommandCallback :
+            IBindingManagerListener, IBindingManagerCallback, IExecuteCallback {
 
         /**
          * The internationalization bundle for text produced by this class.
@@ -86,6 +95,11 @@
          * The callback capable of responding to whether a command is active.
          */
         private const IActiveChecker activeChecker;
+        
+        /**
+         * Check the applicability of firing an execution event for an action.
+         */
+        private final IExecuteApplicable applicabilityChecker;
 
         /**
          * The binding manager for your application. Must not be
@@ -116,7 +130,8 @@
         /**
          * The list of listeners that have registered for property change
          * notification. This is a map of command identifiers (<code>String</code>)
-         * to listeners (<code>IPropertyChangeListener</code>).
+         * to listeners (<code>IPropertyChangeListener</code> or
+         * <code>ListenerList</code> of <code>IPropertyChangeListener</code>).
          */
         private const Map!(String,IPropertyChangeListener) registeredListeners;
 
@@ -144,9 +159,12 @@
                     return true;
                 }
 
+            }, new IExecuteApplicable() {
+                public bool isApplicable(IAction action) {
+                    return true;
+                }
             });
         }
-
         /**
          * Constructs a new instance of <code>CommandCallback</code> with the
          * workbench it should be using.
@@ -166,6 +184,36 @@
         public this(BindingManager bindingManager,
                 CommandManager commandManager,
                 IActiveChecker activeChecker) {
+            this(bindingManager, commandManager, activeChecker,
+                    new IExecuteApplicable() {
+                public bool isApplicable(IAction action) {
+                    return true;
+                }
+            });
+        }
+        /**
+         * Constructs a new instance of <code>CommandCallback</code> with the
+         * workbench it should be using.
+         * 
+         * @param bindingManager
+         *            The binding manager which will provide the callback; must
+         *            not be <code>null</code>.
+         * @param commandManager
+         *            The command manager which will provide the callback; must
+         *            not be <code>null</code>.
+         * @param activeChecker
+         *            The callback mechanism for checking whether a command is
+         *            active; must not be <code>null</code>.
+         * @param checker
+         *            The callback to check if an IAction should fire execution
+         *            events.
+         * 
+         * @since 3.4
+         */
+        public CommandCallback(final BindingManager bindingManager,
+                final CommandManager commandManager,
+                final IActiveChecker activeChecker,
+                final IExecuteApplicable checker) {
             loggedCommandIds = new HashSet!(String);
             registeredListeners = new HashMap!(String,IPropertyChangeListener);
             if (bindingManager is null) {
@@ -182,10 +230,15 @@
                 throw new NullPointerException(
                         "The callback needs an active callback"); //$NON-NLS-1$
             }
+            if (checker is null) {
+                throw new NullPointerException(
+                        "The callback needs an applicable callback"); //$NON-NLS-1$
+            }
 
             this.activeChecker = activeChecker;
             this.bindingManager = bindingManager;
             this.commandManager = commandManager;
+            this.applicabilityChecker = checker;
         }
 
         /**
@@ -194,7 +247,16 @@
          */
         public final void addPropertyChangeListener(String commandId,
                 IPropertyChangeListener listener) {
-            registeredListeners.add(commandId, listener);
+            Object existing = registeredListeners.get(commandId);
+            if (existing instanceof ListenerList) {
+                ((ListenerList) existing).add(listener);
+            } else if (existing !is null) {
+                ListenerList listeners = new ListenerList(ListenerList.IDENTITY);
+                listeners.add(existing);
+                listeners.add(listener);
+            } else {
+                registeredListeners.put(commandId, listener);
+            }
             if (!bindingManagerListenerAttached) {
                 bindingManager.addBindingManagerListener(this);
                 bindingManagerListenerAttached = true;
@@ -213,9 +275,19 @@
                     ParameterizedCommand parameterizedCommand = new ParameterizedCommand(
                             command, null);
                     if (event.isActiveBindingsChangedFor(parameterizedCommand)) {
-                        IPropertyChangeListener listener = cast(IPropertyChangeListener) v;
-                        listener.propertyChange(new PropertyChangeEvent(event
-                                .getManager(), IAction.TEXT, null, null));
+                        Object value = entry.getValue();
+                        PropertyChangeEvent propertyChangeEvent = new PropertyChangeEvent(event
+                                .getManager(), IAction.TEXT, null, null);
+                        if (value instanceof ListenerList) {
+                            Object[] listeners= ((ListenerList) value).getListeners();
+                            for (int i = 0; i < listeners.length; i++) {
+                                final IPropertyChangeListener listener = (IPropertyChangeListener) listeners[i];
+                                listener.propertyChange(propertyChangeEvent);
+                            }
+                        } else {
+                            final IPropertyChangeListener listener = (IPropertyChangeListener) value;
+                            listener.propertyChange(propertyChangeEvent);
+                        }
                     }
                 }
             }
@@ -343,16 +415,71 @@
          */
         public final void removePropertyChangeListener(String commandId,
                 IPropertyChangeListener listener) {
-            IPropertyChangeListener existingListener = cast(IPropertyChangeListener) registeredListeners
-                    .get(commandId);
-            if (existingListener is listener) {
+            Object existing= registeredListeners.get(commandId);
+            if (existing is listener) {
                 registeredListeners.removeKey(commandId);
                 if (registeredListeners.drained()) {
                     bindingManager.removeBindingManagerListener(this);
                     bindingManagerListenerAttached = false;
                 }
+            } else if (existing instanceof ListenerList) {
+                ListenerList existingList = (ListenerList) existing;
+                existingList.remove(listener);
+                if (existingList.size() is 1) {
+                    registeredListeners.put(commandId, existingList.getListeners()[0]);
+                }
             }
         }
+
+        public void preExecute(IAction action, Event event) {
+            String actionDefinitionId = action.getActionDefinitionId();
+            if (actionDefinitionIdisnull 
+                    || !applicabilityChecker.isApplicable(action)) {
+                return;
+            }
+            Command command = commandManager.getCommand(actionDefinitionId);
+            ExecutionEvent executionEvent = new ExecutionEvent(command,
+                    Collections.EMPTY_MAP, event, null);
+
+            commandManager.firePreExecute(actionDefinitionId, executionEvent);
+        }
+
+        public void postExecuteSuccess(IAction action, Object returnValue) {
+            String actionDefinitionId = action.getActionDefinitionId();
+            if (actionDefinitionIdisnull 
+                    || !applicabilityChecker.isApplicable(action)) {
+                return;
+            }
+            commandManager.firePostExecuteSuccess(actionDefinitionId, returnValue);
+        }
+
+        public void postExecuteFailure(IAction action,
+                ExecutionException exception) {
+            String actionDefinitionId = action.getActionDefinitionId();
+            if (actionDefinitionIdisnull 
+                    || !applicabilityChecker.isApplicable(action)) {
+                return;
+            }
+            commandManager.firePostExecuteFailure(actionDefinitionId, exception);
+        }
+
+        public void notDefined(IAction action, NotDefinedException exception) {
+            String actionDefinitionId = action.getActionDefinitionId();
+            if (actionDefinitionIdisnull 
+                    || !applicabilityChecker.isApplicable(action)) {
+                return;
+            }
+            commandManager.fireNotDefined(actionDefinitionId, exception);
+        }
+
+        public void notEnabled(IAction action, NotEnabledException exception) {
+            String actionDefinitionId = action.getActionDefinitionId();
+            if (actionDefinitionIdisnull 
+                    || !applicabilityChecker.isApplicable(action)) {
+                return;
+            }
+            commandManager.fireNotEnabled(actionDefinitionId, exception);
+        }
     }
 
     /**
@@ -406,6 +533,102 @@
          */
         public TriggerSequence[] getActiveBindingsFor(String commandId);
     }
+    
+    /**
+     * An overridable mechanism to filter certain IActions from the execution
+     * bridge.
+     * 
+     * @since 3.4
+     */
+    public static interface IExecuteApplicable {
+        /**
+         * Allow the callback to filter out actions that should not fire
+         * execution events.
+         * 
+         * @param action
+         *            The action with an actionDefinitionId
+         * @return true if this action should be considered.
+         */
+        public bool isApplicable(IAction action);
+    }
+    
+    /**
+     * <p>
+     * A callback for executing execution events. Allows
+     * <code>ActionContributionItems</code> to fire useful events.
+     * </p>
+     * <p>
+     * Clients must not implement this interface and must not extend.
+     * </p>
+     * 
+     * @since 3.4
+     * 
+     */
+    public static interface IExecuteCallback {
+        
+        /**
+         * Fires a <code>NotEnabledException</code> because the action was not
+         * enabled.
+         * 
+         * @param action
+         *          The action contribution that caused the exception,
+         *          never <code>null</code>.
+         * @param exception
+         *          The <code>NotEnabledException</code>, never <code>null</code>.
+         */
+        public void notEnabled(IAction action, NotEnabledException exception);
+
+        /**
+         * Fires a <code>NotDefinedException</code> because the action was not
+         * defined.
+         * 
+         * @param action
+         *          The action contribution that caused the exception,
+         *          never <code>null</code>.
+         * @param exception
+         *          The <code>NotDefinedException</code>, never <code>null</code>.
+         */
+        public void notDefined(IAction action, NotDefinedException exception);
+        
+        /**
+         * Fires an execution event before an action is run.
+         * 
+         * @param action
+         *            The action contribution that requires an
+         *            execution event to be fired. Cannot be <code>null</code>.
+         * @param e
+         *            The DWT Event, may be <code>null</code>.
+         * 
+         */
+        public void preExecute(IAction action,
+                Event e);
+        
+        /**
+         * Fires an execution event when the action returned a success.
+         * 
+         * @param action
+         *            The action contribution that requires an
+         *            execution event to be fired. Cannot be <code>null</code>.
+         * @param returnValue
+         *            The command's result, may be <code>null</code>.
+         * 
+         */
+        public void postExecuteSuccess(IAction action,
+                Object returnValue);
+        
+        /**
+         * Creates an <code>ExecutionException</code> when the action returned
+         * a failure.
+         * 
+         * @param action
+         *          The action contribution that caused the exception,
+         *          never <code>null</code>.
+         * @param exception
+         *          The <code>ExecutionException</code>, never <code>null</code>.
+         */
+        public void postExecuteFailure(IAction action,
+                ExecutionException exception);
+    }
 
     /**
      * A callback mechanism for some external tool to communicate extra
@@ -423,9 +646,8 @@
          * case of the Eclipse workbench, this is the command identifier.
          * </p>
          * <p>
-         * A single instance of the listener may only ever be associated with
-         * one identifier. Attempts to add the listener twice (without a removal
-         * in between) has undefined behaviour.
+         * Has no effect if an identical listener has already been added for
+         * the <code>identifier</code>.
          * </p>
          *
          * @param identifier
@@ -505,6 +727,7 @@
          */
         public void removePropertyChangeListener(String identifier,
                 IPropertyChangeListener listener);
+
     }
 
     /**