1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
#!/usr/bin/env python
###########################################################################
#
# UndoRedoStack implements the usual undo/redo capabilities of a GUI
#
# Author: Orest Shardt
# Created: July 23, 2007
#
###########################################################################
class action:
def __init__(self,act,inv):
self.act = act
self.inv = inv
def undo(self):
#print ("Undo:",self)
self.inv()
def redo(self):
#print ("Redo:",self)
self.act()
def __str__(self):
return "A generic action"
class beginActionGroup:
pass
class endActionGroup:
pass
class actionStack:
def __init__(self):
self.clear()
def add(self,action):
self.undoStack.append(action)
#print ("Added",action)
self.redoStack = []
def undo(self):
if len(self.undoStack) > 0:
op = self.undoStack.pop()
if op is beginActionGroup:
level = 1
self.redoStack.append(endActionGroup)
while level > 0:
op=self.undoStack.pop()
if op is endActionGroup:
level -= 1
self.redoStack.append(beginActionGroup)
elif op is beginActionGroup:
level += 1
self.redoStack.append(endActionGroup)
else:
op.undo()
self.redoStack.append(op)
elif op is endActionGroup:
raise Exception("endActionGroup without previous beginActionGroup")
else:
self.redoStack.append(op)
op.undo()
#print ("undid",op)
else:
pass #print ("nothing to undo")
def redo(self):
if len(self.redoStack) > 0:
op = self.redoStack.pop()
if op is beginActionGroup:
level = 1
self.undoStack.append(endActionGroup)
while level > 0:
op = self.redoStack.pop()
if op is endActionGroup:
level -= 1
self.undoStack.append(beginActionGroup)
elif op is beginActionGroup:
level += 1
self.undoStack.append(endActionGroup)
else:
op.redo()
self.undoStack.append(op)
elif op is endActionGroup:
raise Exception("endActionGroup without previous beginActionGroup")
else:
self.undoStack.append(op)
op.redo()
#print ("redid",op)
else:
pass #print ("nothing to redo")
def setCommitLevel(self):
self.commitLevel = len(self.undoStack)
def changesMade(self):
if len(self.undoStack) != self.commitLevel:
return True
else:
return False
def clear(self):
self.redoStack = []
self.undoStack = []
self.commitLevel = 0
if __name__=='__main__':
import sys
def opq():
print ("action1")
def unopq():
print ("inverse1")
q = action(opq,unopq)
w = action(lambda:sys.stdout.write("action2\n"),lambda:sys.stdout.write("inverse2\n"))
e = action(lambda:sys.stdout.write("action3\n"),lambda:sys.stdout.write("inverse3\n"))
s = actionStack()
s.add(q)
s.add(w)
s.add(e)
|