svn commit: r13484 - trunk/src_new/org/argouml: kernel ui uml/diagram

[email protected]
Newsgroups gmane.comp.lang.uml.argouml.cvs
Message-ID <[email protected]>
Author: bobtarling
Date: 2007-09-03 13:53:50-0700
New Revision: 13484

Removed:
   trunk/src_new/org/argouml/kernel/AbstractCommand.java
Modified:
   trunk/src_new/org/argouml/kernel/AbstractUndoableCommand.java
   trunk/src_new/org/argouml/kernel/ProjectImpl.java
   trunk/src_new/org/argouml/kernel/ProjectManager.java
   trunk/src_new/org/argouml/kernel/UndoManager.java
   trunk/src_new/org/argouml/kernel/UndoableCommand.java
   trunk/src_new/org/argouml/ui/UndoableAction.java
   trunk/src_new/org/argouml/uml/diagram/DiagramUndoManager.java

Log:
Replace command chains with a MacroCommand

Removed: trunk/src_new/org/argouml/kernel/AbstractCommand.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src_new/org/argouml/kernel/AbstractCommand.java?view=auto&rev=13483

Modified: trunk/src_new/org/argouml/kernel/AbstractUndoableCommand.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src_new/org/argouml/kernel/AbstractUndoableCommand.java?view=diff&rev=13484&p1=trunk/src_new/org/argouml/kernel/AbstractUndoableCommand.java&p2=trunk/src_new/org/argouml/kernel/AbstractUndoableCommand.java&r1=13483&r2=13484
==============================================================================
--- trunk/src_new/org/argouml/kernel/AbstractUndoableCommand.java	(original)
+++ trunk/src_new/org/argouml/kernel/AbstractUndoableCommand.java	2007-09-03 13:53:50-0700
@@ -28,8 +28,13 @@
  * The base class for any actions that can be undone by ActionUndo.
  * @author Bob Tarling
  */
-public abstract class AbstractUndoableCommand
-        extends AbstractCommand implements UndoableCommand {
+public abstract class AbstractUndoableCommand implements UndoableCommand {
+    
+    public abstract void execute();
     
     public abstract void undo();
+    
+    public boolean isUndoable() {
+        return true;
+    }
 }

Modified: trunk/src_new/org/argouml/kernel/ProjectImpl.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src_new/org/argouml/kernel/ProjectImpl.java?view=diff&rev=13484&p1=trunk/src_new/org/argouml/kernel/ProjectImpl.java&p2=trunk/src_new/org/argouml/kernel/ProjectImpl.java&r1=13483&r2=13484
==============================================================================
--- trunk/src_new/org/argouml/kernel/ProjectImpl.java	(original)
+++ trunk/src_new/org/argouml/kernel/ProjectImpl.java	2007-09-03 13:53:50-0700
@@ -426,7 +426,7 @@
 
     public void setAuthorname(final String s) {
         final String oldAuthorName = authorname;
-        AbstractCommand memento = new AbstractCommand() {
+        AbstractUndoableCommand memento = new AbstractUndoableCommand() {
             public void execute() {
                 authorname = s;
             }
@@ -435,7 +435,7 @@
                 authorname = oldAuthorName;
             }
         };
-        undoManager.addMemento(memento);
+        undoManager.addCommand(memento);
         memento.execute();
         setSaveEnabled(true);
     }
@@ -448,7 +448,7 @@
 
     public void setAuthoremail(final String s) {
         final String oldAuthorEmail = authoremail;
-        AbstractCommand memento = new AbstractCommand() {
+        AbstractUndoableCommand memento = new AbstractUndoableCommand() {
             public void execute() {
                 authoremail = s;
             }
@@ -457,7 +457,7 @@
                 authoremail = oldAuthorEmail;
             }
         };
-        undoManager.addMemento(memento);
+        undoManager.addCommand(memento);
         memento.execute();
         setSaveEnabled(true);
     }
@@ -480,7 +480,7 @@
 
     public void setDescription(final String s) {
         final String oldDescription = description;
-        AbstractCommand memento = new AbstractCommand() {
+        AbstractUndoableCommand memento = new AbstractUndoableCommand() {
             public void execute() {
                 description = s;
             }
@@ -489,7 +489,7 @@
                 description = oldDescription;
             }
         };
-        undoManager.addMemento(memento);
+        undoManager.addCommand(memento);
         memento.execute();
         setSaveEnabled(true);
     }

Modified: trunk/src_new/org/argouml/kernel/ProjectManager.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src_new/org/argouml/kernel/ProjectManager.java?view=diff&rev=13484&p1=trunk/src_new/org/argouml/kernel/ProjectManager.java&p2=trunk/src_new/org/argouml/kernel/ProjectManager.java&r1=13483&r2=13484
==============================================================================
--- trunk/src_new/org/argouml/kernel/ProjectManager.java	(original)
+++ trunk/src_new/org/argouml/kernel/ProjectManager.java	2007-09-03 13:53:50-0700
@@ -345,7 +345,7 @@
         if (saveAction != null) {
             saveAction.setEnabled(true);
         }
-        AbstractCommand wrappedMemento = new AbstractUndoableCommand() {
+        AbstractUndoableCommand wrappedMemento = new AbstractUndoableCommand() {
             private ModelCommand modelMemento = memento;
             public void undo() {
                 modelMemento.undo();
@@ -358,11 +358,10 @@
             }
             
             public String toString() {
-                return (isStartChain() ? "*" : " ") + "ModelMemento "
-                        + modelMemento;
+                return modelMemento.toString();
             }
 
         };
-        getCurrentProject().getUndoManager().addMemento(wrappedMemento);
+        getCurrentProject().getUndoManager().addCommand(wrappedMemento);
     }
 }

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=13484&p1=trunk/src_new/org/argouml/kernel/UndoManager.java&p2=trunk/src_new/org/argouml/kernel/UndoManager.java&r1=13483&r2=13484
==============================================================================
--- trunk/src_new/org/argouml/kernel/UndoManager.java	(original)
+++ trunk/src_new/org/argouml/kernel/UndoManager.java	2007-09-03 13:53:50-0700
@@ -30,6 +30,7 @@
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
+import java.util.ListIterator;
 
 /**
  * Manages a stacks of Commands to undo and redo.
@@ -49,8 +50,8 @@
     
     // TODO: A UndoChainStack may produce some reasuable code for
     // the undoStack and the redoStack/
-    private List<Command> undoStack = new ArrayList<Command>();
-    private List<Command> redoStack = new ArrayList<Command>();
+    private List<MacroCommand> undoStack = new ArrayList<MacroCommand>();
+    private List<MacroCommand> redoStack = new ArrayList<MacroCommand>();
     
     private static final UndoManager INSTANCE = new UndoManager();
 
@@ -71,16 +72,13 @@
      * Adds a new command to the undo stack.
      * @param command the command.
      */
-    public void addMemento(Command command) {
+    public void addCommand(Command command) {
         if (undoMax == 0) {
             return;
         }
         // Flag the command as to whether it is first in a chain
-        if (newChain) {
-            ((AbstractCommand) command).startChain();
-            // If the command is the first then consider that
-            // there is a new chain being received and clear
-            // the redos
+        final MacroCommand macroCommand;
+        if (newChain || undoStack.isEmpty()) {
             emptyRedo();
             incrementUndoChainCount();
             newChain = false;
@@ -88,8 +86,12 @@
                 // TODO The undo stack is full, dispose
                 // of the oldest chain.
             }
+            macroCommand = new MacroCommand();
+            undoStack.add(macroCommand);
+        } else {
+            macroCommand = undoStack.get(undoChainCount - 1);
         }
-        undoStack.add(command);
+        macroCommand.addCommand(command);
     }
     
     /**
@@ -104,47 +106,23 @@
      * Undo the most recent chain of mementos received by the undo stack
      */
     public void undo() {
-        AbstractUndoableCommand command;
-        boolean startChain = false;
-        do {
-            command = (AbstractUndoableCommand) pop(undoStack);
-            startChain = command.isStartChain();
-            undo(command);
-        } while (!startChain);
-        decrementUndoChainCount();
-        incrementRedoChainCount();
-    }
-    
-    /**
-     * Undo a single command
-     * @param command the command to undo
-     */
-    protected void undo(UndoableCommand command) {
+        MacroCommand command;
+        command = pop(undoStack);
         command.undo();
         redoStack.add(command);
+        decrementUndoChainCount();
+        incrementRedoChainCount();
     }
     
     /**
-     * Redo the most recent chain of mementos received by the undo stack
+     * Redo the most recent MacroCommand received by the redo stack
      */
     public void redo() {
-        do {
-            Command command = pop(redoStack);
-            redo(command);
-        } while(redoStack.size() > 0
-                && !((AbstractCommand)
-                        (redoStack.get(redoStack.size() - 1))).isStartChain());
-        incrementUndoChainCount();
-        decrementRedoChainCount();
-    }
-    
-    /**
-     * Undo a single command
-     * @param command the command to redo
-     */
-    protected void redo(Command command) {
+        MacroCommand command = pop(redoStack);
         command.execute();
         undoStack.add(command);
+        incrementUndoChainCount();
+        decrementRedoChainCount();
     }
     
     /**
@@ -178,11 +156,11 @@
     }
     
     /**
-     * Instructs the UndoManager that the sequence of mementos recieved up
-     * until the next call to newChain all represent one chain of mementos
-     * (ie one undoable user interaction).
+     * Instructs the UndoManager that a new user interaction is about to take
+     * place. All commands received until this is called once more will make
+     * a single undoable unit.
      */
-    public void startChain() {
+    public void startInteraction() {
         newChain = true;
     }
  
@@ -190,7 +168,7 @@
      * Empty a list stack disposing of all mementos.
      * @param list the list of mementos
      */
-    private void emptyStack(List<Command> list) {
+    private void emptyStack(List<MacroCommand> list) {
         // Lets only introduce dispose if we find it's required
         //        for (int i = 0; i < list.size(); ++i) {
         //            list.get(i).dispose();
@@ -198,7 +176,7 @@
         list.clear();
     }
     
-    private Command pop(List<Command> stack) {
+    private MacroCommand pop(List<MacroCommand> stack) {
         return stack.remove(stack.size() - 1);
     }
     
@@ -255,4 +233,57 @@
             fireCanRedo();
         }
     }
+    
+    /**
+     * A MacroCommand is a Command the executes a list of sub-commands.
+     * It represents a single user interaction and contains all the commands
+     * executed as part of that interaction.
+     *
+     * @author Bob
+     */
+    private class MacroCommand extends AbstractUndoableCommand {
+        
+        private List<Command> commands = new ArrayList<Command>();
+        
+        public void undo() {
+            final ListIterator<Command> it =
+                commands.listIterator(commands.size());
+            while (it.hasPrevious()) {
+                ((UndoableCommand) it.previous()).undo();
+            }
+        }
+        
+        public void execute() {
+            final Iterator<Command> it = commands.iterator();
+            while (it.hasNext()) {
+                it.next().execute();
+            }
+        }
+        
+        public boolean isUndoable() {
+            final Iterator<Command> it = commands.iterator();
+            while (it.hasNext()) {
+                final Command command = it.next();
+                if (!(command instanceof UndoableCommand)) {
+                    return false;
+                }
+                if (!((UndoableCommand) command).isUndoable()) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        
+        private void addCommand(Command command) {
+            commands.add(command);
+        }
+        
+        private String getUndoLabel() {
+            return "Undo";
+        }
+        
+        private String getRedoLabel() {
+            return "Redo";
+        }
+    }
 }

Modified: trunk/src_new/org/argouml/kernel/UndoableCommand.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src_new/org/argouml/kernel/UndoableCommand.java?view=diff&rev=13484&p1=trunk/src_new/org/argouml/kernel/UndoableCommand.java&p2=trunk/src_new/org/argouml/kernel/UndoableCommand.java&r1=13483&r2=13484
==============================================================================
--- trunk/src_new/org/argouml/kernel/UndoableCommand.java	(original)
+++ trunk/src_new/org/argouml/kernel/UndoableCommand.java	2007-09-03 13:53:50-0700
@@ -32,7 +32,13 @@
 public interface UndoableCommand extends Command {
 
     /**
-     * To be implemented on the concrete memento to redo an instruction
+     * Perform undo an an undoable command that is in an undoable state
      */
     abstract void undo();
+    
+    /**
+     * To be implemented on the concrete memento to redo an instruction
+     * @return true if the command is undoable
+     */
+    abstract boolean isUndoable();
 }
\ No newline at end of file

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=13484&p1=trunk/src_new/org/argouml/ui/UndoableAction.java&p2=trunk/src_new/org/argouml/ui/UndoableAction.java&r1=13483&r2=13484
==============================================================================
--- trunk/src_new/org/argouml/ui/UndoableAction.java	(original)
+++ trunk/src_new/org/argouml/ui/UndoableAction.java	2007-09-03 13:53:50-0700
@@ -63,6 +63,6 @@
 
     public void actionPerformed(ActionEvent e) {
         final Project p = ProjectManager.getManager().getCurrentProject();
-        p.getUndoManager().startChain();
+        p.getUndoManager().startInteraction();
     }
 }

Modified: trunk/src_new/org/argouml/uml/diagram/DiagramUndoManager.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src_new/org/argouml/uml/diagram/DiagramUndoManager.java?view=diff&rev=13484&p1=trunk/src_new/org/argouml/uml/diagram/DiagramUndoManager.java&p2=trunk/src_new/org/argouml/uml/diagram/DiagramUndoManager.java&r1=13483&r2=13484
==============================================================================
--- trunk/src_new/org/argouml/uml/diagram/DiagramUndoManager.java	(original)
+++ trunk/src_new/org/argouml/uml/diagram/DiagramUndoManager.java	2007-09-03 13:53:50-0700
@@ -66,10 +66,10 @@
         org.argouml.kernel.UndoManager undo = p.getUndoManager();
 
         if (startChain) {
-            undo.startChain();
+            undo.startInteraction();
         }
         
-        undo.addMemento(new DiagramCommand(memento));
+        undo.addCommand(new DiagramCommand(memento));
         
         startChain = false;
     }
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.