comparison clients/editor/plugins/HistoryManager.py @ 255:51cc05d862f2

Merged editor_rewrite branch to trunk. This contains changes that may break compatibility against existing clients. For a list of changes that may affect your client, see: http://wiki.fifengine.de/Changes_to_pychan_and_FIFE_in_editor_rewrite_branch
author cheesesucker@33b003aa-7bff-0310-803a-e67f0ece8222
date Mon, 08 Jun 2009 16:00:02 +0000
parents
children e893afb4963b
comparison
equal deleted inserted replaced
254:10b5f7f36dd4 255:51cc05d862f2
1 # coding: utf-8
2
3 import pychan
4 from pychan import widgets, tools, attrs, internal
5 import scripts
6 import scripts.plugin as plugin
7 from scripts.events import *
8 from scripts.gui.action import Action, ActionGroup
9 import fife
10 from fife import Color
11 from scripts import undomanager
12 import scripts.gui
13 from scripts.gui.panel import Panel
14 import pdb
15
16 class HistoryManager(plugin.Plugin):
17 def __init__(self):
18 self.editor = None
19 self.engine = None
20
21 self._enabled = False
22 self.undomanager = None
23
24 def enable(self):
25 if self._enabled is True:
26 return
27
28 self.editor = scripts.editor.getEditor()
29 self.engine = self.editor.getEngine()
30
31 self._undoGroup = ActionGroup(name=u"UndoGroup")
32 self._showAction = Action(u"History manager", checkable=True)
33 self._undoAction = Action(u"Undo", "gui/icons/undo.png")
34 self._redoAction = Action(u"Redo", "gui/icons/redo.png")
35 self._nextAction = Action(u"Next branch", "gui/icons/next_branch.png")
36 self._prevAction = Action(u"Previous branch", "gui/icons/previous_branch.png")
37 scripts.gui.action.activated.connect(self.toggle, sender=self._showAction)
38 scripts.gui.action.activated.connect(self._undo, sender=self._undoAction)
39 scripts.gui.action.activated.connect(self._redo, sender=self._redoAction)
40 scripts.gui.action.activated.connect(self._next, sender=self._nextAction)
41 scripts.gui.action.activated.connect(self._prev, sender=self._prevAction)
42
43 self._undoGroup.addAction(self._undoAction)
44 self._undoGroup.addAction(self._redoAction)
45 self._undoGroup.addAction(self._nextAction)
46 self._undoGroup.addAction(self._prevAction)
47
48 self.editor._toolsMenu.addAction(self._showAction)
49 self.editor._editMenu.insertAction(self._undoGroup, 0)
50 self.editor._editMenu.insertSeparator(position=1)
51
52 events.postMapShown.connect(self.update)
53 undomanager.changed.connect(self.update)
54
55 self.buildGui()
56
57 def disable(self):
58 if self._enabled is False:
59 return
60
61 self.gui.hide()
62 self.removeAllChildren()
63
64 events.postMapShown.disconnect(self.update)
65 undomanager.changed.disconnect(self.update)
66
67 scripts.gui.action.activated.connect(self.toggle, sender=self._showAction)
68 scripts.gui.action.activated.disconnect(self._undo, sender=self._undoAction)
69 scripts.gui.action.activated.disconnect(self._redo, sender=self._redoAction)
70 scripts.gui.action.activated.disconnect(self._next, sender=self._nextAction)
71 scripts.gui.action.activated.disconnect(self._prev, sender=self._prevAction)
72
73 self.editor._toolsMenu.removeAction(self._showAction)
74 self.editor._toolsMenu.removeAction(self._undoGroup)
75
76
77 def isEnabled(self):
78 return self._enabled;
79
80 def getName(self):
81 return "History manager"
82
83
84 def buildGui(self):
85 self.gui = Panel(title=u"History")
86 self.scrollarea = widgets.ScrollArea(min_size=(200,300))
87 self.list = widgets.ListBox()
88 self.list.capture(self._itemSelected)
89
90 self.gui.addChild(self.scrollarea)
91 self.scrollarea.addChild(self.list)
92
93 self.gui.position_technique = "right:center"
94
95 def _itemSelected(self):
96 mapview = self.editor.getActiveMapView()
97 if mapview is None:
98 return
99
100 undomanager = mapview.getController().getUndoManager()
101
102 stackitem = self.list.selected_item.item
103 if stackitem == undomanager.current_item:
104 #print "Selected current item"
105 return
106
107 searchlist = []
108 searchlist2 = []
109 parent = stackitem
110 branch = parent.next
111 while parent is not None:
112 if parent is undomanager.first_item or len(parent._branches) > 1:
113 searchlist.append( (parent, branch) )
114 branch = parent
115 parent = parent.parent
116
117 current_item = undomanager.current_item
118
119 parent = current_item
120 branch = parent.next
121 while parent is not None:
122 if parent is undomanager.first_item or len(parent._branches) > 1:
123 searchlist2.append( (parent, branch) )
124 branch = parent
125 parent = parent.parent
126
127 searchlist.reverse()
128 searchlist2.reverse()
129
130 # Remove duplicate entries, except the last duplicate, so we don't undo
131 # more items than necessary
132 sl = len(searchlist);
133 if len(searchlist2) < sl:
134 sl = len(searchlist2)
135 for s in range(sl):
136 if searchlist[s][0] != searchlist[s][0]:
137 searchlist = searchlist[s-1:]
138
139 s_item = searchlist[0][0]
140
141 # Undo until we reach the first shared parent
142 i = 0
143 item = current_item
144 while item is not None:
145 if item == s_item:
146 undomanager.undo(i)
147 current_item = item
148 break
149 i += 1
150 item = item.previous
151 else:
152 print "Nada (undo)"
153 return
154
155 # Switch branches
156 for s_item in searchlist:
157 if s_item[0].setBranch(s_item[1]) is False:
158 print "Warning: HistoryManager: Switching branch failed for: ", s_item
159
160 # Redo to stackitem
161 item = current_item
162 i = 0
163 while item is not None:
164 if item == stackitem:
165 undomanager.redo(i)
166 break
167 i += 1
168 item = item.next
169 else:
170 print "Nada (redo)"
171
172 # Select the current item, important to see if the undo/redo didn't work as expected
173 self.update()
174
175
176 def recursiveUpdate(self, item, indention, parent=None, branchstr="-"):
177 items = []
178
179 branchnr = 0
180
181 class _ListItem:
182 def __init__(self, str, item, parent):
183 self.str = str
184 self.item = item
185 self.parent = parent
186
187 def __str__(self):
188 return self.str
189
190 while item is not None:
191 listitem = _ListItem(u" "*indention + branchstr + " " + item.object.name, item, parent)
192 items.append(listitem)
193 branchnr = -1
194
195 for branch in item._branches:
196 branchnr += 1
197 if branchnr == 0:
198 continue
199
200 items.extend(self.recursiveUpdate(branch, indention+2, listitem, str(branchnr)))
201
202 if len(item._branches) > 0:
203 item = item._branches[0]
204 else:
205 break
206 #item = item.next
207
208 return items
209
210 def update(self):
211 mapview = self.editor.getActiveMapView()
212 if mapview is None:
213 self.list.items = []
214 return
215
216 self.undomanager = undomanager = mapview.getController().getUndoManager()
217 items = []
218 items = self.recursiveUpdate(undomanager.first_item, 0)
219
220 self.list.items = items
221 i = 0
222 for it in items:
223 if it.item == undomanager.current_item:
224 self.list.selected = i
225 break
226 i += 1
227 self.scrollarea.adaptLayout()
228
229 def show(self):
230 self.update()
231 self.gui.show()
232 self._showAction.setChecked(True)
233
234 def hide(self):
235 self.gui.setDocked(False)
236 self.gui.hide()
237 self._showAction.setChecked(False)
238
239 def _undo(self):
240 if self.undomanager:
241 self.undomanager.undo()
242
243 def _redo(self):
244 if self.undomanager:
245 self.undomanager.redo()
246
247 def _next(self):
248 if self.undomanager:
249 self.undomanager.nextBranch()
250
251 def _prev(self):
252 if self.undomanager:
253 self.undomanager.previousBranch()
254
255 def toggle(self):
256 if self.gui.isVisible() or self.gui.isDocked():
257 self.hide()
258 else:
259 self.show()