[kune-commits] r1110 - in trunk: . src/main/java/org/ourproject/kune/chat/server/managers src/main/java/org/ourproject/kune/platf/client/actions src/main/java/org/ourproject/kune/platf/client/actions/ui src/main/java/org/ourproject/kune/platf/client/errors src/main/java/org/ourproject/kune/platf/client/i18n src/main/java/org/ourproject/kune/platf/client/services src/main/java/org/ourproject/kune/platf/client/shortcuts src/main/java/org/ourproject/kune/platf/client/ui src/main/java/org/ourproject/kune/platf/client/ui/rte/insertmedia src/main/java/org/ourproject/kune/platf/server/domain src/main/java/org/ourproject/kune/platf/server/manager/file src/main/java/org/ourproject/kune/rack/filters/gwts

vjrj vjrj at ourproject.org
Wed May 13 15:53:20 CEST 2009


Author: vjrj
Date: 2009-05-13 15:53:01 +0200 (Wed, 13 May 2009)
New Revision: 1110

Added:
   trunk/src/main/java/org/ourproject/kune/platf/client/actions/AbstractAction.java
   trunk/src/main/java/org/ourproject/kune/platf/client/actions/Action.java
   trunk/src/main/java/org/ourproject/kune/platf/client/actions/ActionEvent.java
   trunk/src/main/java/org/ourproject/kune/platf/client/actions/ActionListener.java
   trunk/src/main/java/org/ourproject/kune/platf/client/actions/ActionMap.java
   trunk/src/main/java/org/ourproject/kune/platf/client/actions/EventListener.java
   trunk/src/main/java/org/ourproject/kune/platf/client/actions/EventListenerProxy.java
   trunk/src/main/java/org/ourproject/kune/platf/client/actions/InputMap.java
   trunk/src/main/java/org/ourproject/kune/platf/client/actions/KeyStroke.java
   trunk/src/main/java/org/ourproject/kune/platf/client/actions/PropertyChangeEvent.java
   trunk/src/main/java/org/ourproject/kune/platf/client/actions/PropertyChangeListener.java
   trunk/src/main/java/org/ourproject/kune/platf/client/actions/PropertyChangeListenerProxy.java
   trunk/src/main/java/org/ourproject/kune/platf/client/actions/PropertyChangeSupport.java
   trunk/src/main/java/org/ourproject/kune/platf/client/actions/ui/
   trunk/src/main/java/org/ourproject/kune/platf/client/actions/ui/AbstractButton.java
   trunk/src/main/java/org/ourproject/kune/platf/client/actions/ui/DefaultButton.java
   trunk/src/main/java/org/ourproject/kune/platf/client/actions/ui/TestButton.java
Modified:
   trunk/COPYRIGHT
   trunk/TODO
   trunk/src/main/java/org/ourproject/kune/chat/server/managers/ChatException.java
   trunk/src/main/java/org/ourproject/kune/platf/client/actions/ActionCollection.java
   trunk/src/main/java/org/ourproject/kune/platf/client/actions/ActionItemCollection.java
   trunk/src/main/java/org/ourproject/kune/platf/client/actions/BeforeActionCollection.java
   trunk/src/main/java/org/ourproject/kune/platf/client/errors/AccessViolationException.java
   trunk/src/main/java/org/ourproject/kune/platf/client/errors/AlreadyGroupMemberException.java
   trunk/src/main/java/org/ourproject/kune/platf/client/errors/AlreadyUserMemberException.java
   trunk/src/main/java/org/ourproject/kune/platf/client/errors/ContainerNotPermittedException.java
   trunk/src/main/java/org/ourproject/kune/platf/client/errors/ContentNotFoundException.java
   trunk/src/main/java/org/ourproject/kune/platf/client/errors/ContentNotPermittedException.java
   trunk/src/main/java/org/ourproject/kune/platf/client/errors/DefaultException.java
   trunk/src/main/java/org/ourproject/kune/platf/client/errors/EmailAddressInUseException.java
   trunk/src/main/java/org/ourproject/kune/platf/client/errors/GroupNameInUseException.java
   trunk/src/main/java/org/ourproject/kune/platf/client/errors/GroupNotFoundException.java
   trunk/src/main/java/org/ourproject/kune/platf/client/errors/I18nNotFoundException.java
   trunk/src/main/java/org/ourproject/kune/platf/client/errors/LastAdminInGroupException.java
   trunk/src/main/java/org/ourproject/kune/platf/client/errors/NameInUseException.java
   trunk/src/main/java/org/ourproject/kune/platf/client/errors/NameNotPermittedException.java
   trunk/src/main/java/org/ourproject/kune/platf/client/errors/NoDefaultContentException.java
   trunk/src/main/java/org/ourproject/kune/platf/client/errors/SessionExpiredException.java
   trunk/src/main/java/org/ourproject/kune/platf/client/errors/ToolNotFoundException.java
   trunk/src/main/java/org/ourproject/kune/platf/client/errors/UserAuthException.java
   trunk/src/main/java/org/ourproject/kune/platf/client/errors/UserMustBeLoggedException.java
   trunk/src/main/java/org/ourproject/kune/platf/client/errors/UserNotFoundException.java
   trunk/src/main/java/org/ourproject/kune/platf/client/i18n/I18nChangeListenerCollection.java
   trunk/src/main/java/org/ourproject/kune/platf/client/services/PlatformModule.java
   trunk/src/main/java/org/ourproject/kune/platf/client/shortcuts/Keyboard.java
   trunk/src/main/java/org/ourproject/kune/platf/client/ui/MenuItemCollection.java
   trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/insertmedia/ExternalMediaRegistry.java
   trunk/src/main/java/org/ourproject/kune/platf/server/domain/ChatUserParams.java
   trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/EntityLogoDownloadManager.java
   trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/EntityLogoUploadManager.java
   trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/FileDownloadManager.java
   trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/FileDownloadManagerUtils.java
   trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/FileJsonUploadManagerAbstract.java
   trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/FileUploadManager.java
   trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/FileUploadManagerAbstract.java
   trunk/src/main/java/org/ourproject/kune/rack/filters/gwts/DelegatedRemoteServlet.java
Log:
Incomplete - task New Action class (adapted from Classpath Swing classes) to replace ActionDescription

Modified: trunk/COPYRIGHT
===================================================================
--- trunk/COPYRIGHT	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/COPYRIGHT	2009-05-13 13:53:01 UTC (rev 1110)
@@ -121,10 +121,15 @@
    Copyright: (C) 2004 Fluendo S.L under GNU General Public License
 
 video embed dialog:
-	Some ideas and embeded video code from:
-	http://www.jovelstefan.de/embedded-video/ (GPL)
-  http://www.daburna.de/blog/2006/12/13/wordpress-video-plugin/
+   Some ideas and embeded video code from:
+   http://www.jovelstefan.de/embedded-video/ (GPL)
+   http://www.daburna.de/blog/2006/12/13/wordpress-video-plugin/
 
 some license description:
-    from Wikipedia
-    Copyright: under GFDL http://www.gnu.org/copyleft/fdl.html
+   from Wikipedia
+   Copyright: under GFDL http://www.gnu.org/copyleft/fdl.html
+
+some Action classes:
+   from GNU Classpath
+   Copyright: under GNU General Public License
+   http://www.gnu.org/licenses/gpl.html

Modified: trunk/TODO
===================================================================
--- trunk/TODO	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/TODO	2009-05-13 13:53:01 UTC (rev 1110)
@@ -152,6 +152,8 @@
 I am talking about, but I'm sure there is something to do.
 ** vjrj <v> Login: Follow incubation recomendations. See:
    http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/e8e14b16e57b266f
+   Also autocomplete user/passwordi (for browser store):
+   http://groups.google.fr/group/Google-Web-Toolkit/browse_thread/thread/2b2ce0b6aaa82461
 ** vjrj <v> kune debian package:
    Study fat jar + deb package:
    http://anydoby.com/fatjar/

Modified: trunk/src/main/java/org/ourproject/kune/chat/server/managers/ChatException.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/chat/server/managers/ChatException.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/chat/server/managers/ChatException.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -23,13 +23,13 @@
 
 public class ChatException extends RuntimeException {
 
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 3777046831841032482L;
 
+    public ChatException() {
+        super("");
+    }
+
     public ChatException(final XMPPException cause) {
         super(cause);
     }
-
-    public ChatException() {
-        super("");
-    }
 }

Added: trunk/src/main/java/org/ourproject/kune/platf/client/actions/AbstractAction.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/actions/AbstractAction.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/actions/AbstractAction.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -0,0 +1,252 @@
+/* AbstractAction.java --
+   Copyright (C) 2002, 2004, 2005, 2006  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package org.ourproject.kune.platf.client.actions;
+
+import java.util.HashMap;
+
+import com.google.gwt.libideas.resources.client.ImageResource;
+
+/**
+ * A base class for implementing the {@link Action} interface.
+ * 
+ * @author Andrew Selkirk
+ * @author Adapted version for GWT (C) The kune development team
+ */
+public abstract class AbstractAction implements Action {
+
+    /**
+     * A flag that indicates whether or not the action is enabled.
+     */
+    protected boolean enabled = true;
+
+    /**
+     * Provides support for property change event notification.
+     */
+    protected PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);
+
+    /**
+     * store
+     */
+    private final HashMap<String, Object> store = new HashMap<String, Object>();
+
+    /**
+     * Creates a new action with no properties set.
+     */
+    public AbstractAction() {
+        // Nothing to do.
+    }
+
+    /**
+     * Creates a new action with the specified name. The name is stored as a
+     * property with the key {@link Action#NAME}, and no other properties are
+     * initialised.
+     * 
+     * @param name
+     *            the name (<code>null</code> permitted).
+     */
+    public AbstractAction(final String name) {
+        putValue(NAME, name);
+    }
+
+    /**
+     * Creates a new action with the specified name and icon. The name is stored
+     * as a property with the key {@link Action#NAME}, the icon is stored as a
+     * property with the key {@link Action#SMALL_ICON}, and no other properties
+     * are initialised.
+     * 
+     * @param name
+     *            the name (<code>null</code> permitted).
+     * @param icon
+     *            the icon (<code>null</code> permitted).
+     */
+    public AbstractAction(final String name, final ImageResource icon) {
+        putValue(NAME, name);
+        putValue(SMALL_ICON, icon);
+    }
+
+    /**
+     * Registers a listener to receive {@link PropertyChangeEvent} notifications
+     * from this action.
+     * 
+     * @param listener
+     *            the listener.
+     * 
+     * @see #removePropertyChangeListener(PropertyChangeListener)
+     */
+    public void addPropertyChangeListener(final PropertyChangeListener listener) {
+        changeSupport.addPropertyChangeListener(listener);
+    }
+
+    /**
+     * Returns an array of the keys for the property values that have been
+     * defined via the {@link #putValue(String, Object)} method (or the class
+     * constructor).
+     * 
+     * @return An array of keys.
+     */
+    public Object[] getKeys() {
+        return store.keySet().toArray();
+    }
+
+    /**
+     * Returns all registered listeners.
+     * 
+     * @return An array of listeners.
+     * 
+     * @since 1.4
+     */
+    public PropertyChangeListener[] getPropertyChangeListeners() {
+        return changeSupport.getPropertyChangeListeners();
+    }
+
+    /**
+     * Returns the value associated with the specified key.
+     * 
+     * @param key
+     *            the key (not <code>null</code>).
+     * 
+     * @return The value associated with the specified key, or <code>null</code>
+     *         if the key is not found.
+     * 
+     * @see #putValue(String, Object)
+     */
+    public Object getValue(final String key) {
+        return store.get(key);
+    }
+
+    /**
+     * Returns the flag that indicates whether or not the action is enabled.
+     * 
+     * @return The flag.
+     * 
+     * @see #setEnabled(boolean)
+     */
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    /**
+     * Sets the value associated with the specified key and sends a
+     * {@link java.beans.PropertyChangeEvent} to all registered listeners. The
+     * standard keys are:
+     * <ul>
+     * <li>{@link #NAME}</li>
+     * <li>{@link #SHORT_DESCRIPTION}</li>
+     * <li>{@link #LONG_DESCRIPTION}</li>
+     * <li>{@link #SMALL_ICON}</li>
+     * <li>{@link #ACTION_COMMAND_KEY}</li>
+     * <li>{@link #ACCELERATOR_KEY}</li>
+     * <li>{@link #MNEMONIC_KEY}</li>
+     * </ul>
+     * Any existing value associated with the key will be overwritten.
+     * 
+     * @param key
+     *            the key (not <code>null</code>).
+     * @param value
+     *            the value (<code>null</code> permitted).
+     */
+    public void putValue(final String key, final Object value) {
+        Object old = getValue(key);
+        if ((old == null && value != null) || (old != null && !old.equals(value))) {
+            store.put(key, value);
+            firePropertyChange(key, old, value);
+        }
+    }
+
+    /**
+     * Deregisters a listener so that it no longer receives
+     * {@link PropertyChangeEvent} notifications from this action.
+     * 
+     * @param listener
+     *            the listener.
+     * 
+     * @see #addPropertyChangeListener(PropertyChangeListener)
+     */
+    public void removePropertyChangeListener(final PropertyChangeListener listener) {
+        changeSupport.removePropertyChangeListener(listener);
+    }
+
+    /**
+     * Sets the flag that indicates whether or not the action is enabled and, if
+     * the value of the flag changed from the previous setting, sends a
+     * {@link java.beans.PropertyChangeEvent} to all registered listeners (using
+     * the property name 'enabled').
+     * 
+     * @param enabled
+     *            the new flag value.
+     * 
+     * @see #isEnabled()
+     */
+    public void setEnabled(final boolean enabled) {
+        if (enabled != this.enabled) {
+            this.enabled = enabled;
+            firePropertyChange(ENABLED, !this.enabled, this.enabled);
+        }
+    }
+
+    /**
+     * Sends a {@link PropertyChangeEvent} for the named property to all
+     * registered listeners.
+     * 
+     * @param propertyName
+     *            the property name.
+     * @param oldValue
+     *            the old value of the property.
+     * @param newValue
+     *            the new value of the property.
+     */
+    protected void firePropertyChange(final String propertyName, final Object oldValue, final Object newValue) {
+        changeSupport.firePropertyChange(propertyName, oldValue, newValue);
+    }
+
+    /**
+     * Sends a {@link PropertyChangeEvent} for the named property to all
+     * registered listeners. This private method is called by the
+     * {@link #setEnabled(boolean)} method.
+     * 
+     * @param propertyName
+     *            the property name.
+     * @param oldValue
+     *            the old value of the property.
+     * @param newValue
+     *            the new value of the property.
+     */
+    private void firePropertyChange(final String propertyName, final boolean oldValue, final boolean newValue) {
+        changeSupport.firePropertyChange(propertyName, oldValue, newValue);
+    }
+}

Added: trunk/src/main/java/org/ourproject/kune/platf/client/actions/Action.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/actions/Action.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/actions/Action.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -0,0 +1,159 @@
+/* Action.java --
+   Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package org.ourproject.kune.platf.client.actions;
+
+/**
+ * Provides a convenient central point of control for some task that can be
+ * triggered by more than one control in a Swing user interface (for example, a
+ * menu item and a toolbar button).
+ * 
+ * @author Ronald Veldema (rveldema at cs.vu.nl)
+ * @author Adapted version for GWT (C) The kune development team
+ * @author Andrew Selkirk
+ */
+public interface Action extends ActionListener {
+
+    /**
+     * A key to access the default property for the action (this is not used).
+     */
+    String DEFAULT = "Default";
+
+    /**
+     * A key to access the long description for the action.
+     */
+    String LONG_DESCRIPTION = "LongDescription";
+
+    /**
+     * A key to access the name for the action.
+     */
+    String NAME = "Name";
+
+    /**
+     * A key to access the enabled property for the action.
+     */
+    String ENABLED = "enabled";
+
+    /**
+     * A key to access the short description for the action (the short
+     * description is typically used as the tool tip text).
+     */
+    String SHORT_DESCRIPTION = "ShortDescription";
+
+    /**
+     * A key to access the icon for the action.
+     */
+    String SMALL_ICON = "SmallIcon";
+
+    /**
+     * A key to access the KeyStroke used as the accelerator for the action.
+     */
+    String ACCELERATOR_KEY = "AcceleratorKey";
+
+    /**
+     * A key to access the action command string for the action.
+     */
+    String ACTION_COMMAND_KEY = "ActionCommandKey";
+
+    /**
+     * A key to access the mnemonic for the action.
+     */
+    String MNEMONIC_KEY = "MnemonicKey";
+
+    /**
+     * Registers a listener to receive notification whenever one of the action's
+     * properties is modified.
+     * 
+     * @param listener
+     *            the listener.
+     */
+    void addPropertyChangeListener(PropertyChangeListener listener);
+
+    /**
+     * Returns the value associated with the specified key.
+     * 
+     * @param key
+     *            the key (not <code>null</code>).
+     * 
+     * @return The value associated with the specified key, or <code>null</code>
+     *         if the key is not found.
+     */
+    Object getValue(String key);
+
+    /**
+     * Returns the flag that indicates whether or not this action is enabled.
+     * 
+     * @return The flag.
+     */
+    boolean isEnabled();
+
+    /**
+     * Sets the value associated with the specified key and sends a
+     * {@link PropertyChangeEvent} to all registered listeners. The standard
+     * keys are defined in this interface: {@link #NAME},
+     * {@link #SHORT_DESCRIPTION}, {@link #LONG_DESCRIPTION},
+     * {@link #SMALL_ICON}, {@link #ACTION_COMMAND_KEY},
+     * {@link #ACCELERATOR_KEY} and {@link #MNEMONIC_KEY}. Any existing value
+     * associated with the key will be overwritten.
+     * 
+     * @param key
+     *            the key (not <code>null</code>).
+     * @param value
+     *            the value (<code>null</code> permitted).
+     */
+    void putValue(String key, Object value);
+
+    /**
+     * Deregisters a listener so that it no longer receives notification of
+     * changes to the action's properties.
+     * 
+     * @param listener
+     *            the listener.
+     */
+    void removePropertyChangeListener(PropertyChangeListener listener);
+
+    /**
+     * Sets the flag that indicates whether or not this action is enabled. If
+     * the value changes, a {@link java.beans.PropertyChangeEvent} is sent to
+     * all registered listeners.
+     * 
+     * @param b
+     *            the new value of the flag.
+     */
+    void setEnabled(boolean b);
+
+} // Action

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/actions/ActionCollection.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/actions/ActionCollection.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/actions/ActionCollection.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -23,6 +23,6 @@
 
 public class ActionCollection<T> extends ArrayList<ActionDescriptor<T>> {
 
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = -3308296009308246636L;
 
 }

Added: trunk/src/main/java/org/ourproject/kune/platf/client/actions/ActionEvent.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/actions/ActionEvent.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/actions/ActionEvent.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -0,0 +1,193 @@
+/* ActionEvent.java -- an action has been triggered
+   Copyright (C) 1999, 2002, 2005  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package org.ourproject.kune.platf.client.actions;
+
+import com.google.gwt.user.client.ui.KeyboardListener;
+
+/**
+ * This event is generated when an action on a component (such as a button
+ * press) occurs.
+ * 
+ * @author Aaron M. Renn (arenn at urbanophile.com)
+ * @author Adapted version for GWT (C) The kune development team
+ * @see ActionListener
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public class ActionEvent {
+
+    /** Bit mask indicating the shift key was pressed. */
+    public static final int SHIFT_MASK = KeyboardListener.MODIFIER_SHIFT;
+
+    /** Bit mask indicating the control key was pressed. */
+    public static final int CTRL_MASK = KeyboardListener.MODIFIER_CTRL;
+
+    /** Bit mask indicating the that meta key was pressed. */
+    public static final int META_MASK = KeyboardListener.MODIFIER_META;
+
+    /** Bit mask indicating that the alt key was pressed. */
+    public static final int ALT_MASK = KeyboardListener.MODIFIER_ALT;
+
+    /** The first id number in the range of action id's. */
+    public static final int ACTION_FIRST = 1001;
+
+    /** The last id number in the range of action id's. */
+    public static final int ACTION_LAST = 1001;
+
+    /** An event id indicating that an action has occurred. */
+    public static final int ACTION_PERFORMED = 1001;
+
+    /**
+     * A nonlocalized string that gives more specific details of the event
+     * cause.
+     * 
+     * @see #getActionCommand()
+     * @serial the command for this event
+     */
+    private final String actionCommand;
+
+    /**
+     * The bitmask of the modifiers that were pressed during the action.
+     * 
+     * @see #getModifiers()
+     * @serial modifiers for this event
+     */
+    private final int modifiers;
+
+    /**
+     * The timestamp of this event; usually the same as the underlying input
+     * event.
+     * 
+     * @see #getWhen()
+     * @serial the timestamp of the event
+     * @since 1.4
+     */
+    private final long when;
+
+    private final int id;
+
+    /**
+     * Initializes a new instance of <code>ActionEvent</code> with the specified
+     * source, id, command, and modifiers, and timestamp. Note that an invalid
+     * id leads to unspecified results.
+     * 
+     * @param source
+     *            the event source
+     * @param id
+     *            the event id
+     * @param command
+     *            the command string for this action
+     * @param when
+     *            the timestamp of the event
+     * @param modifiers
+     *            the bitwise or of modifier keys down during the action
+     * @throws IllegalArgumentException
+     *             if source is null
+     * @since 1.4
+     */
+    public ActionEvent(final Object source, final int id, final String command, final long when, final int modifiers) {
+        super();
+        this.id = id;
+        actionCommand = command;
+        this.when = when;
+        this.modifiers = modifiers;
+    }
+
+    /**
+     * Returns the command string associated with this action.
+     * 
+     * @return the command string associated with this action
+     */
+    public String getActionCommand() {
+        return actionCommand;
+    }
+
+    /**
+     * Returns the keys held down during the action. This value will be a
+     * combination of the bit mask constants defined in this class, or 0 if no
+     * modifiers were pressed.
+     * 
+     * @return the modifier bits
+     */
+    public int getModifiers() {
+        return modifiers;
+    }
+
+    /**
+     * Gets the timestamp of when this action took place. Usually, this
+     * corresponds to the timestamp of the underlying InputEvent.
+     * 
+     * @return the timestamp of this action
+     * @since 1.4
+     */
+    public long getWhen() {
+        return when;
+    }
+
+    /**
+     * Returns a string that identifies the action event. This is in the format
+     * <code>"ACTION_PERFORMED,cmd=" + getActionCommand() + ",when=" + getWhen()
+     * + ",modifiers=" + &lt;modifier string&gt;</code>, where the modifier
+     * string is in the order "Meta", "Ctrl", "Alt", "Shift", "Alt Graph", and
+     * "Button1", separated by '+', according to the bits set in getModifiers().
+     * 
+     * @return a string identifying the event
+     */
+    public String paramString() {
+        String s = new String(id == ACTION_PERFORMED ? "ACTION_PERFORMED,cmd=" : "unknown type,cmd=");
+        s = s + actionCommand + ",when=" + when + ",modifiers";
+        if ((modifiers & META_MASK) != 0) {
+            s += "+Meta";
+        }
+        if ((modifiers & CTRL_MASK) != 0) {
+            s += "+Ctrl";
+        }
+        if ((modifiers & ALT_MASK) != 0) {
+            s += "+Alt";
+        }
+        if ((modifiers & SHIFT_MASK) != 0) {
+            s += "+Shift";
+        }
+        // if ((modifiers & InputEvent.ALT_GRAPH_MASK) != 0)
+        // s+="+Alt Graph");
+        // if ((modifiers & InputEvent.BUTTON1_MASK) != 0)
+        // s+="+Button1");
+        // s.setCharAt(len, '=');
+        return s;
+    }
+} // class ActionEvent

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/actions/ActionItemCollection.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/actions/ActionItemCollection.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/actions/ActionItemCollection.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -26,10 +26,10 @@
 
 public class ActionItemCollection<T> extends ArrayList<ActionItem<T>> {
 
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 1127359948648860754L;
 
     @Override
-    public boolean add(ActionItem<T> actionItem) {
+    public boolean add(final ActionItem<T> actionItem) {
         ActionDescriptor<T> action = actionItem.getAction();
         int position = action.getPosition();
         if (position == ActionDescriptor.NO_POSITION) {
@@ -47,7 +47,7 @@
     }
 
     @Override
-    public boolean addAll(Collection<? extends ActionItem<T>> actionItems) {
+    public boolean addAll(final Collection<? extends ActionItem<T>> actionItems) {
         for (ActionItem<T> actionItem : actionItems) {
             add(actionItem);
         }

Added: trunk/src/main/java/org/ourproject/kune/platf/client/actions/ActionListener.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/actions/ActionListener.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/actions/ActionListener.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -0,0 +1,57 @@
+/* ActionListener.java -- listens for action events
+   Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package org.ourproject.kune.platf.client.actions;
+
+/**
+ * This interface is for classes that listen for action events.
+ * 
+ * @author Aaron M. Renn (arenn at urbanophile.com)
+ * @author Adapted version for GWT (C) The kune development team
+ * @see ActionEvent
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public interface ActionListener extends EventListener {
+    /**
+     * This method is invoked when an action occurs.
+     * 
+     * @param event
+     *            the <code>ActionEvent</code> that occurred
+     */
+    void actionPerformed(ActionEvent event);
+}

Added: trunk/src/main/java/org/ourproject/kune/platf/client/actions/ActionMap.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/actions/ActionMap.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/actions/ActionMap.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -0,0 +1,192 @@
+/* ActionMap.java --
+   Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package org.ourproject.kune.platf.client.actions;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Maps arbitrary keys (usually Strings) to {@link Action} instances. This is
+ * used in combination with {@link InputMap}s.
+ * 
+ * If a component receives an input event, this is looked up in the component's
+ * <code>InputMap</code>. The result is an object which serves as a key to the
+ * components <code>ActionMap</code>. Finally the <code>Action</code> that is
+ * stored is executed.
+ * 
+ * @author Andrew Selkirk
+ * @author Adapted version for GWT (C) The kune development team
+ * @author Michael Koch
+ */
+public class ActionMap {
+
+    /**
+     * actionMap
+     */
+    private final Map<Object, Action> actionMap = new HashMap<Object, Action>();
+
+    /**
+     * parent
+     */
+    private ActionMap parent;
+
+    /**
+     * Creates a new <code>ActionMap</code> instance.
+     */
+    public ActionMap() {
+        // Nothing to do here.
+    }
+
+    /**
+     * Returns all keys of entries in this <code>ActionMap</code> and all its
+     * parents.
+     * 
+     * @return an array of keys
+     */
+    public Object[] allKeys() {
+        Set<Object> set = new HashSet<Object>();
+
+        if (parent != null) {
+            set.addAll(Arrays.asList(parent.allKeys()));
+        }
+
+        set.addAll(actionMap.keySet());
+        if (set.size() != 0) {
+            return set.toArray();
+        }
+        return null;
+    }
+
+    /**
+     * Clears the <code>ActionMap</code>.
+     */
+    public void clear() {
+        actionMap.clear();
+    }
+
+    /**
+     * Returns an action associated with an object.
+     * 
+     * @param key
+     *            the key of the enty
+     * 
+     * @return the action associated with key, may be null
+     */
+    public Action get(final Object key) {
+        Object result = actionMap.get(key);
+
+        if (result == null && parent != null) {
+            result = parent.get(key);
+        }
+
+        return (Action) result;
+    }
+
+    /**
+     * Returns the parent of this <code>ActionMap</code>.
+     * 
+     * @return the parent, may be null.
+     */
+    public ActionMap getParent() {
+        return parent;
+    }
+
+    /**
+     * Returns all keys of entries in this <code>ActionMap</code>.
+     * 
+     * @return an array of keys
+     */
+    public Object[] keys() {
+        if (size() != 0) {
+            return actionMap.keySet().toArray();
+        }
+        return null;
+    }
+
+    /**
+     * Puts a new <code>Action</code> into the <code>ActionMap</code>. If action
+     * is null an existing entry will be removed.
+     * 
+     * @param key
+     *            the key for the entry
+     * @param action
+     *            the action.
+     */
+    public void put(final Object key, final Action action) {
+        if (action == null) {
+            actionMap.remove(key);
+        } else {
+            actionMap.put(key, action);
+        }
+    }
+
+    /**
+     * Remove an entry from the <code>ActionMap</code>.
+     * 
+     * @param key
+     *            the key of the entry to remove
+     */
+    public void remove(final Object key) {
+        actionMap.remove(key);
+    }
+
+    /**
+     * Sets a parent for this <code>ActionMap</code>.
+     * 
+     * @param parentMap
+     *            the new parent
+     */
+    public void setParent(final ActionMap parentMap) {
+        if (parentMap != this) {
+            parent = parentMap;
+        }
+    }
+
+    /**
+     * Returns the number of entries in this <code>ActionMap</code>.
+     * 
+     * @return the number of entries
+     */
+    public int size() {
+        return actionMap.size();
+    }
+
+}

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/actions/BeforeActionCollection.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/actions/BeforeActionCollection.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/actions/BeforeActionCollection.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -26,7 +26,7 @@
  */
 public class BeforeActionCollection extends ArrayList<BeforeActionListener> {
 
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = -1508664709628420137L;
 
     /**
      * Check before action listeners.

Added: trunk/src/main/java/org/ourproject/kune/platf/client/actions/EventListener.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/actions/EventListener.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/actions/EventListener.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -0,0 +1,53 @@
+/* EventListener.java -- tagging interface for all event listeners
+   Copyright (C) 1998, 1999, 2001, 2002, 2005  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package org.ourproject.kune.platf.client.actions;
+
+/**
+ * Empty interface that is implemented by classes that need to receive events.
+ * Subinterfaces define methods that can be called to fire an event
+ * notification. Normally the name of these subinterfaces end in
+ * <code>Listener</code> and all method described by the subinterface take as
+ * argument an subclass of <code>EventObject</code>.
+ * 
+ * @author Tom Tromey (tromey at cygnus.com)
+ * @author Adapted version for GWT (C) The kune development team
+ * @see EventObject
+ * @status updated to 1.4
+ */
+public interface EventListener {
+}

Added: trunk/src/main/java/org/ourproject/kune/platf/client/actions/EventListenerProxy.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/actions/EventListenerProxy.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/actions/EventListenerProxy.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -0,0 +1,74 @@
+/* EventListenerProxy.java -- abstract wrapper for event listeners
+   Copyright (C) 2002, 2005  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package org.ourproject.kune.platf.client.actions;
+
+/**
+ * An abstract wrapper for event listeners. This allows subclasses to attach
+ * additional parameters to an existing event listener to create a new one.
+ * Subclasses are expected to add methods to set and retrieve any attached
+ * properties.
+ * 
+ * @author Eric Blake (ebb9 at email.byu.edu)
+ * @author Adapted version for GWT (C) The kune development team
+ * 
+ * @since 1.4
+ * @status updated to 1.4
+ */
+public abstract class EventListenerProxy implements EventListener {
+    /** The listener that this proxy wraps. */
+    private final EventListener listener;
+
+    /**
+     * Construct a proxy event listener, given an existing one to augment.
+     * 
+     * @param listener
+     *            the listener to wrap
+     */
+    public EventListenerProxy(final EventListener listener) {
+        this.listener = listener;
+    }
+
+    /**
+     * Return the wrapped event listener.
+     * 
+     * @return the listener associated with this proxy
+     */
+    public EventListener getListener() {
+        return listener;
+    }
+} // class EventListenerProxy

Added: trunk/src/main/java/org/ourproject/kune/platf/client/actions/InputMap.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/actions/InputMap.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/actions/InputMap.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -0,0 +1,234 @@
+/* InputMap.java --
+   Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package org.ourproject.kune.platf.client.actions;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Maps {@link KeyStroke}s to arbitrary objects, usually Strings. This is used
+ * in combination with {@link ActionMap}s.
+ * 
+ * If a component receives an input event, this is looked up in the component's
+ * <code>InputMap</code>. The result is an object which serves as a key to the
+ * component's <code>ActionMap</code>. Finally the <code>Action</code> that is
+ * stored is executed.
+ * 
+ * @author Andrew Selkirk
+ * @author Michael Koch
+ * @author Adapted version for GWT (C) The kune development team
+ * 
+ * @since 1.3
+ */
+public class InputMap {
+
+    /**
+     * Storage for the KeyStroke --> Object mappings.
+     */
+    private Map<KeyStroke, Action> inputMap;
+
+    /**
+     * An optional parent map.
+     */
+    private InputMap parent;
+
+    /**
+     * Creates a new <code>InputMap</code> instance. This default instance
+     * contains no mappings and has no parent.
+     */
+    public InputMap() {
+        // nothing to do
+    }
+
+    /**
+     * Returns all keys of entries in this <code>InputMap</code> and all its
+     * parents.
+     * 
+     * @return An array of keys (may be <code>null</code> or have zero length).
+     */
+    public KeyStroke[] allKeys() {
+        Set<KeyStroke> set = new HashSet<KeyStroke>();
+
+        if (parent != null) {
+            KeyStroke[] parentKeys = parent.allKeys();
+            if (parentKeys != null) {
+                set.addAll(Arrays.asList(parentKeys));
+            }
+        }
+        if (inputMap != null) {
+            set.addAll(inputMap.keySet());
+        }
+        if (set.size() == 0) {
+            return null;
+        }
+        KeyStroke[] array = new KeyStroke[set.size()];
+        return set.toArray(array);
+    }
+
+    /**
+     * Clears the entries from this <code>InputMap</code>. The parent map, if
+     * there is one, is not cleared.
+     */
+    public void clear() {
+        if (inputMap != null) {
+            inputMap.clear();
+        }
+    }
+
+    /**
+     * Returns the binding for the specified keystroke, if there is one.
+     * 
+     * @param keystroke
+     *            the key of the entry (<code>null</code> is ignored).
+     * 
+     * @return The binding associated with the specified keystroke (or
+     *         <code>null</code>).
+     */
+    public Object get(final KeyStroke keystroke) {
+        Object result = null;
+        if (inputMap != null) {
+            result = inputMap.get(keystroke);
+        }
+
+        if (result == null && parent != null) {
+            result = parent.get(keystroke);
+        }
+        return result;
+    }
+
+    /**
+     * Returns the parent of this <code>InputMap</code>. The default value is
+     * <code>null</code>.
+     * 
+     * @return The parent map (possibly <code>null</code>).
+     * 
+     * @see #setParent(InputMap)
+     */
+    public InputMap getParent() {
+        return parent;
+    }
+
+    /**
+     * Returns all keys of entries in this <code>InputMap</code>. This does not
+     * include keys defined in the parent, if there is one (use the
+     * {@link #allKeys()} method for that case). <br>
+     * <br>
+     * Following the behaviour of the reference implementation, this method will
+     * return <code>null</code> when no entries have been added to the map, and
+     * a zero length array if entries have been added but subsequently removed
+     * (or cleared) from the map.
+     * 
+     * @return An array of keys (may be <code>null</code> or have zero length).
+     */
+    public KeyStroke[] keys() {
+        if (inputMap != null) {
+            KeyStroke[] array = new KeyStroke[size()];
+            return inputMap.keySet().toArray(array);
+        }
+        return null;
+    }
+
+    /**
+     * Puts a new entry into the <code>InputMap</code>. If
+     * <code>actionMapKey</code> is <code>null</code> any existing entry will be
+     * removed.
+     * 
+     * @param keystroke
+     *            the keystroke for the entry (<code>null</code> is ignored).
+     * @param actionMapKey
+     *            the action (<code>null</code> permitted).
+     */
+    public void put(final KeyStroke keystroke, final Action actionMapKey) {
+        if (keystroke == null) {
+            return;
+        }
+        if (inputMap == null) {
+            inputMap = new HashMap<KeyStroke, Action>();
+        }
+        if (actionMapKey == null) {
+            inputMap.remove(keystroke);
+        } else {
+            inputMap.put(keystroke, actionMapKey);
+        }
+    }
+
+    /**
+     * Removes an entry from this <code>InputMap</code>. Note that this will not
+     * remove any entry from the parent map, if there is one.
+     * 
+     * @param keystroke
+     *            the key of the entry to remove (<code>null</code> is ignored).
+     */
+    public void remove(final KeyStroke keystroke) {
+        if (inputMap != null) {
+            inputMap.remove(keystroke);
+        }
+    }
+
+    /**
+     * Sets a parent for this <code>InputMap</code>. If a parent is specified,
+     * the {@link #get(KeyStroke)} method will look in the parent if it cannot
+     * find an entry in this map.
+     * 
+     * @param parentMap
+     *            the new parent (<code>null</code> permitted).
+     * 
+     * @see #getParent()
+     */
+    public void setParent(final InputMap parentMap) {
+        parent = parentMap;
+    }
+
+    /**
+     * Returns the number of entries in this <code>InputMap</code>. This count
+     * does not include any entries from the parent map, if there is one.
+     * 
+     * @return The number of entries.
+     */
+    public int size() {
+        int result = 0;
+        if (inputMap != null) {
+            result = inputMap.size();
+        }
+        return result;
+    }
+
+}

Added: trunk/src/main/java/org/ourproject/kune/platf/client/actions/KeyStroke.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/actions/KeyStroke.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/actions/KeyStroke.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -0,0 +1,518 @@
+/* AWTKeyStroke.java -- an immutable key stroke
+   Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package org.ourproject.kune.platf.client.actions;
+
+import java.util.HashMap;
+
+import org.ourproject.kune.platf.client.i18n.Resources;
+import org.ourproject.kune.platf.client.shortcuts.Keyboard;
+
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.ui.KeyboardListener;
+import com.google.gwt.user.client.ui.KeyboardListenerCollection;
+
+/**
+ * This class mirrors KeyEvents, representing both low-level key presses and key
+ * releases, and high level key typed inputs. However, this class forms
+ * immutable strokes, and can be efficiently reused via the factory methods for
+ * creating them.
+ * 
+ * <p>
+ * For backwards compatibility with Swing, this supports a way to build
+ * instances of a subclass, using reflection, provided the subclass has a no-arg
+ * constructor (of any accessibility).
+ * 
+ * @author Eric Blake (ebb9 at email.byu.edu)
+ * @author Andrew John Hughes (gnu_andrew at member.fsf.org)
+ * @author Adapted version for GWT (C) The kune development team
+ * @see #getKeyStroke(char)
+ * @since 1.4
+ * @status updated to 1.4
+ */
+public class KeyStroke {
+
+    /**
+     * The cache of recently created keystrokes. This maps KeyStrokes to
+     * KeyStrokes in a cache which removes the least recently accessed entry,
+     * under the assumption that garbage collection of a new keystroke is easy
+     * when we find the old one that it matches in the cache.
+     */
+    private static final HashMap<KeyStroke, KeyStroke> cache = new HashMap<KeyStroke, KeyStroke>();
+
+    /** The most recently generated keystroke, or null. */
+    private static KeyStroke recent;
+
+    /**
+     * A table of keyCode names to values. This is package-private to avoid an
+     * accessor method.
+     * 
+     * @see #getKeyStroke(String)
+     */
+    static final HashMap<String, Object> vktable = new HashMap<String, Object>();
+
+    private static final int VK_UNDEFINED = 0;
+    private static final char CHAR_UNDEFINED = '\uffff';
+
+    /**
+     * Returns a keystroke representing a typed character.
+     * 
+     * @param keyChar
+     *            the typed character
+     * @return the specified keystroke
+     */
+    public static KeyStroke getKeyStroke(final char keyChar) {
+        return getKeyStroke(keyChar, VK_UNDEFINED, 0, false);
+    }
+
+    /**
+     * Returns a keystroke representing a typed character with the given
+     * modifiers. Note that keyChar is a <code>Character</code> instead of a
+     * <code>char</code> to avoid accidental ambiguity with
+     * <code>getKeyStroke(int, int)</code>. The modifiers are the bitwise or of
+     * the masks found in InputEvent; the new style (*_DOWN_MASK) is preferred,
+     * but the old style will work.
+     * 
+     * @param keyChar
+     *            the typed character
+     * @param modifiers
+     *            the modifiers, or 0
+     * @return the specified keystroke
+     * @throws IllegalArgumentException
+     *             if keyChar is null
+     */
+    public static KeyStroke getKeyStroke(final Character keyChar, final int modifiers) {
+        if (keyChar == null) {
+            throw new IllegalArgumentException();
+        }
+        return getKeyStroke(keyChar.charValue(), VK_UNDEFINED, modifiers, false);
+    }
+
+    /**
+     * Returns a keystroke representing a pressed key event, with the given
+     * modifiers. The "virtual key" should be one of the VK_* constants in
+     * {@link KeyEvent}. The modifiers are the bitwise or of the masks found in
+     * InputEvent; the new style (*_DOWN_MASK) is preferred, but the old style
+     * will work.
+     * 
+     * @param keyCode
+     *            the virtual key
+     * @param modifiers
+     *            the modifiers, or 0
+     * @return the specified keystroke
+     */
+    public static KeyStroke getKeyStroke(final int keyCode, final int modifiers) {
+        return getKeyStroke(CHAR_UNDEFINED, keyCode, modifiers, false);
+    }
+
+    /**
+     * Returns a keystroke representing a pressed or released key event, with
+     * the given modifiers. The "virtual key" should be one of the VK_*
+     * constants in {@link KeyEvent}. The modifiers are the bitwise or of the
+     * masks found in InputEvent; the new style (*_DOWN_MASK) is preferred, but
+     * the old style will work.
+     * 
+     * @param keyCode
+     *            the virtual key
+     * @param modifiers
+     *            the modifiers, or 0
+     * @param release
+     *            true if this is a key release instead of a key press
+     * @return the specified keystroke
+     */
+    public static KeyStroke getKeyStroke(final int keyCode, final int modifiers, final boolean release) {
+        return getKeyStroke(CHAR_UNDEFINED, keyCode, modifiers, release);
+    }
+
+    /**
+     * Returns a keystroke representing what caused the key event.
+     * 
+     * @param event
+     *            the key event to convert
+     * @return the specified keystroke, or null if the event is invalid
+     * @throws NullPointerException
+     *             if event is null
+     */
+    public static KeyStroke getKeyStrokeForEvent(final Event event) {
+        switch (DOM.eventGetType(event)) {
+        case Event.ONKEYDOWN:
+            return getKeyStroke((char) event.getKeyCode(), VK_UNDEFINED,
+                    KeyboardListenerCollection.getKeyboardModifiers(event), false);
+        case Event.ONKEYPRESS:
+            return getKeyStroke(CHAR_UNDEFINED, event.getKeyCode(),
+                    KeyboardListenerCollection.getKeyboardModifiers(event), false);
+        case Event.ONKEYUP:
+            return getKeyStroke(CHAR_UNDEFINED, event.getKeyCode(),
+                    KeyboardListenerCollection.getKeyboardModifiers(event), true);
+        default:
+            return null;
+        }
+    }
+
+    /**
+     * Gets the appropriate keystroke, creating one if necessary.
+     * 
+     * @param keyChar
+     *            the keyChar
+     * @param keyCode
+     *            the keyCode
+     * @param modifiers
+     *            the modifiers
+     * @param release
+     *            true for key release
+     * @return the specified keystroke
+     */
+    private static KeyStroke getKeyStroke(final char keyChar, final int keyCode, final int modifiers,
+            final boolean release) {
+        // Check level 0 cache.
+        KeyStroke stroke = recent; // Avoid thread races.
+        if (stroke != null && stroke.keyChar == keyChar && stroke.keyCode == keyCode && stroke.modifiers == modifiers
+                && stroke.onKeyRelease == release) {
+            return stroke;
+        }
+        stroke = new KeyStroke(keyChar, keyCode, modifiers, release);
+        // Check level 1 cache.
+        KeyStroke cached = cache.get(stroke);
+        if (cached == null) {
+            cache.put(stroke, stroke);
+        } else {
+            stroke = cached;
+        }
+        return recent = stroke;
+    }
+
+    /**
+     * The typed character, or CHAR_UNDEFINED for key presses and releases.
+     * 
+     * @serial the keyChar
+     */
+    private final char keyChar;
+
+    /**
+     * The virtual key code, or VK_UNDEFINED for key typed. Package visible for
+     * use by Component.
+     * 
+     * @serial the keyCode
+     */
+    int keyCode;
+
+    /**
+     * The modifiers in effect. To match Sun, this stores the old style masks
+     * for shift, control, alt, meta, and alt-graph (but not button1); as well
+     * as the new style of extended modifiers for all modifiers.
+     * 
+     * @serial bitwise or of the *_DOWN_MASK modifiers
+     */
+    private int modifiers;
+
+    /**
+     * True if this is a key release; should only be true if keyChar is
+     * CHAR_UNDEFINED.
+     * 
+     * @serial true to distinguish key pressed from key released
+     */
+    private boolean onKeyRelease;
+
+    /**
+     * Construct a keystroke with default values: it will be interpreted as a
+     * key typed event with an invalid character and no modifiers. Client code
+     * should use the factory methods instead.
+     * 
+     * @see #getKeyStroke(char)
+     * @see #getKeyStroke(Character, int)
+     * @see #getKeyStroke(int, int, boolean)
+     * @see #getKeyStroke(int, int)
+     * @see #getKeyStrokeForEvent(KeyEvent)
+     * @see #getKeyStroke(String)
+     */
+    protected KeyStroke() {
+        keyChar = CHAR_UNDEFINED;
+    }
+
+    /**
+     * Construct a keystroke with the given values. Client code should use the
+     * factory methods instead.
+     * 
+     * @param keyChar
+     *            the character entered, if this is a key typed
+     * @param keyCode
+     *            the key pressed or released, or VK_UNDEFINED for key typed
+     * @param modifiers
+     *            the modifier keys for the keystroke, in old or new style
+     * @param onKeyRelease
+     *            true if this is a key release instead of a press
+     * @see #getKeyStroke(char)
+     * @see #getKeyStroke(Character, int)
+     * @see #getKeyStroke(int, int, boolean)
+     * @see #getKeyStroke(int, int)
+     * @see #getKeyStrokeForEvent(KeyEvent)
+     * @see #getKeyStroke(String)
+     */
+    protected KeyStroke(final char keyChar, final int keyCode, final int modifiers, final boolean onKeyRelease) {
+        this.keyChar = keyChar;
+        this.keyCode = keyCode;
+        // No need to call extend(), as only trusted code calls this
+        // constructor.
+        this.modifiers = modifiers;
+        this.onKeyRelease = onKeyRelease;
+    }
+
+    /**
+     * Tests two keystrokes for equality.
+     * 
+     * @param o
+     *            the object to test
+     * @return true if it is equal
+     */
+    @Override
+    public final boolean equals(final Object o) {
+        if (!(o instanceof KeyStroke)) {
+            return false;
+        }
+        KeyStroke s = (KeyStroke) o;
+        return this == o
+                || (keyChar == s.keyChar && keyCode == s.keyCode && modifiers == s.modifiers && onKeyRelease == s.onKeyRelease);
+    }
+
+    /**
+     * Returns the character of this keystroke, if it was typed.
+     * 
+     * @return the character value, or CHAR_UNDEFINED
+     * @see #getKeyStroke(char)
+     */
+    public final char getKeyChar() {
+        return keyChar;
+    }
+
+    /**
+     * Returns the virtual key code of this keystroke, if it was pressed or
+     * released. This will be a VK_* constant from KeyEvent.
+     * 
+     * @return the virtual key code value, or VK_UNDEFINED
+     * @see #getKeyStroke(int, int)
+     */
+    public final int getKeyCode() {
+        return keyCode;
+    }
+
+    /**
+     * Returns the AWT event type of this keystroke. This is one of
+     * {@link KeyEvent#KEY_TYPED}, {@link KeyEvent#KEY_PRESSED}, or
+     * {@link KeyEvent#KEY_RELEASED}.
+     * 
+     * @return the key event type
+     */
+    public final int getKeyEventType() {
+        return keyCode == VK_UNDEFINED ? Event.ONKEYDOWN : onKeyRelease ? Event.ONKEYUP : Event.ONKEYPRESS;
+    }
+
+    @SuppressWarnings("deprecation")
+    public String getKeyText(final int keyCode) {
+        switch (keyCode) {
+        case KeyboardListener.KEY_BACKSPACE:
+            return translateKey("Backspace");
+            // case KeyboardListener.KEY_DELETE:
+            // return translateKey("Delete");
+        case KeyboardListener.KEY_DOWN:
+            return translateKey("Down");
+        case KeyboardListener.KEY_END:
+            return translateKey("End");
+        case KeyboardListener.KEY_ENTER:
+            return translateKey("Enter");
+        case KeyboardListener.KEY_ESCAPE:
+            return translateKey("Escape");
+        case KeyboardListener.KEY_HOME:
+            return translateKey("Home");
+        case KeyboardListener.KEY_LEFT:
+            return translateKey("Left");
+        case KeyboardListener.KEY_PAGEDOWN:
+            return translateKey("Page Down");
+        case KeyboardListener.KEY_PAGEUP:
+            return translateKey("Page Up");
+        case KeyboardListener.KEY_RIGHT:
+            return translateKey("Right");
+        case KeyboardListener.KEY_TAB:
+            return translateKey("Tab");
+        case KeyboardListener.KEY_UP:
+            return translateKey("Up");
+        case Keyboard.KEY_F1:
+        case Keyboard.KEY_F2:
+        case Keyboard.KEY_F3:
+        case Keyboard.KEY_F4:
+        case Keyboard.KEY_F5:
+        case Keyboard.KEY_F6:
+        case Keyboard.KEY_F7:
+        case Keyboard.KEY_F8:
+        case Keyboard.KEY_F9:
+        case Keyboard.KEY_F10:
+        case Keyboard.KEY_F11:
+        case Keyboard.KEY_F12:
+            return translateKey("F" + (keyCode - (Keyboard.KEY_F1 - 1)));
+        case Keyboard.KEY_COMMA:
+        case Keyboard.KEY_PERIOD:
+        case Keyboard.KEY_SLASH:
+        case Keyboard.KEY_0:
+        case Keyboard.KEY_1:
+        case Keyboard.KEY_2:
+        case Keyboard.KEY_3:
+        case Keyboard.KEY_4:
+        case Keyboard.KEY_5:
+        case Keyboard.KEY_6:
+        case Keyboard.KEY_7:
+        case Keyboard.KEY_8:
+        case Keyboard.KEY_9:
+        case Keyboard.KEY_SEMICOLON:
+        case Keyboard.KEY_EQUALS:
+        case Keyboard.KEY_A:
+        case Keyboard.KEY_B:
+        case Keyboard.KEY_C:
+        case Keyboard.KEY_D:
+        case Keyboard.KEY_E:
+        case Keyboard.KEY_F:
+        case Keyboard.KEY_G:
+        case Keyboard.KEY_H:
+        case Keyboard.KEY_I:
+        case Keyboard.KEY_J:
+        case Keyboard.KEY_K:
+        case Keyboard.KEY_L:
+        case Keyboard.KEY_M:
+        case Keyboard.KEY_N:
+        case Keyboard.KEY_O:
+        case Keyboard.KEY_P:
+        case Keyboard.KEY_Q:
+        case Keyboard.KEY_R:
+        case Keyboard.KEY_S:
+        case Keyboard.KEY_T:
+        case Keyboard.KEY_U:
+        case Keyboard.KEY_V:
+        case Keyboard.KEY_W:
+        case Keyboard.KEY_X:
+        case Keyboard.KEY_Y:
+        case Keyboard.KEY_Z:
+        case Keyboard.KEY_OPEN_BRACKET:
+        case Keyboard.KEY_BACK_SLASH:
+        case Keyboard.KEY_CLOSE_BRACKET:
+            return ("" + (char) keyCode).toUpperCase();
+        default:
+            return "Unknown keyCode: 0x" + (keyCode < 0 ? "-" : "") + Integer.toHexString(Math.abs(keyCode));
+        }
+    }
+
+    /**
+     * Returns the modifiers for this keystroke. This will be a bitwise or of
+     * constants from InputEvent; it includes the old style masks for shift,
+     * control, alt, meta, and alt-graph (but not button1); as well as the new
+     * style of extended modifiers for all modifiers.
+     * 
+     * @return the modifiers
+     * @see #getKeyStroke(Character, int)
+     * @see #getKeyStroke(int, int)
+     */
+    public final int getModifiers() {
+        return modifiers;
+    }
+
+    /**
+     * Returns a hashcode for this key event. It is not documented, but appears
+     * to be: <code>(getKeyChar() + 1) * (getKeyCode() + 1)
+     * * (getModifiers() + 1) * 2 + (isOnKeyRelease() ? 1 : 2)</code>.
+     * 
+     * @return the hashcode
+     */
+    @Override
+    public int hashCode() {
+        return (keyChar + 1) * (keyCode + 1) * (modifiers + 1) * 2 + (onKeyRelease ? 1 : 2);
+    }
+
+    /**
+     * Tests if this keystroke is a key release.
+     * 
+     * @return true if this is a key release
+     * @see #getKeyStroke(int, int, boolean)
+     */
+    public final boolean isOnKeyRelease() {
+        return onKeyRelease;
+    }
+
+    @Override
+    public String toString() {
+        String s = " (";
+        if ((modifiers & KeyboardListener.MODIFIER_META) != 0) {
+            s += translateKey("Meta") + "+";
+        }
+        if ((modifiers & KeyboardListener.MODIFIER_CTRL) != 0) {
+            s += translateKey("Ctrl") + "+";
+        }
+        if ((modifiers & KeyboardListener.MODIFIER_ALT) != 0) {
+            s += translateKey("Alt") + "+";
+        }
+        if ((modifiers & KeyboardListener.MODIFIER_SHIFT) != 0) {
+            s += translateKey("Shift") + "+";
+        }
+        if ((modifiers & Event.BUTTON_LEFT) != 0) {
+            s += translateKey("Button1") + "+";
+        }
+        if ((modifiers & Event.BUTTON_RIGHT) != 0) {
+            s += translateKey("Button2") + "+";
+        }
+        if ((modifiers & Event.BUTTON_MIDDLE) != 0) {
+            s += translateKey("Button3") + "+";
+        }
+        s += getKeyText(keyCode) + ")";
+        return s;
+    }
+
+    /**
+     * Returns a cached version of the deserialized keystroke, if available.
+     * 
+     * @return a cached replacement if something goes wrong
+     */
+    protected Object readResolve() {
+        KeyStroke s = cache.get(this);
+        if (s != null) {
+            return s;
+        }
+        cache.put(this, this);
+        return this;
+    }
+
+    private String translateKey(final String keyNameToTranslate) {
+        return Resources.i18n.tWithNT(keyNameToTranslate, "The '" + keyNameToTranslate + "' keyboard key");
+    }
+
+} // class KeyStroke

Added: trunk/src/main/java/org/ourproject/kune/platf/client/actions/PropertyChangeEvent.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/actions/PropertyChangeEvent.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/actions/PropertyChangeEvent.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -0,0 +1,185 @@
+/* PropertyChangeEvent.java -- describes a change in a property
+   Copyright (C) 1998, 2000, 2002, 2005  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package org.ourproject.kune.platf.client.actions;
+
+/**
+ * PropertyChangeEvents are fired in the PropertyChange and VetoableChange event
+ * classes. They represent the old and new values as well as the source Bean. If
+ * the old or new value is a primitive type, it must be wrapped in the
+ * appropriate wrapper type (java.lang.Integer for int, etc., etc.).
+ * 
+ * <p>
+ * If the old or new values are unknown (although why that would be I do not
+ * know), they may be null. Also, if the set of properties itself has changed,
+ * the name should be null, and the old and new values may also be null. Right
+ * now Sun put in a propagationId, reserved for future use. Read the comments on
+ * the constructor and on setPropagationId for more information.
+ * 
+ * @author John Keiser
+ * @author Eric Blake (ebb9 at email.byu.edu)
+ * @author Adapted version for GWT (C) The kune development team
+ * @since 1.1
+ * @status udpated to 1.4
+ */
+public class PropertyChangeEvent {
+
+    /**
+     * The name of the property that changed, may be null. Package visible for
+     * use by PropertyChangeSupport.
+     * 
+     * @serial the changed property name
+     */
+    final String propertyName;
+
+    /**
+     * The new value of the property, may be null. Package visible for use by
+     * PropertyChangeSupport.
+     * 
+     * @serial the new property value
+     */
+    final Object newValue;
+
+    /**
+     * The old value of the property, may be null. Package visible for use by
+     * PropertyChangeSupport.
+     * 
+     * @serial the old property value
+     */
+    final Object oldValue;
+
+    /**
+     * The propagation ID, reserved for future use. May be null.
+     * 
+     * @see #getPropagationId()
+     * @serial the Propagation ID
+     */
+    private Object propagationId;
+
+    private final Object source;
+
+    /**
+     * Create a new PropertyChangeEvent. Remember that if you received a
+     * PropertyChangeEvent and are sending a new one, you should also set the
+     * propagation ID from the old PropertyChangeEvent.
+     * 
+     * @param source
+     *            the Bean containing the property
+     * @param propertyName
+     *            the property's name
+     * @param oldVal
+     *            the old value of the property
+     * @param newVal
+     *            the new value of the property
+     * @throws IllegalArgumentException
+     *             if source is null
+     */
+    public PropertyChangeEvent(final Object source, final String propertyName, final Object oldVal, final Object newVal) {
+        this.source = source;
+        this.propertyName = propertyName;
+        this.oldValue = oldVal;
+        this.newValue = newVal;
+    }
+
+    /**
+     * Get the property's new value. May be null if multiple properties changed.
+     * 
+     * @return the property's new value
+     */
+    public Object getNewValue() {
+        return newValue;
+    }
+
+    /**
+     * Get the property's old value. May be null if multiple properties changed.
+     * 
+     * @return the property's old value
+     */
+    public Object getOldValue() {
+        return oldValue;
+    }
+
+    /**
+     * Get the propagation ID. Right now, it is not used for anything.
+     * 
+     * @return the propagation ID
+     * @see #setPropagationId(Object)
+     */
+    public Object getPropagationId() {
+        return propagationId;
+    }
+
+    /**
+     * Get the property name. May be null if multiple properties changed.
+     * 
+     * @return the property name
+     */
+    public String getPropertyName() {
+        return propertyName;
+    }
+
+    public Object getSource() {
+        return source;
+    }
+
+    /**
+     * Set the propagation ID. This is a way for the event to be passed from
+     * hand to hand and retain a little extra state. Right now it is unused, but
+     * it should be propagated anyway so that future versions of JavaBeans can
+     * use it, for God knows what.
+     * 
+     * @param propagationId
+     *            the propagation ID
+     * @see #getPropagationId()
+     */
+    public void setPropagationId(final Object propagationId) {
+        this.propagationId = propagationId;
+    }
+
+    /**
+     * Utility method to rollback a change.
+     * 
+     * @param event
+     *            the event to rollback
+     * @return a new event with old and new swapped
+     */
+    PropertyChangeEvent rollback() {
+        PropertyChangeEvent result = new PropertyChangeEvent(source, propertyName, newValue, oldValue);
+        result.propagationId = propagationId;
+        return result;
+    }
+} // class PropertyChangeEvent

Added: trunk/src/main/java/org/ourproject/kune/platf/client/actions/PropertyChangeListener.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/actions/PropertyChangeListener.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/actions/PropertyChangeListener.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -0,0 +1,58 @@
+/* PropertyChangeListener.java -- listen for changes in a bound property
+   Copyright (C) 1998, 2000, 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package org.ourproject.kune.platf.client.actions;
+
+/**
+ * PropertyChangeListener allows a class to monitor properties of a Bean for
+ * changes. A propertyChange() event will only be fired <em>after</em> the
+ * property has changed.
+ * 
+ * @author John Keiser
+ * @author Adapted version for GWT (C) The kune development team
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public interface PropertyChangeListener extends EventListener {
+    /**
+     * Fired after a Bean's property has changed.
+     * 
+     * @param e
+     *            the change (containing the old and new values)
+     */
+    void propertyChange(PropertyChangeEvent e);
+} // interface PropertyChangeListener

Added: trunk/src/main/java/org/ourproject/kune/platf/client/actions/PropertyChangeListenerProxy.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/actions/PropertyChangeListenerProxy.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/actions/PropertyChangeListenerProxy.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -0,0 +1,99 @@
+/* PropertyChangeListenerProxy.java -- adds a name to a property listener
+   Copyright (C) 2002, 2005  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package org.ourproject.kune.platf.client.actions;
+
+/**
+ * This class provides an extension to <code>PropertyChangeListener</code> -
+ * associating a name with the listener. This can be used to filter the changes
+ * that one is interested in.
+ * 
+ * @author Eric Blake (ebb9 at email.byu.edu)
+ * @author Adapted version for GWT (C) The kune development team
+ * @since 1.4
+ * @status udpated to 1.4
+ */
+public class PropertyChangeListenerProxy extends EventListenerProxy implements PropertyChangeListener {
+    /**
+     * The name of the property to listen for. Package visible for use by
+     * PropertyChangeSupport.
+     */
+    final String propertyName;
+
+    /**
+     * Create a new proxy which filters property change events and only passes
+     * changes to the named property on to the delegate. A null propertyName or
+     * listener does not fail now, but may cause a NullPointerException down the
+     * road.
+     * 
+     * @param propertyName
+     *            the property's name to filter on
+     * @param listener
+     *            the delegate listener
+     */
+    public PropertyChangeListenerProxy(final String propertyName, final PropertyChangeListener listener) {
+        super(listener);
+        this.propertyName = propertyName;
+    }
+
+    /**
+     * Gets the name of the property this proxy is filtering on.
+     * 
+     * @return the property name
+     */
+    public String getPropertyName() {
+        return propertyName;
+    }
+
+    /**
+     * Forwards the event on to the delegate if the property name matches.
+     * 
+     * @param event
+     *            the event to pass on, if it meets the filter
+     * @throws NullPointerException
+     *             if the delegate this was created with is null
+     */
+    public void propertyChange(final PropertyChangeEvent event) {
+        // Note: Sun does not filter, under the assumption that since
+        // PropertyChangeSupport unwraps proxys, this method should never be
+        // called by normal use of listeners.
+        String name = event == null ? null : event.getPropertyName();
+        if (name == null ? propertyName == null : name.equals(propertyName)) {
+            ((PropertyChangeListener) getListener()).propertyChange(event);
+        }
+    }
+} // class PropertyChangeListenerProxy

Added: trunk/src/main/java/org/ourproject/kune/platf/client/actions/PropertyChangeSupport.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/actions/PropertyChangeSupport.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/actions/PropertyChangeSupport.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -0,0 +1,436 @@
+/* PropertyChangeSupport.java -- support to manage property change listeners
+   Copyright (C) 1998, 1999, 2000, 2002, 2005, 2006
+   Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package org.ourproject.kune.platf.client.actions;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Vector;
+import java.util.Map.Entry;
+
+/**
+ * PropertyChangeSupport makes it easy to fire property change events and handle
+ * listeners. It allows chaining of listeners, as well as filtering by property
+ * name. In addition, it will serialize only those listeners which are
+ * serializable, ignoring the others without problem. This class is thread-safe.
+ * 
+ * @author John Keiser
+ * @author Eric Blake (ebb9 at email.byu.edu)
+ * @author Adapted version for GWT (C) The kune development team
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public class PropertyChangeSupport {
+
+    /**
+     * Maps property names (String) to named listeners (PropertyChangeSupport).
+     * If this is a child instance, this field will be null.
+     * 
+     * @serial the map of property names to named listener managers
+     * @since 1.2
+     */
+    private HashMap<String, PropertyChangeSupport> children;
+
+    /**
+     * The non-null source object for any generated events.
+     * 
+     * @serial the event source
+     */
+    private final Object source;
+
+    /**
+     * The list of all registered property listeners. If this instance was
+     * created by user code, this only holds the global listeners (ie. not tied
+     * to a name), and may be null. If it was created by this class, as a helper
+     * for named properties, then this vector will be non-null, and this
+     * instance appears as a value in the <code>children</code> hashtable of
+     * another instance, so that the listeners are tied to the key of that
+     * hashtable entry.
+     */
+    private Vector<PropertyChangeListener> listeners;
+
+    /**
+     * Create a PropertyChangeSupport to work with a specific source bean.
+     * 
+     * @param source
+     *            the source bean to use
+     * @throws NullPointerException
+     *             if source is null
+     */
+    public PropertyChangeSupport(final Object source) {
+        this.source = source;
+        if (source == null) {
+            throw new NullPointerException();
+        }
+    }
+
+    /**
+     * Adds a PropertyChangeListener to the list of global listeners. All
+     * property change events will be sent to this listener. The listener add is
+     * not unique: that is, <em>n</em> adds with the same listener will result
+     * in <em>n</em> events being sent to that listener for every property
+     * change. Adding a null listener is silently ignored. This method will
+     * unwrap a PropertyChangeListenerProxy, registering the underlying delegate
+     * to the named property list.
+     * 
+     * @param l
+     *            the listener to add
+     */
+    public void addPropertyChangeListener(final PropertyChangeListener l) {
+        if (l == null) {
+            return;
+        }
+
+        if (l instanceof PropertyChangeListenerProxy) {
+            PropertyChangeListenerProxy p = (PropertyChangeListenerProxy) l;
+            addPropertyChangeListener(p.propertyName, (PropertyChangeListener) p.getListener());
+        } else {
+            if (listeners == null) {
+                listeners = new Vector<PropertyChangeListener>();
+            }
+            listeners.add(l);
+        }
+    }
+
+    /**
+     * Adds a PropertyChangeListener listening on the specified property. Events
+     * will be sent to the listener only if the property name matches. The
+     * listener add is not unique; that is, <em>n</em> adds on a particular
+     * property for a particular listener will result in <em>n</em> events being
+     * sent to that listener when that property is changed. The effect is
+     * cumulative, too; if you are registered to listen to receive events on all
+     * property changes, and then you register on a particular property, you
+     * will receive change events for that property twice. Adding a null
+     * listener is silently ignored. This method will unwrap a
+     * PropertyChangeListenerProxy, registering the underlying delegate to the
+     * named property list if the names match, and discarding it otherwise.
+     * 
+     * @param propertyName
+     *            the name of the property to listen on
+     * @param l
+     *            the listener to add
+     * @throws NullPointerException
+     *             if propertyName is null
+     */
+    public void addPropertyChangeListener(final String propertyName, PropertyChangeListener l) {
+        if (l == null) {
+            return;
+        }
+
+        while (l instanceof PropertyChangeListenerProxy) {
+            PropertyChangeListenerProxy p = (PropertyChangeListenerProxy) l;
+            if (propertyName == null ? p.propertyName != null : !propertyName.equals(p.propertyName)) {
+                return;
+            }
+            l = (PropertyChangeListener) p.getListener();
+        }
+        PropertyChangeSupport s = null;
+        if (children == null) {
+            children = new HashMap<String, PropertyChangeSupport>();
+        } else {
+            s = children.get(propertyName);
+        }
+        if (s == null) {
+            s = new PropertyChangeSupport(source);
+            s.listeners = new Vector<PropertyChangeListener>();
+            children.put(propertyName, s);
+        }
+        s.listeners.add(l);
+    }
+
+    /**
+     * Fire an indexed property change event. This will only fire an event if
+     * the old and new values are not equal.
+     * 
+     * @param name
+     *            the name of the property which changed
+     * @param index
+     *            the index of the property which changed
+     * @param oldValue
+     *            the old value of the property
+     * @param newValue
+     *            the new value of the property
+     * @since 1.5
+     */
+    public void fireIndexedPropertyChange(final String name, final int index, final boolean oldValue,
+            final boolean newValue) {
+        if (oldValue != newValue) {
+            fireIndexedPropertyChange(name, index, Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
+        }
+    }
+
+    /**
+     * Fire an indexed property change event. This will only fire an event if
+     * the old and new values are not equal.
+     * 
+     * @param name
+     *            the name of the property which changed
+     * @param index
+     *            the index of the property which changed
+     * @param oldValue
+     *            the old value of the property
+     * @param newValue
+     *            the new value of the property
+     * @since 1.5
+     */
+    public void fireIndexedPropertyChange(final String name, final int index, final int oldValue, final int newValue) {
+        if (oldValue != newValue) {
+            fireIndexedPropertyChange(name, index, Integer.valueOf(oldValue), Integer.valueOf(newValue));
+        }
+    }
+
+    /**
+     * Fire a PropertyChangeEvent to all the global listeners, and to all the
+     * listeners for the specified property name. This does nothing if old and
+     * new values of the event are equal.
+     * 
+     * @param event
+     *            the event to fire
+     * @throws NullPointerException
+     *             if event is null
+     */
+    public void firePropertyChange(final PropertyChangeEvent event) {
+        if (event.oldValue != null && event.oldValue.equals(event.newValue)) {
+            return;
+        }
+        Vector<PropertyChangeListener> v = listeners; // Be thread-safe.
+        if (v != null) {
+            int i = v.size();
+            while (--i >= 0) {
+                (v.get(i)).propertyChange(event);
+            }
+        }
+        HashMap<String, PropertyChangeSupport> h = children; // Be
+        // thread-safe.
+        if (h != null && event.propertyName != null) {
+            PropertyChangeSupport s = h.get(event.propertyName);
+            if (s != null) {
+                v = s.listeners; // Be thread-safe.
+                int i = v == null ? 0 : v.size();
+                while (--i >= 0) {
+                    (v.get(i)).propertyChange(event);
+                }
+            }
+        }
+    }
+
+    /**
+     * Fire a PropertyChangeEvent containing the old and new values of the
+     * property to all the global listeners, and to all the listeners for the
+     * specified property name. This does nothing if old and new are equal.
+     * 
+     * @param propertyName
+     *            the name of the property that changed
+     * @param oldVal
+     *            the old value
+     * @param newVal
+     *            the new value
+     */
+    public void firePropertyChange(final String propertyName, final boolean oldVal, final boolean newVal) {
+        if (oldVal != newVal) {
+            firePropertyChange(new PropertyChangeEvent(source, propertyName, Boolean.valueOf(oldVal),
+                    Boolean.valueOf(newVal)));
+        }
+    }
+
+    /**
+     * Fire a PropertyChangeEvent containing the old and new values of the
+     * property to all the global listeners, and to all the listeners for the
+     * specified property name. This does nothing if old and new are equal.
+     * 
+     * @param propertyName
+     *            the name of the property that changed
+     * @param oldVal
+     *            the old value
+     * @param newVal
+     *            the new value
+     */
+    public void firePropertyChange(final String propertyName, final int oldVal, final int newVal) {
+        if (oldVal != newVal) {
+            firePropertyChange(new PropertyChangeEvent(source, propertyName, Integer.valueOf(oldVal),
+                    Integer.valueOf(newVal)));
+        }
+    }
+
+    /**
+     * Fire a PropertyChangeEvent containing the old and new values of the
+     * property to all the global listeners, and to all the listeners for the
+     * specified property name. This does nothing if old and new are non-null
+     * and equal.
+     * 
+     * @param propertyName
+     *            the name of the property that changed
+     * @param oldVal
+     *            the old value
+     * @param newVal
+     *            the new value
+     */
+    public void firePropertyChange(final String propertyName, final Object oldVal, final Object newVal) {
+        firePropertyChange(new PropertyChangeEvent(source, propertyName, oldVal, newVal));
+    }
+
+    /**
+     * Returns an array of all registered property change listeners. Those that
+     * were registered under a name will be wrapped in a
+     * <code>PropertyChangeListenerProxy</code>, so you must check whether the
+     * listener is an instance of the proxy class in order to see what name the
+     * real listener is registered under. If there are no registered listeners,
+     * this returns an empty array.
+     * 
+     * @return the array of registered listeners
+     * @see PropertyChangeListenerProxy
+     * @since 1.4
+     */
+    public PropertyChangeListener[] getPropertyChangeListeners() {
+        ArrayList<PropertyChangeListener> list = new ArrayList<PropertyChangeListener>();
+        if (listeners != null) {
+            list.addAll(listeners);
+        }
+        if (children != null) {
+            int i = children.size();
+            Iterator<Entry<String, PropertyChangeSupport>> iter = children.entrySet().iterator();
+            while (--i >= 0) {
+                Entry<String, PropertyChangeSupport> e = iter.next();
+                String name = e.getKey();
+                Vector<PropertyChangeListener> v = (e.getValue()).listeners;
+                int j = v.size();
+                while (--j >= 0) {
+                    list.add(new PropertyChangeListenerProxy(name, v.get(j)));
+                }
+            }
+        }
+        return list.toArray(new PropertyChangeListener[list.size()]);
+    }
+
+    /**
+     * Returns an array of all property change listeners registered under the
+     * given property name. If there are no registered listeners, or
+     * propertyName is null, this returns an empty array.
+     * 
+     * @return the array of registered listeners
+     * @since 1.4
+     */
+    public PropertyChangeListener[] getPropertyChangeListeners(final String propertyName) {
+        if (children == null || propertyName == null) {
+            return new PropertyChangeListener[0];
+        }
+        PropertyChangeSupport s = children.get(propertyName);
+        if (s == null) {
+            return new PropertyChangeListener[0];
+        }
+        return s.listeners.toArray(new PropertyChangeListener[s.listeners.size()]);
+    }
+
+    /**
+     * Tell whether the specified property is being listened on or not. This
+     * will only return <code>true</code> if there are listeners on all
+     * properties or if there is a listener specifically on this property.
+     * 
+     * @param propertyName
+     *            the property that may be listened on
+     * @return whether the property is being listened on
+     */
+    public boolean hasListeners(final String propertyName) {
+        return listeners != null || (children != null && children.get(propertyName) != null);
+    }
+
+    /**
+     * Removes a PropertyChangeListener from the list of global listeners. If
+     * any specific properties are being listened on, they must be deregistered
+     * by themselves; this will only remove the general listener to all
+     * properties. If <code>add()</code> has been called multiple times for a
+     * particular listener, <code>remove()</code> will have to be called the
+     * same number of times to deregister it. This method will unwrap a
+     * PropertyChangeListenerProxy, removing the underlying delegate from the
+     * named property list.
+     * 
+     * @param l
+     *            the listener to remove
+     */
+    public void removePropertyChangeListener(final PropertyChangeListener l) {
+        if (l instanceof PropertyChangeListenerProxy) {
+            PropertyChangeListenerProxy p = (PropertyChangeListenerProxy) l;
+            removePropertyChangeListener(p.propertyName, (PropertyChangeListener) p.getListener());
+        } else if (listeners != null) {
+            listeners.remove(l);
+            if (listeners.isEmpty()) {
+                listeners = null;
+            }
+        }
+    }
+
+    /**
+     * Removes a PropertyChangeListener from listening to a specific property.
+     * If <code>add()</code> has been called multiple times for a particular
+     * listener on a property, <code>remove()</code> will have to be called the
+     * same number of times to deregister it. This method will unwrap a
+     * PropertyChangeListenerProxy, removing the underlying delegate from the
+     * named property list if the names match.
+     * 
+     * @param propertyName
+     *            the property to stop listening on
+     * @param l
+     *            the listener to remove
+     * @throws NullPointerException
+     *             if propertyName is null
+     */
+    public void removePropertyChangeListener(final String propertyName, PropertyChangeListener l) {
+        if (children == null) {
+            return;
+        }
+        PropertyChangeSupport s = children.get(propertyName);
+        if (s == null) {
+            return;
+        }
+        while (l instanceof PropertyChangeListenerProxy) {
+            PropertyChangeListenerProxy p = (PropertyChangeListenerProxy) l;
+            if (propertyName == null ? p.propertyName != null : !propertyName.equals(p.propertyName)) {
+                return;
+            }
+            l = (PropertyChangeListener) p.getListener();
+        }
+        s.listeners.remove(l);
+        if (s.listeners.isEmpty()) {
+            children.remove(propertyName);
+            if (children.isEmpty()) {
+                children = null;
+            }
+        }
+    }
+} // class PropertyChangeSupport

Added: trunk/src/main/java/org/ourproject/kune/platf/client/actions/ui/AbstractButton.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/actions/ui/AbstractButton.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/actions/ui/AbstractButton.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -0,0 +1,125 @@
+package org.ourproject.kune.platf.client.actions.ui;
+
+import org.ourproject.kune.platf.client.actions.Action;
+import org.ourproject.kune.platf.client.actions.PropertyChangeEvent;
+import org.ourproject.kune.platf.client.actions.PropertyChangeListener;
+import org.ourproject.kune.platf.client.ui.rte.img.RTEImgResources;
+
+import com.google.gwt.libideas.resources.client.ImageResource;
+import com.google.gwt.user.client.ui.Composite;
+import com.gwtext.client.widgets.Button;
+
+public abstract class AbstractButton extends Composite {
+
+    private Action action;
+    private final Button button;
+
+    /**
+     * Listener the button uses to receive PropertyChangeEvents from its Action.
+     */
+    PropertyChangeListener actionPropertyChangeListener;
+
+    public AbstractButton() {
+        button = new Button();
+        initWidget(button);
+    }
+
+    public void setAction(final Action a) {
+        if (action != null) {
+            action.removePropertyChangeListener(actionPropertyChangeListener);
+            // removeActionListener(action);
+            if (actionPropertyChangeListener != null) {
+                action.removePropertyChangeListener(actionPropertyChangeListener);
+                actionPropertyChangeListener = null;
+            }
+        }
+
+        action = a;
+        configurePropertiesFromAction(action);
+        if (action != null) {
+            actionPropertyChangeListener = createActionPropertyChangeListener(a);
+            action.addPropertyChangeListener(actionPropertyChangeListener);
+            // addActionListener(action);
+        }
+    }
+
+    public void setEnabled(final boolean enabled) {
+        if (enabled) {
+            button.enable();
+        } else {
+            button.disable();
+        }
+    }
+
+    public void setIcon(final ImageResource imageResource) {
+        if (imageResource != null) {
+            // FIXME
+            button.setIconCls(RTEImgResources.SUFFIX + imageResource.getName());
+        }
+    }
+
+    public void setText(final String text) {
+        button.setText(text);
+    }
+
+    public void setToolTipText(final String tooltip) {
+        button.setTooltip(tooltip);
+    }
+
+    protected void configurePropertiesFromAction(final Action a) {
+        if (a == null) {
+            setText(null);
+            setIcon(null);
+            setEnabled(true);
+            setToolTipText(null);
+        } else {
+            setText((String) (a.getValue(Action.NAME)));
+            setIcon((ImageResource) (a.getValue(Action.SMALL_ICON)));
+            setEnabled(a.isEnabled());
+            setToolTipText((String) (a.getValue(Action.SHORT_DESCRIPTION)));
+            // if (a.getValue(Action.MNEMONIC_KEY) != null) {
+            // setMnemonic(((Integer)
+            // (a.getValue(Action.MNEMONIC_KEY))).intValue());
+            // }
+            // String actionCommand = (String)
+            // (a.getValue(Action.ACTION_COMMAND_KEY));
+            //
+            // // Set actionCommand to button's text by default if it is not
+            // // specified
+            // if (actionCommand != null) {
+            // setActionCommand((String)
+            // (a.getValue(Action.ACTION_COMMAND_KEY)));
+            // } else {
+            // setActionCommand(getText());
+            // }
+        }
+    }
+
+    protected PropertyChangeListener createActionPropertyChangeListener(final Action a) {
+        return new PropertyChangeListener() {
+            public void propertyChange(final PropertyChangeEvent e) {
+                Action act = (Action) (e.getSource());
+                if (e.getPropertyName().equals(Action.ENABLED)) {
+                    setEnabled(act.isEnabled());
+                } else if (e.getPropertyName().equals(Action.NAME)) {
+                    setText((String) (act.getValue(Action.NAME)));
+                } else if (e.getPropertyName().equals(Action.SMALL_ICON)) {
+                    setIcon((ImageResource) (act.getValue(Action.SMALL_ICON)));
+                } else if (e.getPropertyName().equals(Action.SHORT_DESCRIPTION)) {
+                    setToolTipText((String) (act.getValue(Action.SHORT_DESCRIPTION)));
+                }
+                // else if (e.getPropertyName().equals(Action.MNEMONIC_KEY)) {
+                // if (act.getValue(Action.MNEMONIC_KEY) != null) {
+                // setMnemonic(((Integer) (act.getValue(Action.MNEMONIC_KEY)))
+                // .intValue());
+                // } else if
+                // (e.getPropertyName().equals(Action.ACTION_COMMAND_KEY)) {
+                // setActionCommand((String)
+                // (act.getValue(Action.ACTION_COMMAND_KEY)));
+                // }
+                // }
+            }
+        };
+    }
+
+}

Added: trunk/src/main/java/org/ourproject/kune/platf/client/actions/ui/DefaultButton.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/actions/ui/DefaultButton.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/actions/ui/DefaultButton.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -0,0 +1,28 @@
+package org.ourproject.kune.platf.client.actions.ui;
+
+import org.ourproject.kune.platf.client.actions.Action;
+
+import com.google.gwt.libideas.resources.client.ImageResource;
+
+public class DefaultButton extends AbstractButton {
+    public DefaultButton() {
+    }
+
+    public DefaultButton(final Action action) {
+        configurePropertiesFromAction(action);
+    }
+
+    public DefaultButton(final ImageResource icon) {
+        setIcon(icon);
+    }
+
+    public DefaultButton(final String text) {
+        setText(text);
+    }
+
+    public DefaultButton(final String text, final ImageResource icon) {
+        setText(text);
+        setIcon(icon);
+    }
+
+}

Added: trunk/src/main/java/org/ourproject/kune/platf/client/actions/ui/TestButton.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/actions/ui/TestButton.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/actions/ui/TestButton.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -0,0 +1,36 @@
+package org.ourproject.kune.platf.client.actions.ui;
+
+import org.ourproject.kune.platf.client.actions.AbstractAction;
+import org.ourproject.kune.platf.client.actions.Action;
+import org.ourproject.kune.platf.client.actions.ActionEvent;
+import org.ourproject.kune.platf.client.ui.noti.NotifyUser;
+import org.ourproject.kune.workspace.client.skel.WorkspaceSkeleton;
+
+import com.google.gwt.user.client.Timer;
+
+public class TestButton extends DefaultButton {
+    public class NotiAction extends AbstractAction {
+        public NotiAction() {
+            super.putValue(Action.NAME, "test");
+            super.putValue(Action.SHORT_DESCRIPTION, "test button");
+        }
+
+        public void actionPerformed(final ActionEvent event) {
+            NotifyUser.info("Button clicked");
+        }
+    }
+
+    public TestButton(final WorkspaceSkeleton ws) {
+        super();
+        ws.getEntityWorkspace().getBottomTitle().add(this);
+        final NotiAction noti = new NotiAction();
+        super.setAction(noti);
+        new Timer() {
+            @Override
+            public void run() {
+                noti.putValue(Action.NAME, "test2");
+                noti.putValue(Action.SHORT_DESCRIPTION, "test2 button");
+            }
+        }.schedule(5000);
+    }
+}

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/errors/AccessViolationException.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/errors/AccessViolationException.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/errors/AccessViolationException.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -20,5 +20,5 @@
 package org.ourproject.kune.platf.client.errors;
 
 public class AccessViolationException extends DefaultException {
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = -3786772632052256999L;
 }

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/errors/AlreadyGroupMemberException.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/errors/AlreadyGroupMemberException.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/errors/AlreadyGroupMemberException.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -20,5 +20,5 @@
 package org.ourproject.kune.platf.client.errors;
 
 public class AlreadyGroupMemberException extends DefaultException {
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 6663958867752546481L;
 }

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/errors/AlreadyUserMemberException.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/errors/AlreadyUserMemberException.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/errors/AlreadyUserMemberException.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -20,5 +20,5 @@
 package org.ourproject.kune.platf.client.errors;
 
 public class AlreadyUserMemberException extends DefaultException {
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = -6365615768192330492L;
 }

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/errors/ContainerNotPermittedException.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/errors/ContainerNotPermittedException.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/errors/ContainerNotPermittedException.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -20,5 +20,5 @@
 package org.ourproject.kune.platf.client.errors;
 
 public class ContainerNotPermittedException extends DefaultException {
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 6866318170714609691L;
 }

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/errors/ContentNotFoundException.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/errors/ContentNotFoundException.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/errors/ContentNotFoundException.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -20,5 +20,5 @@
 package org.ourproject.kune.platf.client.errors;
 
 public class ContentNotFoundException extends DefaultException {
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = -4641212341448422627L;
 }

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/errors/ContentNotPermittedException.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/errors/ContentNotPermittedException.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/errors/ContentNotPermittedException.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -20,5 +20,5 @@
 package org.ourproject.kune.platf.client.errors;
 
 public class ContentNotPermittedException extends DefaultException {
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 4771568826852748873L;
 }

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/errors/DefaultException.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/errors/DefaultException.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/errors/DefaultException.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -23,8 +23,9 @@
 import com.google.gwt.user.client.rpc.StatusCodeException;
 
 public class DefaultException extends StatusCodeException implements IsSerializable {
-    private static final long serialVersionUID = 1L;
 
+    private static final long serialVersionUID = -6111471089427505005L;
+
     public DefaultException() {
         this(0, "");
     }

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/errors/EmailAddressInUseException.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/errors/EmailAddressInUseException.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/errors/EmailAddressInUseException.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -20,5 +20,5 @@
 package org.ourproject.kune.platf.client.errors;
 
 public class EmailAddressInUseException extends DefaultException {
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 3740509040361715407L;
 }

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/errors/GroupNameInUseException.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/errors/GroupNameInUseException.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/errors/GroupNameInUseException.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -20,5 +20,5 @@
 package org.ourproject.kune.platf.client.errors;
 
 public class GroupNameInUseException extends DefaultException {
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = -4746775725822225687L;
 }

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/errors/GroupNotFoundException.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/errors/GroupNotFoundException.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/errors/GroupNotFoundException.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -20,5 +20,5 @@
 package org.ourproject.kune.platf.client.errors;
 
 public class GroupNotFoundException extends DefaultException {
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 2358855015943550817L;
 }

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/errors/I18nNotFoundException.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/errors/I18nNotFoundException.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/errors/I18nNotFoundException.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -20,5 +20,5 @@
 package org.ourproject.kune.platf.client.errors;
 
 public class I18nNotFoundException extends DefaultException {
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = -2400899465805236215L;
 }

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/errors/LastAdminInGroupException.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/errors/LastAdminInGroupException.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/errors/LastAdminInGroupException.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -20,5 +20,5 @@
 package org.ourproject.kune.platf.client.errors;
 
 public class LastAdminInGroupException extends DefaultException {
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = -8727443733339361388L;
 }

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/errors/NameInUseException.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/errors/NameInUseException.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/errors/NameInUseException.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -20,5 +20,5 @@
 package org.ourproject.kune.platf.client.errors;
 
 public class NameInUseException extends DefaultException {
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 4890594846432830537L;
 }

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/errors/NameNotPermittedException.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/errors/NameNotPermittedException.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/errors/NameNotPermittedException.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -20,5 +20,5 @@
 package org.ourproject.kune.platf.client.errors;
 
 public class NameNotPermittedException extends DefaultException {
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = -8022844560909422614L;
 }

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/errors/NoDefaultContentException.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/errors/NoDefaultContentException.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/errors/NoDefaultContentException.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -20,5 +20,5 @@
 package org.ourproject.kune.platf.client.errors;
 
 public class NoDefaultContentException extends DefaultException {
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 7443824340580555859L;
 }

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/errors/SessionExpiredException.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/errors/SessionExpiredException.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/errors/SessionExpiredException.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -20,5 +20,5 @@
 package org.ourproject.kune.platf.client.errors;
 
 public class SessionExpiredException extends DefaultException {
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = -1603881986661302041L;
 }

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/errors/ToolNotFoundException.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/errors/ToolNotFoundException.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/errors/ToolNotFoundException.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -20,5 +20,5 @@
 package org.ourproject.kune.platf.client.errors;
 
 public class ToolNotFoundException extends DefaultException {
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 472511647264356558L;
 }

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/errors/UserAuthException.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/errors/UserAuthException.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/errors/UserAuthException.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -20,5 +20,5 @@
 package org.ourproject.kune.platf.client.errors;
 
 public class UserAuthException extends DefaultException {
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = -8383513776573054971L;
 }

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/errors/UserMustBeLoggedException.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/errors/UserMustBeLoggedException.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/errors/UserMustBeLoggedException.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -20,5 +20,5 @@
 package org.ourproject.kune.platf.client.errors;
 
 public class UserMustBeLoggedException extends DefaultException {
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = -5091069990899662849L;
 }

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/errors/UserNotFoundException.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/errors/UserNotFoundException.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/errors/UserNotFoundException.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -20,5 +20,5 @@
 package org.ourproject.kune.platf.client.errors;
 
 public class UserNotFoundException extends DefaultException {
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 6207713694613166661L;
 }

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/i18n/I18nChangeListenerCollection.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/i18n/I18nChangeListenerCollection.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/i18n/I18nChangeListenerCollection.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -20,7 +20,6 @@
 package org.ourproject.kune.platf.client.i18n;
 
 import java.util.ArrayList;
-import java.util.Iterator;
 
 /**
  * A helper class for implementers of the SourcesI18nChangeEvents interface.
@@ -29,15 +28,14 @@
  */
 public class I18nChangeListenerCollection extends ArrayList<I18nChangeListener> {
 
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = -2435290836445582410L;
 
     /**
      * Fires a locale change event to all listeners.
      * 
      */
     public void fireI18nLanguageChange() {
-        for (Iterator<I18nChangeListener> it = iterator(); it.hasNext();) {
-            I18nChangeListener listener = it.next();
+        for (I18nChangeListener listener : this) {
             listener.onI18nLanguageChange();
         }
     }

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/services/PlatformModule.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/services/PlatformModule.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/services/PlatformModule.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -21,6 +21,7 @@
 
 import org.ourproject.kune.platf.client.actions.ActionManager;
 import org.ourproject.kune.platf.client.actions.toolbar.ActionToolbarPanel;
+import org.ourproject.kune.platf.client.actions.ui.TestButton;
 import org.ourproject.kune.platf.client.app.Application;
 import org.ourproject.kune.platf.client.app.ApplicationComponentGroup;
 import org.ourproject.kune.platf.client.app.ApplicationDefault;
@@ -115,6 +116,7 @@
 import org.ourproject.kune.platf.client.ui.rte.saving.RTESavingEditorPresenter;
 import org.ourproject.kune.platf.client.utils.DeferredCommandWrapper;
 import org.ourproject.kune.platf.client.utils.TimerWrapper;
+import org.ourproject.kune.workspace.client.skel.WorkspaceSkeleton;
 
 import com.calclab.suco.client.events.Listener0;
 import com.calclab.suco.client.ioc.decorator.NoDecoration;
@@ -523,9 +525,18 @@
                 return new ExternalMediaRegistry($(Session.class).getInitData().getExtMediaDescrips());
             }});
 
+        register(Singleton.class, new Factory<TestButton>(TestButton.class) {
+            @Override
+            public TestButton create() {
+                final TestButton btn = new TestButton($(WorkspaceSkeleton.class));
+                return btn;
+            }
+        });
+
         $(ApplicationComponentGroup.class).createAll();
         $(ToolGroup.class).createAll();
         $(Application.class).start();
         // $(HelloWorld.class);
+
     }
 }
\ No newline at end of file

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/shortcuts/Keyboard.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/shortcuts/Keyboard.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/shortcuts/Keyboard.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -19,4 +19,50 @@
     public int KEY_F11 = 122; /* Full screen */
     public int KEY_F12 = 123;
 
+    public int KEY_COMMA = ',';
+    public int KEY_MINUS = '-';
+    public int KEY_PERIOD = '.';
+    public int KEY_SLASH = '/';
+    public int KEY_0 = '0';
+    public int KEY_1 = '1';
+    public int KEY_2 = '2';
+    public int KEY_3 = '3';
+    public int KEY_4 = '4';
+    public int KEY_5 = '5';
+    public int KEY_6 = '6';
+    public int KEY_7 = '7';
+    public int KEY_8 = '8';
+    public int KEY_9 = '9';
+    public int KEY_SEMICOLON = ';';
+    public int KEY_EQUALS = '=';
+    public int KEY_A = 'A';
+    public int KEY_B = 'B';
+    public int KEY_C = 'C';
+    public int KEY_D = 'D';
+    public int KEY_E = 'E';
+    public int KEY_F = 'F';
+    public int KEY_G = 'G';
+    public int KEY_H = 'H';
+    public int KEY_I = 'I';
+    public int KEY_J = 'J';
+    public int KEY_K = 'K';
+    public int KEY_L = 'L';
+    public int KEY_M = 'M';
+    public int KEY_N = 'N';
+    public int KEY_O = 'O';
+    public int KEY_P = 'P';
+    public int KEY_Q = 'Q';
+    public int KEY_R = 'R';
+    public int KEY_S = 'S';
+    public int KEY_T = 'T';
+    public int KEY_U = 'U';
+    public int KEY_V = 'V';
+    public int KEY_W = 'W';
+    public int KEY_X = 'X';
+    public int KEY_Y = 'Y';
+    public int KEY_Z = 'Z';
+    public int KEY_OPEN_BRACKET = '[';
+    public int KEY_BACK_SLASH = '\\';
+    public int KEY_CLOSE_BRACKET = ']';
+
 }

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/ui/MenuItemCollection.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/ui/MenuItemCollection.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/ui/MenuItemCollection.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -44,6 +44,6 @@
 
 public class MenuItemCollection<T> extends ArrayList<MenuItem<T>> {
 
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = -4719030300216601947L;
 
 }

Modified: trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/insertmedia/ExternalMediaRegistry.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/insertmedia/ExternalMediaRegistry.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/insertmedia/ExternalMediaRegistry.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -9,8 +9,7 @@
 
 public class ExternalMediaRegistry extends ArrayList<ExtMediaDescripDTO> {
 
-    private static final long serialVersionUID = 1L;
-
+    private static final long serialVersionUID = -9109609520119776917L;
     public static final ExtMediaDescripDTO NO_MEDIA = new ExtMediaDescripDTO(null, null, null, null, null, 0, 0);
 
     public ExternalMediaRegistry(final List<ExtMediaDescripDTO> extMediaDescrips) {

Modified: trunk/src/main/java/org/ourproject/kune/platf/server/domain/ChatUserParams.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/server/domain/ChatUserParams.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/server/domain/ChatUserParams.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -25,7 +25,7 @@
 
 public class ChatUserParams implements Serializable {
 
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = -1343712336914940957L;
 
     private String avatar;
 

Modified: trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/EntityLogoDownloadManager.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/EntityLogoDownloadManager.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/EntityLogoDownloadManager.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -36,8 +36,7 @@
 
 public class EntityLogoDownloadManager extends HttpServlet {
 
-    private static final long serialVersionUID = 1L;
-
+    private static final long serialVersionUID = -1958945058088446881L;
     @Inject
     GroupManager groupManager;
 

Modified: trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/EntityLogoUploadManager.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/EntityLogoUploadManager.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/EntityLogoUploadManager.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -46,7 +46,7 @@
 
 public class EntityLogoUploadManager extends FileUploadManagerAbstract {
 
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = -4281058427935636238L;
 
     @Inject
     GroupManager groupManager;
@@ -55,14 +55,14 @@
     I18nTranslationService i18n;
 
     @Override
-    protected void beforeRespond(HttpServletResponse response, Writer w) throws IOException {
+    protected void beforeRespond(final HttpServletResponse response, final Writer w) throws IOException {
         super.beforeRespond(response, w);
         response.setCharacterEncoding("utf-8");
         response.setContentType("text/xml");
     }
 
-    protected void createUploadedFile(StateToken stateToken, String mimeTypeS, File origFile) throws Exception,
-            IOException, MagickException, FileNotFoundException {
+    protected void createUploadedFile(final StateToken stateToken, final String mimeTypeS, final File origFile)
+            throws Exception, IOException, MagickException, FileNotFoundException {
         BasicMimeType mimeType = new BasicMimeType(mimeTypeS);
         if (!mimeType.getType().equals("image")) {
             throw new Exception("Trying to set a non image (" + mimeTypeS + ") as group logo");
@@ -91,8 +91,8 @@
     @Authenticated
     @Authorizated(accessRolRequired = AccessRol.Administrator, actionLevel = ActionLevel.group)
     @Transactional(type = TransactionType.READ_WRITE)
-    protected void createUploadedFile(String userHash, StateToken stateToken, String fileName, FileItem file,
-            String typeId) throws Exception {
+    protected void createUploadedFile(final String userHash, final StateToken stateToken, final String fileName,
+            final FileItem file, final String typeId) throws Exception {
         String mimeTypeS = file.getContentType();
         File tmpOrigFile = File.createTempFile("logoOrig", "");
         file.write(tmpOrigFile);
@@ -133,13 +133,13 @@
     }
 
     @Override
-    protected void onFileUploadException(HttpServletResponse response) throws IOException {
+    protected void onFileUploadException(final HttpServletResponse response) throws IOException {
         doResponse(response, createXmlResponse(false, i18n.t("Error: File too large")).toString(),
                 HttpServletResponse.SC_BAD_REQUEST);
     }
 
     @Override
-    protected void onOtherException(HttpServletResponse response, Exception e) throws IOException {
+    protected void onOtherException(final HttpServletResponse response, final Exception e) throws IOException {
         super.onOtherException(response, e);
         log.info("Exception: " + e.getCause());
         // e.printStackTrace();
@@ -148,7 +148,7 @@
     }
 
     @Override
-    protected void onSuccess(HttpServletResponse response) throws IOException {
+    protected void onSuccess(final HttpServletResponse response) throws IOException {
         doResponse(response, createXmlResponse(true, i18n.t("Success uploading")).toString());
     }
 

Modified: trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/FileDownloadManager.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/FileDownloadManager.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/FileDownloadManager.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -54,13 +54,14 @@
  */
 public class FileDownloadManager extends HttpServlet {
 
+    private static final long serialVersionUID = -1160659289588014049L;
+
     static final String RESP_HEADER_ATTACHMENT_FILENAME = "attachment; filename=\"";
     static final String RESP_HEADER_CONTEND_DISP = "Content-Disposition";
     static final String RESP_HEADER_END = "\"";
 
     static final String APPLICATION_X_DOWNLOAD = "application/x-download";
 
-    private static final long serialVersionUID = 1L;
     public static final Log log = LogFactory.getLog(FileDownloadManager.class);
 
     @Inject

Modified: trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/FileDownloadManagerUtils.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/FileDownloadManagerUtils.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/FileDownloadManagerUtils.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -30,8 +30,6 @@
 
 public class FileDownloadManagerUtils {
 
-    private static final long serialVersionUID = 1L;
-
     public static void returnFile(final String filename, final OutputStream out) throws FileNotFoundException,
             IOException {
         InputStream in = null;
@@ -49,7 +47,7 @@
         }
     }
 
-    public static void returnNotFound(HttpServletResponse resp) throws IOException {
+    public static void returnNotFound(final HttpServletResponse resp) throws IOException {
         resp.getWriter().println("Content not found");
         resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
     }

Modified: trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/FileJsonUploadManagerAbstract.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/FileJsonUploadManagerAbstract.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/FileJsonUploadManagerAbstract.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -32,13 +32,12 @@
 
 public abstract class FileJsonUploadManagerAbstract extends FileUploadManagerAbstract {
 
-    private static final long serialVersionUID = 1L;
-
+    private static final long serialVersionUID = 8437422616838698647L;
     @Inject
     I18nTranslationService i18n;
 
     @Override
-    protected void beforeRespond(HttpServletResponse response, Writer w) throws IOException {
+    protected void beforeRespond(final HttpServletResponse response, final Writer w) throws IOException {
         super.beforeRespond(response, w);
         response.setCharacterEncoding("utf-8");
         response.setContentType("text/html");
@@ -49,12 +48,12 @@
     }
 
     @Override
-    protected void onFileUploadException(HttpServletResponse response) throws IOException {
+    protected void onFileUploadException(final HttpServletResponse response) throws IOException {
         doResponse(response, createJsonResponse(false, i18n.t("Error: File too large")).toString());
     }
 
     @Override
-    protected void onOtherException(HttpServletResponse response, Exception e) throws IOException {
+    protected void onOtherException(final HttpServletResponse response, final Exception e) throws IOException {
         super.onOtherException(response, e);
         log.info("Exception: " + e.getCause());
         // e.printStackTrace();
@@ -62,7 +61,7 @@
     }
 
     @Override
-    protected void onSuccess(HttpServletResponse response) throws IOException {
+    protected void onSuccess(final HttpServletResponse response) throws IOException {
         doResponse(response, createJsonResponse(true, i18n.t("Uploading was successful")).toString());
     }
 }

Modified: trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/FileUploadManager.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/FileUploadManager.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/FileUploadManager.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -53,8 +53,7 @@
 @RequestScoped
 public class FileUploadManager extends FileJsonUploadManagerAbstract {
 
-    private static final long serialVersionUID = 1L;
-
+    private static final long serialVersionUID = -7209922761735338754L;
     @Inject
     UserSession userSession;
     @Inject
@@ -93,8 +92,8 @@
     }
 
     @Override
-    protected void createUploadedFile(String userHash, StateToken stateToken, String fileName, FileItem file,
-            String typeId) throws Exception {
+    protected void createUploadedFile(final String userHash, final StateToken stateToken, final String fileName,
+            final FileItem file, final String typeId) throws Exception {
         createUploadedFileWrapped(userHash, stateToken, fileName, file, typeId);
     }
 
@@ -102,7 +101,7 @@
     @Authorizated(accessRolRequired = AccessRol.Editor, actionLevel = ActionLevel.container, mustCheckMembership = false)
     @Transactional(type = TransactionType.READ_WRITE)
     Content createUploadedFileWrapped(final String userHash, final StateToken stateToken, final String fileName,
-            final FileItem fileUploadItem, String typeId) throws Exception {
+            final FileItem fileUploadItem, final String typeId) throws Exception {
         final String relDir = FileUtils.toDir(stateToken);
         final String absDir = kuneProperties.get(KuneProperties.UPLOAD_LOCATION) + relDir;
         fileManager.mkdir(absDir);
@@ -146,7 +145,7 @@
         }
     }
 
-    private void generateThumbs(String absDir, String filename, String extension, boolean isPdf) {
+    private void generateThumbs(final String absDir, final String filename, final String extension, final boolean isPdf) {
         try {
             String fileOrig = absDir + filename;
             String withoutExtension = FileUtils.getFileNameWithoutExtension(filename, extension);

Modified: trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/FileUploadManagerAbstract.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/FileUploadManagerAbstract.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/platf/server/manager/file/FileUploadManagerAbstract.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -45,7 +45,7 @@
 
 public abstract class FileUploadManagerAbstract extends HttpServlet {
 
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = -4227762495128652369L;
 
     public static final Log log = LogFactory.getLog(FileUploadManager.class);
 
@@ -60,8 +60,8 @@
     protected void beforeRespond(final HttpServletResponse response, final Writer w) throws IOException {
     }
 
-    protected void createUploadedFile(String userHash, StateToken stateToken, String fileName, FileItem file,
-            String typeId) throws Exception {
+    protected void createUploadedFile(final String userHash, final StateToken stateToken, final String fileName,
+            final FileItem file, final String typeId) throws Exception {
     }
 
     @Override
@@ -123,12 +123,12 @@
         }
     }
 
-    protected void doResponse(final HttpServletResponse response, String additionalResponse) throws IOException {
+    protected void doResponse(final HttpServletResponse response, final String additionalResponse) throws IOException {
         doResponse(response, additionalResponse, HttpServletResponse.SC_OK);
     }
 
-    protected void doResponse(final HttpServletResponse response, String additionalResponse, int responseCode)
-            throws IOException {
+    protected void doResponse(final HttpServletResponse response, final String additionalResponse,
+            final int responseCode) throws IOException {
         final Writer w = new OutputStreamWriter(response.getOutputStream());
         if (additionalResponse != null) {
             w.write(additionalResponse);
@@ -141,13 +141,13 @@
         doResponse(response, null);
     }
 
-    protected void onOtherException(HttpServletResponse response, final Exception e) throws IOException {
+    protected void onOtherException(final HttpServletResponse response, final Exception e) throws IOException {
         log.info("Exception: " + e.getCause());
         e.printStackTrace();
         doResponse(response, null);
     }
 
-    protected void onSuccess(HttpServletResponse response) throws IOException {
+    protected void onSuccess(final HttpServletResponse response) throws IOException {
         doResponse(response, null);
     }
 

Modified: trunk/src/main/java/org/ourproject/kune/rack/filters/gwts/DelegatedRemoteServlet.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/rack/filters/gwts/DelegatedRemoteServlet.java	2009-05-11 20:23:46 UTC (rev 1109)
+++ trunk/src/main/java/org/ourproject/kune/rack/filters/gwts/DelegatedRemoteServlet.java	2009-05-13 13:53:01 UTC (rev 1110)
@@ -29,12 +29,13 @@
 import com.google.gwt.user.server.rpc.RemoteServiceServlet;
 
 public class DelegatedRemoteServlet extends RemoteServiceServlet {
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = -7646054921925214953L;
     private transient RemoteService service;
     private ServletContext servletContext;
 
-    public void setService(final RemoteService service) {
-        this.service = service;
+    @Override
+    public ServletContext getServletContext() {
+        return servletContext;
     }
 
     @Override
@@ -47,17 +48,17 @@
         }
     }
 
-    @Override
-    protected void doUnexpectedFailure(final Throwable e) {
-        e.printStackTrace();
-        super.doUnexpectedFailure(e);
+    public void setService(final RemoteService service) {
+        this.service = service;
     }
 
     public void setServletContext(final ServletContext servletContext) {
         this.servletContext = servletContext;
     }
 
-    public ServletContext getServletContext() {
-        return servletContext;
+    @Override
+    protected void doUnexpectedFailure(final Throwable e) {
+        e.printStackTrace();
+        super.doUnexpectedFailure(e);
     }
 }
\ No newline at end of file




More information about the kune-commits mailing list