1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-03-30 09:36:43 +00:00

Fix editor undo for nested data.

This commit is contained in:
Aesylwinn 2016-05-23 15:51:36 -04:00
parent 6199663bd8
commit 774e1497b6
3 changed files with 83 additions and 56 deletions

View file

@ -17,7 +17,13 @@
CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelIndex& index, CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelIndex& index,
const QVariant& new_, QUndoCommand* parent) const QVariant& new_, QUndoCommand* parent)
: QUndoCommand (parent), mModel (&model), mIndex (index), mNew (new_), mHasRecordState(false), mOldRecordState(CSMWorld::RecordBase::State_BaseOnly) : QUndoCommand (parent)
, mModel (&model)
, mIndex (index)
, mNew (new_)
, mHasRecordState(false)
, mOldRecordState(CSMWorld::RecordBase::State_BaseOnly)
, mModifyNestedCommand(0)
{ {
if (QAbstractProxyModel *proxy = dynamic_cast<QAbstractProxyModel *> (&model)) if (QAbstractProxyModel *proxy = dynamic_cast<QAbstractProxyModel *> (&model))
{ {
@ -28,40 +34,57 @@ CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelI
if (mIndex.parent().isValid()) if (mIndex.parent().isValid())
{ {
setText ("Modify " + dynamic_cast<CSMWorld::IdTree*>(mModel)->nestedHeaderData ( IdTree& tree = static_cast<CSMWorld::IdTree&>(*mModel);
mIndex.parent().column(), mIndex.column(), Qt::Horizontal, Qt::DisplayRole).toString());
mModifyNestedCommand = new ModifyNestedCommand(tree, mIndex, new_, this);
setText(mModifyNestedCommand->text());
} }
else else
{ {
setText ("Modify " + mModel->headerData (mIndex.column(), Qt::Horizontal, Qt::DisplayRole).toString()); setText ("Modify " + mModel->headerData (mIndex.column(), Qt::Horizontal, Qt::DisplayRole).toString());
}
// Remember record state before the modification // Remember record state before the modification
if (CSMWorld::IdTable *table = dynamic_cast<IdTable *>(mModel)) if (CSMWorld::IdTable *table = dynamic_cast<IdTable *>(mModel))
{
mHasRecordState = true;
int stateColumnIndex = table->findColumnIndex(Columns::ColumnId_Modification);
int rowIndex = mIndex.row();
if (mIndex.parent().isValid())
{ {
rowIndex = mIndex.parent().row(); mHasRecordState = true;
} int stateColumnIndex = table->findColumnIndex(Columns::ColumnId_Modification);
mRecordStateIndex = table->index(rowIndex, stateColumnIndex); int rowIndex = mIndex.row();
mOldRecordState = static_cast<CSMWorld::RecordBase::State>(table->data(mRecordStateIndex).toInt()); if (mIndex.parent().isValid())
{
rowIndex = mIndex.parent().row();
}
mRecordStateIndex = table->index(rowIndex, stateColumnIndex);
mOldRecordState = static_cast<CSMWorld::RecordBase::State>(table->data(mRecordStateIndex).toInt());
}
} }
} }
void CSMWorld::ModifyCommand::redo() void CSMWorld::ModifyCommand::redo()
{ {
mOld = mModel->data (mIndex, Qt::EditRole); if (mModifyNestedCommand)
mModel->setData (mIndex, mNew); {
mModifyNestedCommand->redo();
}
else
{
mOld = mModel->data (mIndex, Qt::EditRole);
mModel->setData (mIndex, mNew);
}
} }
void CSMWorld::ModifyCommand::undo() void CSMWorld::ModifyCommand::undo()
{ {
mModel->setData (mIndex, mOld); if (mModifyNestedCommand)
{
mModifyNestedCommand->undo();
}
else
{
mModel->setData (mIndex, mOld);
}
if (mHasRecordState) if (mHasRecordState)
{ {
mModel->setData(mRecordStateIndex, mOldRecordState); mModel->setData(mRecordStateIndex, mOldRecordState);
@ -301,37 +324,29 @@ void CSMWorld::UpdateCellCommand::undo()
mModel.setData (mIndex, mOld); mModel.setData (mIndex, mOld);
} }
CSMWorld::ModifyNestedCommand::ModifyNestedCommand (IdTree& model, const std::string& id, int nestedRow, CSMWorld::ModifyNestedCommand::ModifyNestedCommand (IdTree& model, const QModelIndex& index, const QVariant& new_,
int nestedColumn, int parentColumn, const QVariant& new_, QUndoCommand* parent) QUndoCommand* parent)
: QUndoCommand(parent) : QUndoCommand(parent)
, NestedTableStoring(model, id, parentColumn) , NestedTableStoring(model, index.parent())
, mModel(model) , mModel(model)
, mId(id) , mIndex(index)
, mNestedRow(nestedRow)
, mNestedColumn(nestedColumn)
, mParentColumn(parentColumn)
, mNew(new_) , mNew(new_)
{ {
std::string title = model.headerData(parentColumn, Qt::Horizontal, Qt::DisplayRole).toString().toUtf8().constData(); setText("Modify " + model.nestedHeaderData(mIndex.parent().column(), mIndex.column(), Qt::Horizontal,
setText (("Modify " + title + " sub-table of " + mId).c_str()); Qt::DisplayRole).toString());
QModelIndex parentIndex = mModel.getModelIndex(mId, mParentColumn); mModifyParentCommand = new ModifyCommand(mModel, mIndex.parent(), mIndex.parent().data(Qt::EditRole), this);
mModifyParentCommand = new ModifyCommand(mModel, parentIndex, parentIndex.data(Qt::EditRole), this);
} }
void CSMWorld::ModifyNestedCommand::redo() void CSMWorld::ModifyNestedCommand::redo()
{ {
QModelIndex parentIndex = mModel.getModelIndex(mId, mParentColumn); mModel.setData(mIndex, mNew);
QModelIndex nestedIndex = mModel.index(mNestedRow, mNestedColumn, parentIndex);
mModel.setData(nestedIndex, mNew);
mModifyParentCommand->redo(); mModifyParentCommand->redo();
} }
void CSMWorld::ModifyNestedCommand::undo() void CSMWorld::ModifyNestedCommand::undo()
{ {
QModelIndex parentIndex = mModel.getModelIndex(mId, mParentColumn); mModel.setNestedTable(mIndex.parent(), getOld());
mModel.setNestedTable(parentIndex, getOld());
mModifyParentCommand->undo(); mModifyParentCommand->undo();
} }
@ -402,7 +417,14 @@ void CSMWorld::AddNestedCommand::undo()
} }
CSMWorld::NestedTableStoring::NestedTableStoring(const IdTree& model, const std::string& id, int parentColumn) CSMWorld::NestedTableStoring::NestedTableStoring(const IdTree& model, const std::string& id, int parentColumn)
: mOld(model.nestedTable(model.getModelIndex(id, parentColumn))) {} : mOld(model.nestedTable(model.getModelIndex(id, parentColumn)))
{
}
CSMWorld::NestedTableStoring::NestedTableStoring(const IdTree& model, const QModelIndex& parentIndex)
: mOld(model.nestedTable(parentIndex))
{
}
CSMWorld::NestedTableStoring::~NestedTableStoring() CSMWorld::NestedTableStoring::~NestedTableStoring()
{ {

View file

@ -23,6 +23,7 @@ namespace CSMWorld
class IdTree; class IdTree;
struct RecordBase; struct RecordBase;
struct NestedTableWrapperBase; struct NestedTableWrapperBase;
class ModifyNestedCommand;
class ModifyCommand : public QUndoCommand class ModifyCommand : public QUndoCommand
{ {
@ -35,6 +36,8 @@ namespace CSMWorld
QModelIndex mRecordStateIndex; QModelIndex mRecordStateIndex;
CSMWorld::RecordBase::State mOldRecordState; CSMWorld::RecordBase::State mOldRecordState;
ModifyNestedCommand* mModifyNestedCommand;
public: public:
ModifyCommand (QAbstractItemModel& model, const QModelIndex& index, const QVariant& new_, ModifyCommand (QAbstractItemModel& model, const QModelIndex& index, const QVariant& new_,
@ -191,6 +194,7 @@ namespace CSMWorld
public: public:
NestedTableStoring(const IdTree& model, const std::string& id, int parentColumn); NestedTableStoring(const IdTree& model, const std::string& id, int parentColumn);
NestedTableStoring(const IdTree& model, const QModelIndex& parentIndex);
~NestedTableStoring(); ~NestedTableStoring();
@ -203,13 +207,7 @@ namespace CSMWorld
{ {
IdTree& mModel; IdTree& mModel;
std::string mId; QModelIndex mIndex;
int mNestedRow;
int mNestedColumn;
int mParentColumn;
QVariant mNew; QVariant mNew;
@ -218,8 +216,7 @@ namespace CSMWorld
public: public:
ModifyNestedCommand (IdTree& model, const std::string& id, int nestedRow, int nestedColumn, ModifyNestedCommand (IdTree& model, const QModelIndex& index, const QVariant& new_, QUndoCommand* parent = 0);
int parentColumn, const QVariant& new_, QUndoCommand* parent = 0);
virtual void redo(); virtual void redo();

View file

@ -254,6 +254,7 @@ namespace CSVRender
int posY = clampToCell(static_cast<int>(localCoords.y())); int posY = clampToCell(static_cast<int>(localCoords.y()));
int posZ = clampToCell(static_cast<int>(localCoords.z())); int posZ = clampToCell(static_cast<int>(localCoords.z()));
int recordIndex = mPathgridCollection.getIndex (mId);
int parentColumn = mPathgridCollection.findColumnIndex(CSMWorld::Columns::ColumnId_PathgridPoints); int parentColumn = mPathgridCollection.findColumnIndex(CSMWorld::Columns::ColumnId_PathgridPoints);
int posXColumn = mPathgridCollection.searchNestedColumnIndex(parentColumn, int posXColumn = mPathgridCollection.searchNestedColumnIndex(parentColumn,
@ -265,13 +266,14 @@ namespace CSVRender
int posZColumn = mPathgridCollection.searchNestedColumnIndex(parentColumn, int posZColumn = mPathgridCollection.searchNestedColumnIndex(parentColumn,
CSMWorld::Columns::ColumnId_PathgridPosZ); CSMWorld::Columns::ColumnId_PathgridPosZ);
QModelIndex parent = model->index(recordIndex, parentColumn);
int row = static_cast<int>(source->mPoints.size()); int row = static_cast<int>(source->mPoints.size());
// Add node // Add node
commands.push(new CSMWorld::AddNestedCommand(*model, mId, row, parentColumn)); commands.push(new CSMWorld::AddNestedCommand(*model, mId, row, parentColumn));
commands.push(new CSMWorld::ModifyNestedCommand(*model, mId, row, posXColumn, parentColumn, posX)); commands.push(new CSMWorld::ModifyNestedCommand(*model, model->index(row, posXColumn, parent), posX));
commands.push(new CSMWorld::ModifyNestedCommand(*model, mId, row, posYColumn, parentColumn, posY)); commands.push(new CSMWorld::ModifyNestedCommand(*model, model->index(row, posYColumn, parent), posY));
commands.push(new CSMWorld::ModifyNestedCommand(*model, mId, row, posZColumn, parentColumn, posZ)); commands.push(new CSMWorld::ModifyNestedCommand(*model, model->index(row, posZColumn, parent), posZ));
} }
else else
{ {
@ -294,6 +296,7 @@ namespace CSVRender
CSMWorld::IdTree* model = dynamic_cast<CSMWorld::IdTree*>(mData.getTableModel( CSMWorld::IdTree* model = dynamic_cast<CSMWorld::IdTree*>(mData.getTableModel(
CSMWorld::UniversalId::Type_Pathgrids)); CSMWorld::UniversalId::Type_Pathgrids));
int recordIndex = mPathgridCollection.getIndex(mId);
int parentColumn = mPathgridCollection.findColumnIndex(CSMWorld::Columns::ColumnId_PathgridPoints); int parentColumn = mPathgridCollection.findColumnIndex(CSMWorld::Columns::ColumnId_PathgridPoints);
int posXColumn = mPathgridCollection.searchNestedColumnIndex(parentColumn, int posXColumn = mPathgridCollection.searchNestedColumnIndex(parentColumn,
@ -305,18 +308,20 @@ namespace CSVRender
int posZColumn = mPathgridCollection.searchNestedColumnIndex(parentColumn, int posZColumn = mPathgridCollection.searchNestedColumnIndex(parentColumn,
CSMWorld::Columns::ColumnId_PathgridPosZ); CSMWorld::Columns::ColumnId_PathgridPosZ);
QModelIndex parent = model->index(recordIndex, parentColumn);
for (size_t i = 0; i < mSelected.size(); ++i) for (size_t i = 0; i < mSelected.size(); ++i)
{ {
const CSMWorld::Pathgrid::Point& point = source->mPoints[mSelected[i]]; const CSMWorld::Pathgrid::Point& point = source->mPoints[mSelected[i]];
int row = static_cast<int>(mSelected[i]); int row = static_cast<int>(mSelected[i]);
commands.push(new CSMWorld::ModifyNestedCommand(*model, mId, row, posXColumn, parentColumn, commands.push(new CSMWorld::ModifyNestedCommand(*model, model->index(row, posXColumn, parent),
clampToCell(point.mX + offsetX))); clampToCell(point.mX + offsetX)));
commands.push(new CSMWorld::ModifyNestedCommand(*model, mId, row, posYColumn, parentColumn, commands.push(new CSMWorld::ModifyNestedCommand(*model, model->index(row, posYColumn, parent),
clampToCell(point.mY + offsetY))); clampToCell(point.mY + offsetY)));
commands.push(new CSMWorld::ModifyNestedCommand(*model, mId, row, posZColumn, parentColumn, commands.push(new CSMWorld::ModifyNestedCommand(*model, model->index(row, posZColumn, parent),
clampToCell(point.mZ + offsetZ))); clampToCell(point.mZ + offsetZ)));
} }
} }
@ -560,6 +565,7 @@ namespace CSVRender
CSMWorld::IdTree* model = dynamic_cast<CSMWorld::IdTree*>(mData.getTableModel( CSMWorld::IdTree* model = dynamic_cast<CSMWorld::IdTree*>(mData.getTableModel(
CSMWorld::UniversalId::Type_Pathgrids)); CSMWorld::UniversalId::Type_Pathgrids));
int recordIndex = mPathgridCollection.getIndex(mId);
int parentColumn = mPathgridCollection.findColumnIndex(CSMWorld::Columns::ColumnId_PathgridEdges); int parentColumn = mPathgridCollection.findColumnIndex(CSMWorld::Columns::ColumnId_PathgridEdges);
int edge0Column = mPathgridCollection.searchNestedColumnIndex(parentColumn, int edge0Column = mPathgridCollection.searchNestedColumnIndex(parentColumn,
@ -568,19 +574,21 @@ namespace CSVRender
int edge1Column = mPathgridCollection.searchNestedColumnIndex(parentColumn, int edge1Column = mPathgridCollection.searchNestedColumnIndex(parentColumn,
CSMWorld::Columns::ColumnId_PathgridEdge1); CSMWorld::Columns::ColumnId_PathgridEdge1);
QModelIndex parent = model->index(recordIndex, parentColumn);
if (edgeExists(source, node1, node2) == -1) if (edgeExists(source, node1, node2) == -1)
{ {
// Set first edge last since that reorders the edge list // Set first edge last since that reorders the edge list
commands.push(new CSMWorld::AddNestedCommand(*model, mId, 0, parentColumn)); commands.push(new CSMWorld::AddNestedCommand(*model, mId, 0, parentColumn));
commands.push(new CSMWorld::ModifyNestedCommand(*model, mId, 0, edge1Column, parentColumn, node2)); commands.push(new CSMWorld::ModifyNestedCommand(*model, model->index(0, edge1Column, parent), node2));
commands.push(new CSMWorld::ModifyNestedCommand(*model, mId, 0, edge0Column, parentColumn, node1)); commands.push(new CSMWorld::ModifyNestedCommand(*model, model->index(0, edge0Column, parent), node1));
} }
if (edgeExists(source, node2, node1) == -1) if (edgeExists(source, node2, node1) == -1)
{ {
commands.push(new CSMWorld::AddNestedCommand(*model, mId, 0, parentColumn)); commands.push(new CSMWorld::AddNestedCommand(*model, mId, 0, parentColumn));
commands.push(new CSMWorld::ModifyNestedCommand(*model, mId, 0, edge1Column, parentColumn, node1)); commands.push(new CSMWorld::ModifyNestedCommand(*model, model->index(0, edge1Column, parent), node1));
commands.push(new CSMWorld::ModifyNestedCommand(*model, mId, 0, edge0Column, parentColumn, node2)); commands.push(new CSMWorld::ModifyNestedCommand(*model, model->index(0, edge0Column, parent), node2));
} }
} }