From 1774f6d9bf98d19715197b5ffd7faaa780254841 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 24 Mar 2016 11:12:05 +0100 Subject: [PATCH 1/2] moved ref num assingment from instance creation to save procedure --- apps/opencs/model/doc/savingstages.cpp | 35 ++++++++++++---- apps/opencs/model/tools/mergestages.cpp | 1 + apps/opencs/model/world/ref.cpp | 2 +- apps/opencs/model/world/ref.hpp | 1 + apps/opencs/model/world/refcollection.cpp | 1 + apps/opencs/view/render/instancemode.cpp | 19 +-------- apps/opencs/view/world/referencecreator.cpp | 45 --------------------- apps/opencs/view/world/referencecreator.hpp | 7 +--- 8 files changed, 34 insertions(+), 77 deletions(-) diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index af9c380a3..775496a19 100644 --- a/apps/opencs/model/doc/savingstages.cpp +++ b/apps/opencs/model/doc/savingstages.cpp @@ -265,13 +265,29 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages) std::map >::const_iterator references = mState.getSubRecords().find (Misc::StringUtils::lowerCase (cell.get().mId)); - if (cell.isModified() || + if (cell.isModified() || cell.mState == CSMWorld::RecordBase::State_Deleted || references!=mState.getSubRecords().end()) { CSMWorld::Cell cellRecord = cell.get(); bool interior = cellRecord.mId.substr (0, 1)!="#"; + // count new references and adjust RefNumCount accordingsly + int newRefNum = cellRecord.mRefNumCounter; + + if (references!=mState.getSubRecords().end()) + { + for (std::deque::const_iterator iter (references->second.begin()); + iter!=references->second.end(); ++iter) + { + const CSMWorld::Record& ref = + mDocument.getData().getReferences().getRecord (*iter); + + if (ref.get().mNew) + ++cellRecord.mRefNumCounter; + } + } + // write cell data writer.startRecord (cellRecord.sRecordId); @@ -309,11 +325,16 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages) stream << "#" << index.first << " " << index.second; } - // An empty mOriginalCell is meant to indicate that it is the same as - // the current cell. It is possible that a moved ref is moved again. - if ((refRecord.mOriginalCell.empty() ? refRecord.mCell : refRecord.mOriginalCell) + if (refRecord.mNew) + { + refRecord.mRefNum.mIndex = newRefNum++; + } + else if ((refRecord.mOriginalCell.empty() ? refRecord.mCell : refRecord.mOriginalCell) != stream.str() && !interior) { + // An empty mOriginalCell is meant to indicate that it is the same as + // the current cell. It is possible that a moved ref is moved again. + ESM::MovedCellRef moved; moved.mRefNum = refRecord.mRefNum; @@ -350,7 +371,7 @@ int CSMDoc::WritePathgridCollectionStage::setup() void CSMDoc::WritePathgridCollectionStage::perform (int stage, Messages& messages) { ESM::ESMWriter& writer = mState.getWriter(); - const CSMWorld::Record& pathgrid = + const CSMWorld::Record& pathgrid = mDocument.getData().getPathgrids().getRecord (stage); if (pathgrid.isModified() || pathgrid.mState == CSMWorld::RecordBase::State_Deleted) @@ -386,7 +407,7 @@ int CSMDoc::WriteLandCollectionStage::setup() void CSMDoc::WriteLandCollectionStage::perform (int stage, Messages& messages) { ESM::ESMWriter& writer = mState.getWriter(); - const CSMWorld::Record& land = + const CSMWorld::Record& land = mDocument.getData().getLand().getRecord (stage); if (land.isModified() || land.mState == CSMWorld::RecordBase::State_Deleted) @@ -412,7 +433,7 @@ int CSMDoc::WriteLandTextureCollectionStage::setup() void CSMDoc::WriteLandTextureCollectionStage::perform (int stage, Messages& messages) { ESM::ESMWriter& writer = mState.getWriter(); - const CSMWorld::Record& landTexture = + const CSMWorld::Record& landTexture = mDocument.getData().getLandTextures().getRecord (stage); if (landTexture.isModified() || landTexture.mState == CSMWorld::RecordBase::State_Deleted) diff --git a/apps/opencs/model/tools/mergestages.cpp b/apps/opencs/model/tools/mergestages.cpp index f52e8886f..4d4835ece 100644 --- a/apps/opencs/model/tools/mergestages.cpp +++ b/apps/opencs/model/tools/mergestages.cpp @@ -99,6 +99,7 @@ void CSMTools::MergeReferencesStage::perform (int stage, CSMDoc::Messages& messa ref.mRefNum.mIndex = mIndex[Misc::StringUtils::lowerCase (ref.mCell)]++; ref.mRefNum.mContentFile = 0; + ref.mNew = false; CSMWorld::Record newRecord ( CSMWorld::RecordBase::State_ModifiedOnly, 0, &ref); diff --git a/apps/opencs/model/world/ref.cpp b/apps/opencs/model/world/ref.cpp index e6345ce71..0439b9448 100644 --- a/apps/opencs/model/world/ref.cpp +++ b/apps/opencs/model/world/ref.cpp @@ -6,7 +6,7 @@ #include "cellcoordinates.hpp" -CSMWorld::CellRef::CellRef() +CSMWorld::CellRef::CellRef() : mNew (true) { mRefNum.mIndex = 0; mRefNum.mContentFile = 0; diff --git a/apps/opencs/model/world/ref.hpp b/apps/opencs/model/world/ref.hpp index c60392221..5d10a3a1b 100644 --- a/apps/opencs/model/world/ref.hpp +++ b/apps/opencs/model/world/ref.hpp @@ -13,6 +13,7 @@ namespace CSMWorld std::string mId; std::string mCell; std::string mOriginalCell; + bool mNew; // new reference, not counted yet, ref num not assigned yet CellRef(); diff --git a/apps/opencs/model/world/refcollection.cpp b/apps/opencs/model/world/refcollection.cpp index 65251a81d..506f9027e 100644 --- a/apps/opencs/model/world/refcollection.cpp +++ b/apps/opencs/model/world/refcollection.cpp @@ -19,6 +19,7 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool Cell& cell2 = base ? cell.mBase : cell.mModified; CellRef ref; + ref.mNew = false; ESM::MovedCellRef mref; bool isDeleted = false; diff --git a/apps/opencs/view/render/instancemode.cpp b/apps/opencs/view/render/instancemode.cpp index 32373c395..4c708242a 100644 --- a/apps/opencs/view/render/instancemode.cpp +++ b/apps/opencs/view/render/instancemode.cpp @@ -421,24 +421,7 @@ void CSVRender::InstanceMode::dropEvent (QDropEvent* event) CSMWorld::Columns::ColumnId_ReferenceableId), QString::fromUtf8 (iter->getId().c_str())); - std::auto_ptr incrementCommand; - - if (!noCell) - { - // increase reference count in cell - QModelIndex countIndex = cellTable.getModelIndex (cellId, - cellTable.findColumnIndex (CSMWorld::Columns::ColumnId_RefNumCounter)); - - int count = cellTable.data (countIndex).toInt(); - - incrementCommand.reset ( - new CSMWorld::ModifyCommand (cellTable, countIndex, count+1)); - } - - CSMWorld::CommandMacro macro (document.getUndoStack()); - macro.push (createCommand.release()); - if (incrementCommand.get()) - macro.push (incrementCommand.release()); + document.getUndoStack().push (createCommand.release()); dropped = true; } diff --git a/apps/opencs/view/world/referencecreator.cpp b/apps/opencs/view/world/referencecreator.cpp index 5428f4e95..182e374b7 100644 --- a/apps/opencs/view/world/referencecreator.cpp +++ b/apps/opencs/view/world/referencecreator.cpp @@ -26,51 +26,6 @@ void CSVWorld::ReferenceCreator::configureCreateCommand (CSMWorld::CreateCommand findColumnIndex (CSMWorld::Columns::ColumnId_Cell); command.addValue (cellIdColumn, mCell->text()); - - // Set RefNum - int refNumColumn = dynamic_cast ( - *getData().getTableModel (CSMWorld::UniversalId::Type_References)). - findColumnIndex (CSMWorld::Columns::ColumnId_RefNum); - - command.addValue (refNumColumn, getRefNumCount()); -} - -void CSVWorld::ReferenceCreator::pushCommand (std::auto_ptr command, - const std::string& id) -{ - // get the old count - std::string cellId = mCell->text().toUtf8().constData(); - - CSMWorld::IdTable& cellTable = dynamic_cast ( - *getData().getTableModel (CSMWorld::UniversalId::Type_Cells)); - - int countColumn = cellTable.findColumnIndex (CSMWorld::Columns::ColumnId_RefNumCounter); - - QModelIndex countIndex = cellTable.getModelIndex (cellId, countColumn); - - int count = cellTable.data (countIndex).toInt(); - - // command for incrementing counter - std::auto_ptr increment (new CSMWorld::ModifyCommand - (cellTable, countIndex, count+1)); - - CSMWorld::CommandMacro macro (getUndoStack(), command->text()); - GenericCreator::pushCommand (command, id); - macro.push (increment.release()); -} - -int CSVWorld::ReferenceCreator::getRefNumCount() const -{ - std::string cellId = mCell->text().toUtf8().constData(); - - CSMWorld::IdTable& cellTable = dynamic_cast ( - *getData().getTableModel (CSMWorld::UniversalId::Type_Cells)); - - int countColumn = cellTable.findColumnIndex (CSMWorld::Columns::ColumnId_RefNumCounter); - - QModelIndex countIndex = cellTable.getModelIndex (cellId, countColumn); - - return cellTable.data (countIndex).toInt(); } CSVWorld::ReferenceCreator::ReferenceCreator (CSMWorld::Data& data, QUndoStack& undoStack, diff --git a/apps/opencs/view/world/referencecreator.hpp b/apps/opencs/view/world/referencecreator.hpp index c230d0126..31010fa24 100644 --- a/apps/opencs/view/world/referencecreator.hpp +++ b/apps/opencs/view/world/referencecreator.hpp @@ -29,11 +29,6 @@ namespace CSVWorld virtual void configureCreateCommand (CSMWorld::CreateCommand& command) const; - virtual void pushCommand (std::auto_ptr command, - const std::string& id); - - int getRefNumCount() const; - public: ReferenceCreator (CSMWorld::Data& data, QUndoStack& undoStack, @@ -50,7 +45,7 @@ namespace CSVWorld /// Focus main input widget virtual void focus(); - + private slots: void cellChanged(); From 8f699b5d397093e75301b006c9803b946b60bbdb Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 2 Apr 2016 10:08:03 +0200 Subject: [PATCH 2/2] avoid creating move tags for instances that exist only in the currently edited content file --- apps/opencs/model/doc/savingstages.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index 775496a19..ee65248e2 100644 --- a/apps/opencs/model/doc/savingstages.cpp +++ b/apps/opencs/model/doc/savingstages.cpp @@ -11,6 +11,7 @@ #include #include "../world/infocollection.hpp" +#include "../world/cellcoordinates.hpp" #include "document.hpp" #include "savingstate.hpp" @@ -238,7 +239,7 @@ void CSMDoc::CollectionReferencesStage::perform (int stage, Messages& messages) // An empty mOriginalCell is meant to indicate that it is the same as // the current cell. It is possible that a moved ref is moved again. if ((record.get().mOriginalCell.empty() ? - record.get().mCell : record.get().mOriginalCell) != stream.str() && !interior) + record.get().mCell : record.get().mOriginalCell) != stream.str() && !interior && record.mState!=CSMWorld::RecordBase::State_ModifiedOnly && !record.get().mNew) indices.push_back (i); else indices.push_front (i); @@ -283,7 +284,10 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages) const CSMWorld::Record& ref = mDocument.getData().getReferences().getRecord (*iter); - if (ref.get().mNew) + if (ref.get().mNew || + (!interior && ref.mState==CSMWorld::RecordBase::State_ModifiedOnly && + /// \todo consider worldspace + CSMWorld::CellCoordinates (ref.get().getCellIndex()).getId("")!=ref.get().mCell)) ++cellRecord.mRefNumCounter; } } @@ -325,7 +329,9 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages) stream << "#" << index.first << " " << index.second; } - if (refRecord.mNew) + if (refRecord.mNew || + (!interior && ref.mState==CSMWorld::RecordBase::State_ModifiedOnly && + refRecord.mCell!=stream.str())) { refRecord.mRefNum.mIndex = newRefNum++; }