Reputation: 3124
How can I remove a specific command from a QUndoStack
?
This command can be given by its index or pointer.
Upvotes: 0
Views: 1736
Reputation: 2179
As @dtech has pointed out, it does not make sense to undo a command which is not at the most recently pushed command (i.e., the command at top of the stack).
It does, however, make sense to undo the most recently pushed command.
And QUndoStack
provides a very convenient way to do this: QUndoStack::undo()
.
But, this does not delete the command, as it will still be available through QUndoStack::push(...)
. To truly delete the command, it must be marked obsolete before undoing it:
auto* cmd = const_cast<QUndoCommand*>(undo_stack.command(undo_stack.count()-1));
cmd->undo(); // must be called explicitly
cmd->setObsolete(true);
undo_stack.undo();
It requires a const_cast
, so I'd call it a hack. But for me, it works.
Upvotes: 3
Reputation: 1125
If you are using Qt 5.9, the QUndoStack::command(int index)
and QUndoCommand::setObsolete(bool obsolete)
functions are probably what you are looking for. The relevant docs from the QUndoStack::redo()
command provide the explanation for how an obsoleted command is handled:
If
QUndoCommand::isObsolete()
returns true for the current command, then the command will be deleted from the stack. Additionally, if the clean index is greater than or equal to the current command index, then the clean index is reset.
Upvotes: 7
Reputation: 49309
That's the thing about stacks - you only work on top of the stack. You can push and you can pop. You don't remove stuff from the middle of the stack.
In an undo-redo scenario this is even more important, as the order of commands must be diligently preserved for the whole thing to work. Otherwise you will break it.
Which is why it is called an "undo stack" and not "reverse arbitrary action whatchamacallit".
There is QUndoStack::setIndex(int idx)
which will undo all commands until the provided index. But you cannot really remove only a specific command. You need to undo all commands until you reach and remove the one you want.
Upvotes: 2