b302b2182c87cb42b04b1e3a283ec1b05e1ef9a9
[potlatch2.git] / net / systemeD / halcyon / connection / MainUndoStack.as
1 package net.systemeD.halcyon.connection {
2
3     import flash.events.*;
4
5     public class MainUndoStack extends EventDispatcher {
6         private static const GLOBAL_INSTANCE:MainUndoStack = new MainUndoStack();
7         
8         public static function getGlobalStack():MainUndoStack {
9             return GLOBAL_INSTANCE;
10         }
11         
12         private var undoActions:Array = [];
13         private var redoActions:Array = [];
14
15         /*
16          * Performs the action, then puts it on the undo stack.
17          *
18          * If you want to delay execution don't put it on this
19          * stack -- find another one.
20          */
21         public function addAction(action:UndoableAction):void {
22             trace("doing "+action);
23             var result:uint = action.doAction();
24             
25             switch ( result ) {
26             
27             case UndoableAction.FAIL:
28                 throw new Error("Failure performing "+action);
29                 
30             case UndoableAction.NO_CHANGE:
31                 // nothing to do, and don't add to stack
32                 break;
33                 
34             case UndoableAction.SUCCESS:
35             default:
36                 if ( undoActions.length > 0 ) {
37                     var previous:UndoableAction = undoActions[undoActions.length - 1];
38                     var isMerged:Boolean = action.mergePrevious(previous);
39                     if ( isMerged ) {
40                                                 UndoableEntityAction(action).wasDirty = UndoableEntityAction(previous).wasDirty;
41                                                 UndoableEntityAction(action).connectionWasDirty = UndoableEntityAction(previous).connectionWasDirty;
42                         undoActions.pop();
43                                         }
44                 }
45                 undoActions.push(action);
46                 redoActions = [];
47                 dispatchEvent(new Event("new_undo_item"));
48                 dispatchEvent(new Event("new_redo_item"));
49                 break;
50                 
51             }
52         }
53         
54         /*
55          * Call to kill the undo queue -- the user will not be able to undo
56          * anything they previously did after this is called.
57          */
58         public function breakUndo():void {
59             undoActions = [];
60             redoActions = [];
61         }
62         
63         [Bindable(event="new_undo_item")]
64         public function canUndo():Boolean {
65             return undoActions.length > 0;
66         }
67         
68         [Bindable(event="new_redo_item")]
69         public function canRedo():Boolean {
70             return redoActions.length > 0;
71         }
72         
73         public function undo():void {
74                         if (!undoActions.length) { return; }
75             var action:UndoableAction = undoActions.pop();
76             trace("undoing "+action);
77             action.undoAction();
78             redoActions.push(action);
79             dispatchEvent(new Event("new_undo_item"));
80             dispatchEvent(new Event("new_redo_item"));
81         }
82         
83         public function redo():void {
84                         if (!redoActions.length) { return; }
85             var action:UndoableAction = redoActions.pop();
86             trace("redoing "+action);
87             action.doAction();
88             undoActions.push(action);
89             dispatchEvent(new Event("new_undo_item"));
90             dispatchEvent(new Event("new_redo_item"));
91         }
92        
93     }
94 }