5 #include "rs_undoable.h"
12 #warning "!!! Need to deal with setAutoDelete() Qt3->Qt4 !!!"
13 // undoList.setAutoDelete(true);
18 /*virtual*/ RS_Undo::~RS_Undo()
20 while (!undoList.isEmpty())
21 delete undoList.takeFirst();
25 * @return Number of Cycles that can be undone.
27 int RS_Undo::countUndoCycles()
29 RS_DEBUG->print("RS_Undo::countUndoCycles");
31 return undoPointer + 1;
35 * @return Number of Cycles that can be redone.
37 int RS_Undo::countRedoCycles()
39 RS_DEBUG->print("RS_Undo::countRedoCycles");
41 return (int)undoList.count() - 1 - undoPointer;
45 * Adds an Undo Cycle at the current position in the list.
46 * All Cycles after the new one are removed and the Undoabels
49 void RS_Undo::addUndoCycle(RS_UndoCycle * i)
51 RS_DEBUG->print("RS_Undo::addUndoCycle");
53 undoList.insert(++undoPointer, i);
55 RS_DEBUG->print("RS_Undo::addUndoCycle: ok");
59 * Starts a new cycle for one undo step. Every undoable that is
60 * added after calling this method goes into this cycle.
62 void RS_Undo::startUndoCycle()
64 RS_DEBUG->print("RS_Undo::startUndoCycle");
66 // definitely delete Undo Cycles and all Undoables in them
67 // that cannot be redone now:
68 while ((int)undoList.count() > undoPointer + 1 && (int)undoList.count() > 0)
70 RS_UndoCycle * l = undoList.last();
74 RS_Undoable * u = NULL;
79 u = l->getFirstUndoable();
83 // Remove the pointer from _all_ cycles:
84 // for(RS_UndoCycle * l2=undoList.first(); l2!=NULL; l2=undoList.next())
85 // l2->removeUndoable(u);
86 for(int i=0; i<undoList.size(); i++)
87 undoList[i]->removeUndoable(u);
89 // Delete the Undoable for good:
103 // Remove obsolete undo cycles:
104 undoList.removeLast();
107 currentCycle = new RS_UndoCycle();
111 * Adds an undoable to the current undo cycle.
113 void RS_Undo::addUndoable(RS_Undoable * u)
115 RS_DEBUG->print("RS_Undo::addUndoable");
117 if (currentCycle != NULL)
119 currentCycle->addUndoable(u);
123 RS_DEBUG->print(RS_Debug::D_WARNING, "RS_Undo::addUndoable(): No undo cycle active.");
128 * Ends the current undo cycle.
130 void RS_Undo::endUndoCycle()
132 addUndoCycle(currentCycle);
137 * Undoes the last undo cycle.
141 RS_DEBUG->print("RS_Undo::undo");
143 if (undoPointer >= 0)
145 RS_UndoCycle * i = undoList.at(undoPointer);
149 // for(RS_Undoable * u=i->undoables.first(); u!=NULL; u=i->undoables.next())
150 // u->changeUndoState();
151 for(int j=0; j<i->undoables.size(); j++)
152 i->undoables[j]->changeUndoState();
160 * Redoes the undo cycle which was at last undone.
164 RS_DEBUG->print("RS_Undo::redo");
166 if (undoPointer + 1 < (int)undoList.count())
169 RS_UndoCycle * i = undoList.at(undoPointer);
173 // for(RS_Undoable * u=i->undoables.first(); u!=NULL; u=i->undoables.next())
174 // u->changeUndoState();
175 for(int j=0; j<i->undoables.size(); j++)
176 i->undoables[j]->changeUndoState();
182 * @return The undo item that is next if we're about to undo
185 RS_UndoCycle * RS_Undo::getUndoCycle()
187 RS_UndoCycle * ret = NULL;
189 RS_DEBUG->print("RS_Undo::getUndoCycle");
191 if (undoPointer >= 0 && undoPointer < (int)undoList.count())
192 ret = undoList.at(undoPointer);
194 RS_DEBUG->print("RS_Undo::getUndoCycle: OK");
200 * @return The redo item that is next if we're about to redo
203 RS_UndoCycle * RS_Undo::getRedoCycle()
205 RS_DEBUG->print("RS_Undo::getRedoCycle");
207 if (undoPointer + 1 >= 0 && undoPointer + 1 < (int)undoList.count())
208 return undoList.at(undoPointer + 1);
214 * Dumps the undo list to stdout.
216 std::ostream & operator<<(std::ostream & os, RS_Undo & l)
218 os << "Undo List: " << "\n";
219 os << " Pointer is at: " << l.undoPointer << "\n";
221 // for(RS_UndoCycle * i=l.undoList.first(); i!=NULL; i=l.undoList.next())
222 for(int j=0; j<l.undoList.size(); j++)
224 RS_UndoCycle * i = l.undoList[j];
226 // if (l.undoList.at() == l.undoPointer)
227 if (j == l.undoPointer)
238 //huh? how is this getting defined???
242 * Testing Undoables, Undo Cycles and the Undo container.
244 /*static*/ bool RS_Undo::test()
251 std::cout << "Testing RS_Undo\n";
252 std::cout << " Adding 500 cycles..";
254 // Add 500 Undo Cycles with i Undoables in every Cycle
255 for(i=1; i<=500; ++i)
257 //c1 = new RS_UndoCycle();
258 undo.startUndoCycle();
262 u1 = new RS_Undoable();
264 undo.addUndoable(u1);
267 //undo.addUndoCycle(c1);
273 assert(undo.countUndoCycles() == 500);
274 assert(undo.countRedoCycles() == 0);
276 std::cout << " Undo 500 cycles..";
277 // Undo all 500 cycles
279 for(i=1; i<=500; ++i)
284 assert(undo.countUndoCycles() == 0);
285 assert(undo.countRedoCycles() == 500);
287 std::cout << " Redo 500 cycles..";
288 // Redo all 500 cycles
290 for(i=1; i<=500; ++i)
295 assert(undo.countUndoCycles() == 500);
296 assert(undo.countRedoCycles() == 0);
298 std::cout << " Undo 250 cycles..";
299 // Undo all 500 cycles
301 for(i=1; i<=250; ++i)
306 assert(undo.countUndoCycles() == 250);
307 assert(undo.countRedoCycles() == 250);
309 std::cout << " Adding 10 cycles..";
313 //c1 = new RS_UndoCycle();
314 undo.startUndoCycle();
318 u1 = new RS_Undoable();
319 //c1->addUndoable(u1);
320 undo.addUndoable(u1);
323 //undo.addUndoCycle(c1);
329 assert(undo.countUndoCycles() == 260);
330 assert(undo.countRedoCycles() == 0);
332 std::cout << " Undo 5 cycles..";
339 assert(undo.countUndoCycles() == 255);
340 assert(undo.countRedoCycles() == 5);
342 std::cout << " Redo 5 cycles..";
349 assert(undo.countUndoCycles() == 260);
350 assert(undo.countRedoCycles() == 0);
352 std::cout << " Undo 15 cycles..";
359 assert(undo.countUndoCycles() == 245);
360 assert(undo.countRedoCycles() == 15);
362 std::cout << " Adding 1 cycle..";
366 //c1 = new RS_UndoCycle();
367 undo.startUndoCycle();
371 u1 = new RS_Undoable();
372 //c1->addUndoable(u1);
373 undo.addUndoable(u1);
376 //undo.addUndoCycle(c1);
382 assert(undo.countUndoCycles() == 246);
383 assert(undo.countRedoCycles() == 0);