[SOLVED] QUndoStack multiple steps
-
Hello,
Could someone please help me to figure out how to do multiple undos, basically group undo or redo event together.
Basically, I have a node with arrows pointing to a different node, when I delete it, I'm deleting it's arrows as well and putting all events in undo stack. Now when I press undo button I want the node and it's arrows to reappear, so far I have to click 3-4 times to get all the arrows back.
I hope what I wrote makes sense, it's kinda difficult to explain.
I looked into QUndoGroup, if I understood correctly it's for having multiple Undo stacks in your application rather than grouping events.
Best Regards
Raivis -
I'm not sure if my solution is good enough, I don't like it myself but it works.
Basically what I came up with was:
- Create a dummy command, which doesn't do anything, except gets into the undo stack
- When you want to set that this is the group, before and after your command was executed push the dummy command in.
- In your Redo and Undo functions, check if undo or redo text is equal to the dummy command, then just repeat undo +1 iteration until you get to the other dummy
It's pretty difficult to explain in words, but the concept is very easy, and as I said I don't like it.
Here some code snippets from my app about this issue:@void MainWindow::undoAction()
{
if(undoStack->canUndo())
{
if(undoStack->undoText() == "Undo Redo Group Node at (0, 0)")
{
undoStack->undo();
while(undoStack->undoText() != "Undo Redo Group Node at (0, 0)") undoStack->undo();
}
undoStack->undo();
}
canIUndoOrRedo();
}@
Similar to undo, you have to do to redo as well.Here is have I group two commands together:
@undoStack->push( new UndoRedoGroupCommand() );
undoStack->push(new DeleteBlockCommand(currentItem,scene));
undoStack->push(new DeleteBlockCommand(lineItem,scene));
undoStack->push( new UndoRedoGroupCommand() );@Hopefully it will help someone, and if anybody comes up with a more proper way of grouping undos / redos together, I'm very eager to hear it.
-
Hi,
[quote author="xcoder" date="1349364379"]Hello,
Basically, I have a node with arrows pointing to a different node, when I delete it, I'm deleting it's arrows as well and putting all events in undo stack. Now when I press undo button I want the node and it's arrows to reappear, so far I have to click 3-4 times to get all the arrows back.
[/quote]I know another method, but the node must "know" it's associated arrows. Something like this:
@
class Node
{
private:
QList<Arrow *> myArrows;
};
@Now, when you deletes a node, you must store the node and it's arrows, then hide it. If you press redo button, the node and it's arrows is shown. Something like this:
@
class deleteNode
{
public:
deleteNode()
{
// store node and it's arrows
}void redo()
{
// hide node and it's arrows
}void undo()
{
// show node and it's arrows
}
};
@As an ilustrative example, you can use this files ("mQDeleteCommand.h":http://code.google.com/p/scaphandre/source/browse/trunk/src/commands/mQDeleteCommand.h and "mQDeleteCommand.cpp":http://code.google.com/p/scaphandre/source/browse/trunk/src/commands/mQDeleteCommand.cpp). Where Outsiders act as Arrows, and if arrows can connect with another arrows are stored recursively.
I don't know if this is the proper way that you want, but is the way that I used.
Mario.
-
Hi Mario,
I looked at the code, looks interesting. I'll try to do it this way again, before I was trying to do the undo stack similar how you described it, but I failed :)
Kind Regards
Raivis -
Hi xcoder,
to achieve this grouping, the QUnbdoStack has the method beginMacro/endMacro.
This is some code of mine, where I use it:@
m_undoStack->beginMacro(tr("Paste data from clipboard to article categories"));
int nRowMin = qMax(qMin(rTopLeft.row(), rBottomRight.row()), 0);
updateOrAddEntries(pMimeData, nRowMin, tr("paste data to article categories"));
m_undoStack->endMacro();
@