Mercurial > projects > dwt-addons
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); + } /**