diff --git a/apps/opencs/model/world/commands.cpp b/apps/opencs/model/world/commands.cpp index b48d6eba2c..308b5386e0 100644 --- a/apps/opencs/model/world/commands.cpp +++ b/apps/opencs/model/world/commands.cpp @@ -17,7 +17,13 @@ CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelIndex& index, 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 (&model)) { @@ -28,40 +34,57 @@ CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelI if (mIndex.parent().isValid()) { - setText ("Modify " + dynamic_cast(mModel)->nestedHeaderData ( - mIndex.parent().column(), mIndex.column(), Qt::Horizontal, Qt::DisplayRole).toString()); + IdTree& tree = static_cast(*mModel); + + mModifyNestedCommand = new ModifyNestedCommand(tree, mIndex, new_, this); + setText(mModifyNestedCommand->text()); } else { setText ("Modify " + mModel->headerData (mIndex.column(), Qt::Horizontal, Qt::DisplayRole).toString()); - } - // Remember record state before the modification - if (CSMWorld::IdTable *table = dynamic_cast(mModel)) - { - mHasRecordState = true; - int stateColumnIndex = table->findColumnIndex(Columns::ColumnId_Modification); - - int rowIndex = mIndex.row(); - if (mIndex.parent().isValid()) + // Remember record state before the modification + if (CSMWorld::IdTable *table = dynamic_cast(mModel)) { - rowIndex = mIndex.parent().row(); - } + mHasRecordState = true; + int stateColumnIndex = table->findColumnIndex(Columns::ColumnId_Modification); - mRecordStateIndex = table->index(rowIndex, stateColumnIndex); - mOldRecordState = static_cast(table->data(mRecordStateIndex).toInt()); + int rowIndex = mIndex.row(); + if (mIndex.parent().isValid()) + { + rowIndex = mIndex.parent().row(); + } + + mRecordStateIndex = table->index(rowIndex, stateColumnIndex); + mOldRecordState = static_cast(table->data(mRecordStateIndex).toInt()); + } } } void CSMWorld::ModifyCommand::redo() { - mOld = mModel->data (mIndex, Qt::EditRole); - mModel->setData (mIndex, mNew); + if (mModifyNestedCommand) + { + mModifyNestedCommand->redo(); + } + else + { + mOld = mModel->data (mIndex, Qt::EditRole); + mModel->setData (mIndex, mNew); + } } void CSMWorld::ModifyCommand::undo() { - mModel->setData (mIndex, mOld); + if (mModifyNestedCommand) + { + mModifyNestedCommand->undo(); + } + else + { + mModel->setData (mIndex, mOld); + } + if (mHasRecordState) { mModel->setData(mRecordStateIndex, mOldRecordState); @@ -301,37 +324,29 @@ void CSMWorld::UpdateCellCommand::undo() mModel.setData (mIndex, mOld); } -CSMWorld::ModifyNestedCommand::ModifyNestedCommand (IdTree& model, const std::string& id, int nestedRow, - int nestedColumn, int parentColumn, const QVariant& new_, QUndoCommand* parent) +CSMWorld::ModifyNestedCommand::ModifyNestedCommand (IdTree& model, const QModelIndex& index, const QVariant& new_, + QUndoCommand* parent) : QUndoCommand(parent) - , NestedTableStoring(model, id, parentColumn) + , NestedTableStoring(model, index.parent()) , mModel(model) - , mId(id) - , mNestedRow(nestedRow) - , mNestedColumn(nestedColumn) - , mParentColumn(parentColumn) + , mIndex(index) , mNew(new_) { - std::string title = model.headerData(parentColumn, Qt::Horizontal, Qt::DisplayRole).toString().toUtf8().constData(); - setText (("Modify " + title + " sub-table of " + mId).c_str()); + setText("Modify " + model.nestedHeaderData(mIndex.parent().column(), mIndex.column(), Qt::Horizontal, + Qt::DisplayRole).toString()); - QModelIndex parentIndex = mModel.getModelIndex(mId, mParentColumn); - mModifyParentCommand = new ModifyCommand(mModel, parentIndex, parentIndex.data(Qt::EditRole), this); + mModifyParentCommand = new ModifyCommand(mModel, mIndex.parent(), mIndex.parent().data(Qt::EditRole), this); } void CSMWorld::ModifyNestedCommand::redo() { - QModelIndex parentIndex = mModel.getModelIndex(mId, mParentColumn); - QModelIndex nestedIndex = mModel.index(mNestedRow, mNestedColumn, parentIndex); - mModel.setData(nestedIndex, mNew); + mModel.setData(mIndex, mNew); mModifyParentCommand->redo(); } - void CSMWorld::ModifyNestedCommand::undo() { - QModelIndex parentIndex = mModel.getModelIndex(mId, mParentColumn); - mModel.setNestedTable(parentIndex, getOld()); + mModel.setNestedTable(mIndex.parent(), getOld()); mModifyParentCommand->undo(); } @@ -402,7 +417,14 @@ void CSMWorld::AddNestedCommand::undo() } 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() { diff --git a/apps/opencs/model/world/commands.hpp b/apps/opencs/model/world/commands.hpp index b51720df8a..d0aed97c70 100644 --- a/apps/opencs/model/world/commands.hpp +++ b/apps/opencs/model/world/commands.hpp @@ -23,6 +23,7 @@ namespace CSMWorld class IdTree; struct RecordBase; struct NestedTableWrapperBase; + class ModifyNestedCommand; class ModifyCommand : public QUndoCommand { @@ -35,6 +36,8 @@ namespace CSMWorld QModelIndex mRecordStateIndex; CSMWorld::RecordBase::State mOldRecordState; + ModifyNestedCommand* mModifyNestedCommand; + public: ModifyCommand (QAbstractItemModel& model, const QModelIndex& index, const QVariant& new_, @@ -191,6 +194,7 @@ namespace CSMWorld public: NestedTableStoring(const IdTree& model, const std::string& id, int parentColumn); + NestedTableStoring(const IdTree& model, const QModelIndex& parentIndex); ~NestedTableStoring(); @@ -203,13 +207,7 @@ namespace CSMWorld { IdTree& mModel; - std::string mId; - - int mNestedRow; - - int mNestedColumn; - - int mParentColumn; + QModelIndex mIndex; QVariant mNew; @@ -218,8 +216,7 @@ namespace CSMWorld public: - ModifyNestedCommand (IdTree& model, const std::string& id, int nestedRow, int nestedColumn, - int parentColumn, const QVariant& new_, QUndoCommand* parent = 0); + ModifyNestedCommand (IdTree& model, const QModelIndex& index, const QVariant& new_, QUndoCommand* parent = 0); virtual void redo(); diff --git a/apps/opencs/view/render/pathgrid.cpp b/apps/opencs/view/render/pathgrid.cpp index 939558be96..b3b582b7a1 100644 --- a/apps/opencs/view/render/pathgrid.cpp +++ b/apps/opencs/view/render/pathgrid.cpp @@ -254,6 +254,7 @@ namespace CSVRender int posY = clampToCell(static_cast(localCoords.y())); int posZ = clampToCell(static_cast(localCoords.z())); + int recordIndex = mPathgridCollection.getIndex (mId); int parentColumn = mPathgridCollection.findColumnIndex(CSMWorld::Columns::ColumnId_PathgridPoints); int posXColumn = mPathgridCollection.searchNestedColumnIndex(parentColumn, @@ -265,13 +266,14 @@ namespace CSVRender int posZColumn = mPathgridCollection.searchNestedColumnIndex(parentColumn, CSMWorld::Columns::ColumnId_PathgridPosZ); + QModelIndex parent = model->index(recordIndex, parentColumn); int row = static_cast(source->mPoints.size()); // Add node 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, mId, row, posYColumn, parentColumn, posY)); - commands.push(new CSMWorld::ModifyNestedCommand(*model, mId, row, posZColumn, parentColumn, posZ)); + commands.push(new CSMWorld::ModifyNestedCommand(*model, model->index(row, posXColumn, parent), posX)); + commands.push(new CSMWorld::ModifyNestedCommand(*model, model->index(row, posYColumn, parent), posY)); + commands.push(new CSMWorld::ModifyNestedCommand(*model, model->index(row, posZColumn, parent), posZ)); } else { @@ -294,6 +296,7 @@ namespace CSVRender CSMWorld::IdTree* model = dynamic_cast(mData.getTableModel( CSMWorld::UniversalId::Type_Pathgrids)); + int recordIndex = mPathgridCollection.getIndex(mId); int parentColumn = mPathgridCollection.findColumnIndex(CSMWorld::Columns::ColumnId_PathgridPoints); int posXColumn = mPathgridCollection.searchNestedColumnIndex(parentColumn, @@ -305,18 +308,20 @@ namespace CSVRender int posZColumn = mPathgridCollection.searchNestedColumnIndex(parentColumn, CSMWorld::Columns::ColumnId_PathgridPosZ); + QModelIndex parent = model->index(recordIndex, parentColumn); + for (size_t i = 0; i < mSelected.size(); ++i) { const CSMWorld::Pathgrid::Point& point = source->mPoints[mSelected[i]]; int row = static_cast(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))); - 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))); - 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))); } } @@ -560,6 +565,7 @@ namespace CSVRender CSMWorld::IdTree* model = dynamic_cast(mData.getTableModel( CSMWorld::UniversalId::Type_Pathgrids)); + int recordIndex = mPathgridCollection.getIndex(mId); int parentColumn = mPathgridCollection.findColumnIndex(CSMWorld::Columns::ColumnId_PathgridEdges); int edge0Column = mPathgridCollection.searchNestedColumnIndex(parentColumn, @@ -568,19 +574,21 @@ namespace CSVRender int edge1Column = mPathgridCollection.searchNestedColumnIndex(parentColumn, CSMWorld::Columns::ColumnId_PathgridEdge1); + QModelIndex parent = model->index(recordIndex, parentColumn); + if (edgeExists(source, node1, node2) == -1) { // Set first edge last since that reorders the edge list 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, mId, 0, edge0Column, parentColumn, node1)); + commands.push(new CSMWorld::ModifyNestedCommand(*model, model->index(0, edge1Column, parent), node2)); + commands.push(new CSMWorld::ModifyNestedCommand(*model, model->index(0, edge0Column, parent), node1)); } if (edgeExists(source, node2, node1) == -1) { 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, mId, 0, edge0Column, parentColumn, node2)); + commands.push(new CSMWorld::ModifyNestedCommand(*model, model->index(0, edge1Column, parent), node1)); + commands.push(new CSMWorld::ModifyNestedCommand(*model, model->index(0, edge0Column, parent), node2)); } }