svn commit: r13496 - trunk/src_new/org/argouml: kernel ui

[email protected]
Newsgroups gmane.comp.lang.uml.argouml.cvs
Message-ID <[email protected]>
Author: bobtarling
Date: 2007-09-05 16:19:24-0700
New Revision: 13496

Modified:
   trunk/src_new/org/argouml/kernel/DefaultUndoManager.java
   trunk/src_new/org/argouml/kernel/UndoManager.java
   trunk/src_new/org/argouml/ui/ProjectActions.java
   trunk/src_new/org/argouml/ui/UndoableAction.java

Log:
Start work to change label for undo/redo and disable

Modified: trunk/src_new/org/argouml/kernel/DefaultUndoManager.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src_new/org/argouml/kernel/DefaultUndoManager.java?view=diff&rev=13496&p1=trunk/src_new/org/argouml/kernel/DefaultUndoManager.java&p2=trunk/src_new/org/argouml/kernel/DefaultUndoManager.java&r1=13495&r2=13496
==============================================================================
--- trunk/src_new/org/argouml/kernel/DefaultUndoManager.java	(original)
+++ trunk/src_new/org/argouml/kernel/DefaultUndoManager.java	2007-09-05 16:19:24-0700
@@ -33,6 +33,8 @@
 import java.util.ListIterator;
 import java.util.Stack;
 
+import org.argouml.i18n.Translator;
+
 /**
  * Manages a stacks of Commands to undo and redo.
  * UndoManager is only temporarily singleton until changes are made to GEF.
@@ -45,12 +47,19 @@
     private Collection<PropertyChangeListener> listeners =
         new ArrayList<PropertyChangeListener>();
     
-    private boolean newChain = true;
+    /**
+     * Set when a new user interaction begins
+     */
+    private boolean newInteraction = true;
     
-    // TODO: A UndoChainStack may produce some reasuable code for
-    // the undoStack and the redoStack/
-    private Stack<Interaction> undoStack = new Stack<Interaction>();
-    private Stack<Interaction> redoStack = new Stack<Interaction>();
+    /**
+     * A description of the user interaction taking place.
+     * Often this is the label of an Action.
+     */
+    private String newInteractionLabel;
+    
+    private UndoStack undoStack = new UndoStack();
+    private RedoStack redoStack = new RedoStack();
     
     private static final UndoManager INSTANCE = new DefaultUndoManager();
 
@@ -73,13 +82,13 @@
         }
         // Flag the command as to whether it is first in a chain
         final Interaction macroCommand;
-        if (newChain || undoStack.isEmpty()) {
+        if (newInteraction || undoStack.isEmpty()) {
             redoStack.clear();
-            newChain = false;
+            newInteraction = false;
             if (undoStack.size() > undoMax) {
                 undoStack.remove(0);
             }
-            macroCommand = new Interaction();
+            macroCommand = new Interaction(newInteractionLabel);
             undoStack.push(macroCommand);
         } else {
             macroCommand = undoStack.peek();
@@ -111,54 +120,27 @@
         undoStack.push(command);
     }
     
-    /**
-     * 
-     * @see org.argouml.kernel.UndoManager#empty()
-     */
-    public void empty() {
-        undoStack.clear();
-        redoStack.clear();
-    }
-    
-    /**
-     * 
-     * @see org.argouml.kernel.UndoManager#startInteraction()
-     */
-    public void startInteraction() {
-        newChain = true;
+    public void startInteraction(String label) {
+        if (!newInteraction) {
+            this.newInteractionLabel = label;
+            newInteraction = true;
+        }
     }
  
-    /**
-     * @param listener
-     * @see org.argouml.kernel.UndoManager#addPropertyChangeListener(java.beans.PropertyChangeListener)
-     */
     public void addPropertyChangeListener(PropertyChangeListener listener) {
         listeners.add(listener);
     }
     
-    private void fireCanUndo() {
-        Iterator i = listeners.iterator();
-        while (i.hasNext()) {
-            PropertyChangeListener listener = (PropertyChangeListener) i.next();
-            listener.propertyChange(
-                    new PropertyChangeEvent(
-                            this,
-                            "canUndo",
-                            "",
-                            Boolean.toString(undoStack.size() > 0)));
-        }
+    public void removePropertyChangeListener(PropertyChangeListener listener) {
+        listeners.remove(listener);
     }
     
-    private void fireCanRedo() {
+    private void fire(String property, Object value) {
         Iterator i = listeners.iterator();
         while (i.hasNext()) {
             PropertyChangeListener listener = (PropertyChangeListener) i.next();
             listener.propertyChange(
-                    new PropertyChangeEvent(
-                            this,
-                            "canRedo",
-                            "",
-                            Boolean.toString(redoStack.size() > 0)));
+                    new PropertyChangeEvent(this, property, "", value));
         }
     }
     
@@ -173,6 +155,12 @@
         
         private List<Command> commands = new ArrayList<Command>();
         
+        private String label;
+        
+        Interaction(String label) {
+            this.label = label;
+        }
+        
         public void undo() {
             final ListIterator<Command> it =
                 commands.listIterator(commands.size());
@@ -203,12 +191,85 @@
             commands.add(command);
         }
         
+        // TODO: i18n
         private String getUndoLabel() {
-            return "Undo";
+            if (isUndoable()) {
+                return "Undo " + label;
+            } else {
+                return "Can't Undo " + label;
+            }
         }
         
+        // TODO: i18n
         private String getRedoLabel() {
-            return "Redo";
+            return "Redo " + label;
+        }
+    }
+    
+    private abstract class InteractionStack extends Stack<Interaction> {
+        
+        private String enabledProperty;
+        private String labelProperty;
+        
+        public InteractionStack(
+                String enabledProperty,
+                String labelProperty) {
+            this.enabledProperty = enabledProperty;
+            this.labelProperty = labelProperty;
+        }
+        
+        public Interaction push(Interaction item) {
+            super.push(item);
+            fireLabel();
+            if (size() == 1) {
+                fire(enabledProperty, true);
+            }
+            return item;
+        }
+        
+        public Interaction pop() {
+            Interaction item = super.pop();
+            fireLabel();
+            if (size() == 0) {
+                fire(enabledProperty, false);
+            }
+            return item;
+        }
+        
+        private void fireLabel() {
+            fire(labelProperty, getLabel());
+        }
+        
+        protected abstract String getLabel();
+    }
+    
+    private class UndoStack extends InteractionStack {
+        
+        public UndoStack() {
+            super("undoable", "undoLabel");
+        }
+        
+        protected String getLabel() {
+            if (empty()) {
+                return Translator.localize("action.undo");
+            } else {
+                return peek().getUndoLabel();
+            }
+        }
+    }
+    
+    private class RedoStack extends InteractionStack {
+        
+        public RedoStack() {
+            super("redoable", "redoLabel");
+        }
+        
+        protected String getLabel() {
+            if (empty()) {
+                return Translator.localize("action.redo");
+            } else {
+                return peek().getRedoLabel();
+            }
         }
     }
 }

Modified: trunk/src_new/org/argouml/kernel/UndoManager.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src_new/org/argouml/kernel/UndoManager.java?view=diff&rev=13496&p1=trunk/src_new/org/argouml/kernel/UndoManager.java&p2=trunk/src_new/org/argouml/kernel/UndoManager.java&r1=13495&r2=13496
==============================================================================
--- trunk/src_new/org/argouml/kernel/UndoManager.java	(original)
+++ trunk/src_new/org/argouml/kernel/UndoManager.java	2007-09-05 16:19:24-0700
@@ -62,17 +62,13 @@
     public abstract void redo();
 
     /**
-     * Empty all undoable and redoable items from the UndoManager
-     */
-    public abstract void empty();
-
-    /**
      * Instructs the UndoManager that a new user interaction is about to take
      * place. All commands received until the next call to startInteraction
      * will form a single undoable unit.
+     * @param label the label for this interaction to build the undo/redo label
      */
-    public abstract void startInteraction();
-
+    public abstract void startInteraction(String label);
+    
     /**
      * Allow a listener to detect when the undo or redo stack
      * changes availability
@@ -80,4 +76,11 @@
      */
     public abstract void addPropertyChangeListener(
             PropertyChangeListener listener);
+    
+    /**
+     * Remove the listener
+     * @param listener a PropertyChangeListener
+     */
+    public abstract void removePropertyChangeListener(
+            PropertyChangeListener listener);
 }
\ No newline at end of file

Modified: trunk/src_new/org/argouml/ui/ProjectActions.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src_new/org/argouml/ui/ProjectActions.java?view=diff&rev=13496&p1=trunk/src_new/org/argouml/ui/ProjectActions.java&p2=trunk/src_new/org/argouml/ui/ProjectActions.java&r1=13495&r2=13496
==============================================================================
--- trunk/src_new/org/argouml/ui/ProjectActions.java	(original)
+++ trunk/src_new/org/argouml/ui/ProjectActions.java	2007-09-05 16:19:24-0700
@@ -24,14 +24,18 @@
 
 package org.argouml.ui;
 
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
 import java.util.Collection;
 import java.util.List;
 
 import javax.swing.AbstractAction;
 
 import org.argouml.i18n.Translator;
+import org.argouml.kernel.DefaultUndoManager;
 import org.argouml.kernel.Project;
 import org.argouml.kernel.ProjectManager;
+import org.argouml.kernel.UndoManager;
 import org.argouml.ui.targetmanager.TargetEvent;
 import org.argouml.ui.targetmanager.TargetListener;
 import org.argouml.ui.targetmanager.TargetManager;
@@ -53,25 +57,31 @@
  * 
  * @author Tom Morris
  */
-public final class ProjectActions implements TargetListener {
+public final class ProjectActions
+        implements TargetListener, PropertyChangeListener {
 
     private static ProjectActions theInstance;
     
     private ProjectActions() {
         super();
+        undoAction = 
+            new ActionUndo(Translator.localize("action.undo"));
+        undoAction.setEnabled(false);
+        redoAction = 
+            new ActionRedo(Translator.localize("action.redo"));
+        redoAction.setEnabled(false);
         TargetManager.getInstance().addTargetListener(this);
+        DefaultUndoManager.getInstance().addPropertyChangeListener(this);
     }
 
     /**
      * The action to undo the last user interaction.
      */
-    private final ActionUndo undoAction = 
-        new ActionUndo(Translator.localize("action.undo"));
+    private final ActionUndo undoAction;
     /**
      * The action to redo the last undone action.
      */
-    private final AbstractAction redoAction = 
-        new ActionRedo(Translator.localize("action.redo"));
+    private final AbstractAction redoAction;
 
     /**
      * Singleton retrieval method for the projectbrowser. Lazely instantiates
@@ -223,4 +233,21 @@
     private static void setTarget(Object o) {
         TargetManager.getInstance().setTarget(o);
     }
+
+    public void propertyChange(PropertyChangeEvent evt) {
+        if (evt.getSource() instanceof UndoManager) {
+            if ("undoLabel".equals(evt.getPropertyName())) {
+                undoAction.putValue(AbstractAction.NAME, evt.getNewValue());
+            }
+            if ("redoLabel".equals(evt.getPropertyName())) {
+                redoAction.putValue(AbstractAction.NAME, evt.getNewValue());
+            }
+            if ("undoable".equals(evt.getPropertyName())) {
+                undoAction.setEnabled((Boolean) evt.getNewValue());
+            }
+            if ("redoable".equals(evt.getPropertyName())) {
+                redoAction.setEnabled((Boolean) evt.getNewValue());
+            }
+        }
+    }
 }

Modified: trunk/src_new/org/argouml/ui/UndoableAction.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src_new/org/argouml/ui/UndoableAction.java?view=diff&rev=13496&p1=trunk/src_new/org/argouml/ui/UndoableAction.java&p2=trunk/src_new/org/argouml/ui/UndoableAction.java&r1=13495&r2=13496
==============================================================================
--- trunk/src_new/org/argouml/ui/UndoableAction.java	(original)
+++ trunk/src_new/org/argouml/ui/UndoableAction.java	2007-09-05 16:19:24-0700
@@ -38,7 +38,6 @@
  */
 public abstract class UndoableAction extends AbstractAction {
 
-
     /*
      * @see javax.swing.AbstractAction.AbstractAction()
      */
@@ -63,6 +62,6 @@
 
     public void actionPerformed(ActionEvent e) {
         final Project p = ProjectManager.getManager().getCurrentProject();
-        p.getUndoManager().startInteraction();
+        p.getUndoManager().startInteraction((String) getValue(AbstractAction.NAME));
     }
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.