I have a custom QAbstractTableModel descendant that I want to extend with a QUndoStack to allow undo/redo of changes to the model.
How would I do this nicely? I have two ideas but I am unhappy with both.
I created a simple QUndoCommand descendant:
{
public:
: m_index(index),
m_oldValue(oldValue),
m_newValue(newValue)
{}
void undo();
void redo();
private:
const QVariant m_oldValue;
///< Holds the old value. const QVariant m_newValue;
///< Holds the new value. };
void SetDataCommand::undo()
{
if (m_index.isValid())
const_cast<QAbstractItemModel *>(m_index.model())->setData(m_index, m_oldValue);
}
void SetDataCommand::redo()
{
if (m_index.isValid())
const_cast<QAbstractItemModel *>(m_index.model())->setData(m_index, m_newValue);
}
class SetDataCommand: public QUndoCommand
{
public:
SetDataCommand(const QPersistentModelIndex & index, const QVariant & oldValue, const QVariant & newValue)
: m_index(index),
m_oldValue(oldValue),
m_newValue(newValue)
{}
void undo();
void redo();
private:
const QPersistentModelIndex m_index; ///< Holds the model index.
const QVariant m_oldValue; ///< Holds the old value.
const QVariant m_newValue; ///< Holds the new value.
};
void SetDataCommand::undo()
{
if (m_index.isValid())
const_cast<QAbstractItemModel *>(m_index.model())->setData(m_index, m_oldValue);
}
void SetDataCommand::redo()
{
if (m_index.isValid())
const_cast<QAbstractItemModel *>(m_index.model())->setData(m_index, m_newValue);
}
To copy to clipboard, switch view to plain text mode
Idea 1:
The setData(...) method changes the model data and adds the undo command to the undo stack. Problem: Pushing the undo command to the stack will execute the redo() method of the command.
Workaround: The redo command has a boolean guard that will lead the first call to redo() do nothing. Both undo() and redo() would use a user role to make changes to the model to prevent the creation of undo commands when using undo/redo.
Idea 2:
The setData() method creates the undo command which will then lead to the call to redo() that will call some protected? custom method that will modify the model. The problem is that I would not know in the setData() method, if the undo command succeded with redo() and would return true without knowing.
Workaround: I would have to do all checks before creating the undo command to be certain that the undo command will not fail to modify the data.
Thanks in advance for comments and ideas,
-Jens
Bookmarks