From befc7a40781cea62819e8d6de64bb2b848f22f93 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 25 May 2014 15:46:23 +0200 Subject: [PATCH 001/185] adding column for the content of the container --- CMakeLists.txt | 4 -- apps/opencs/model/world/columns.hpp | 1 + apps/opencs/model/world/idtable.cpp | 1 + apps/opencs/model/world/refidadapterimp.cpp | 4 +- apps/opencs/model/world/refidadapterimp.hpp | 7 ++-- apps/opencs/model/world/refidcollection.cpp | 5 ++- apps/opencs/model/world/refiddata.hpp | 42 ++++++++++----------- 7 files changed, 33 insertions(+), 31 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 392fdfc66c..9168d9a5a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,16 +38,12 @@ if(EXISTS ${PROJECT_SOURCE_DIR}/.git) set(GIT_VERSION "${GIT_VERSION_MAJOR}.${GIT_VERSION_MINOR}.${GIT_VERSION_RELEASE}") - if(NOT ${OPENMW_VERSION} STREQUAL ${GIT_VERSION}) - message(FATAL_ERROR "Silly Zini forgot to update the version again...") - else(NOT ${OPENMW_VERSION} STREQUAL ${GIT_VERSION}) set(OPENMW_VERSION_MAJOR ${GIT_VERSION_MAJOR}) set(OPENMW_VERSION_MINOR ${GIT_VERSION_MINOR}) set(OPENMW_VERSION_RELEASE ${GIT_VERSION_RELEASE}) set(OPENMW_VERSION_COMMITHASH "${COMMITHASH}") set(OPENMW_VERSION_TAGHASH "${TAGHASH}") - endif(NOT ${OPENMW_VERSION} STREQUAL ${GIT_VERSION}) message(STATUS "OpenMW version ${OPENMW_VERSION}") else(MATCH) diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 855e89cade..fa9c92e7d6 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -167,6 +167,7 @@ namespace CSMWorld ColumnId_PcRank = 154, ColumnId_Scope = 155, ColumnId_ReferenceableId = 156, + ColumnId_ContainerContent = 157, // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index 50998c36f1..31797d0812 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -130,6 +130,7 @@ void CSMWorld::IdTable::cloneRecord(const std::string& origin, CSMWorld::UniversalId::Type type) { int index = mIdCollection->getAppendIndex (destination); + beginInsertRows (QModelIndex(), index, index); mIdCollection->cloneRecord(origin, destination, type); endInsertRows(); diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index f00e9fc77b..afb61acc6b 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -173,9 +173,9 @@ void CSMWorld::ClothingRefIdAdapter::setData (const RefIdColumn *column, RefIdDa } CSMWorld::ContainerRefIdAdapter::ContainerRefIdAdapter (const NameColumns& columns, - const RefIdColumn *weight, const RefIdColumn *organic, const RefIdColumn *respawn) + const RefIdColumn *weight, const RefIdColumn *organic, const RefIdColumn *respawn, const RefIdColumn *content) : NameRefIdAdapter (UniversalId::Type_Container, columns), mWeight (weight), - mOrganic (organic), mRespawn (respawn) + mOrganic (organic), mRespawn (respawn), mContent(content) {} QVariant CSMWorld::ContainerRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index bd509a86b6..59c8c64614 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -34,7 +34,7 @@ namespace CSMWorld BaseRefIdAdapter (UniversalId::Type type, const BaseColumns& base); virtual std::string getId (const RecordBase& record) const; - + virtual void setId (RecordBase& record, const std::string& id); virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) @@ -57,7 +57,7 @@ namespace CSMWorld { (dynamic_cast&> (record).get().mId) = id; } - + template std::string BaseRefIdAdapter::getId (const RecordBase& record) const { @@ -610,11 +610,12 @@ namespace CSMWorld const RefIdColumn *mWeight; const RefIdColumn *mOrganic; const RefIdColumn *mRespawn; + const RefIdColumn *mContent; public: ContainerRefIdAdapter (const NameColumns& columns, const RefIdColumn *weight, - const RefIdColumn *organic, const RefIdColumn *respawn); + const RefIdColumn *organic, const RefIdColumn *respawn, const RefIdColumn *content); virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) const; diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index f515e34d8e..1745ce957f 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -165,6 +165,9 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn (Columns::ColumnId_Respawn, ColumnBase::Display_Boolean)); const RefIdColumn *respawn = &mColumns.back(); + mColumns.push_back(RefIdColumn (Columns::ColumnId_ContainerContent, ColumnBase::Display_None, ColumnBase::Flag_Dialogue, false, false)); + const RefIdColumn *content = &mColumns.back(); + CreatureColumns creatureColumns (actorsColumns); mColumns.push_back (RefIdColumn (Columns::ColumnId_CreatureType, ColumnBase::Display_CreatureType)); @@ -340,7 +343,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Clothing, new ClothingRefIdAdapter (enchantableColumns, clothingType))); mAdapters.insert (std::make_pair (UniversalId::Type_Container, - new ContainerRefIdAdapter (nameColumns, weightCapacity, organic, respawn))); + new ContainerRefIdAdapter (nameColumns, weightCapacity, organic, respawn, content))); mAdapters.insert (std::make_pair (UniversalId::Type_Creature, new CreatureRefIdAdapter (creatureColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Door, diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index 1b600364c7..535e914ee0 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -231,27 +231,27 @@ namespace CSMWorld void save (int index, ESM::ESMWriter& writer) const; - //RECORD CONTAINERS ACCESS METHODS - const RefIdDataContainer& getBooks() const; - const RefIdDataContainer& getActivators() const; - const RefIdDataContainer& getPotions() const; - const RefIdDataContainer& getApparati() const; - const RefIdDataContainer& getArmors() const; - const RefIdDataContainer& getClothing() const; - const RefIdDataContainer& getContainers() const; - const RefIdDataContainer& getCreatures() const; - const RefIdDataContainer& getDoors() const; - const RefIdDataContainer& getIngredients() const; - const RefIdDataContainer& getCreatureLevelledLists() const; - const RefIdDataContainer& getItemLevelledList() const; - const RefIdDataContainer& getLights() const; - const RefIdDataContainer& getLocpicks() const; - const RefIdDataContainer& getMiscellaneous() const; - const RefIdDataContainer& getNPCs() const; - const RefIdDataContainer& getWeapons() const; - const RefIdDataContainer& getProbes() const; - const RefIdDataContainer& getRepairs() const; - const RefIdDataContainer& getStatics() const; + //RECORD CONTAINERS ACCESS METHODS + const RefIdDataContainer& getBooks() const; + const RefIdDataContainer& getActivators() const; + const RefIdDataContainer& getPotions() const; + const RefIdDataContainer& getApparati() const; + const RefIdDataContainer& getArmors() const; + const RefIdDataContainer& getClothing() const; + const RefIdDataContainer& getContainers() const; + const RefIdDataContainer& getCreatures() const; + const RefIdDataContainer& getDoors() const; + const RefIdDataContainer& getIngredients() const; + const RefIdDataContainer& getCreatureLevelledLists() const; + const RefIdDataContainer& getItemLevelledList() const; + const RefIdDataContainer& getLights() const; + const RefIdDataContainer& getLocpicks() const; + const RefIdDataContainer& getMiscellaneous() const; + const RefIdDataContainer& getNPCs() const; + const RefIdDataContainer& getWeapons() const; + const RefIdDataContainer& getProbes() const; + const RefIdDataContainer& getRepairs() const; + const RefIdDataContainer& getStatics() const; }; } From 41db48720d49d0b87bc1bc8d705bfb4ae7785ef5 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 27 May 2014 14:01:15 +0200 Subject: [PATCH 002/185] does not compile --- apps/opencs/model/world/refidadapter.cpp | 16 +++++- apps/opencs/model/world/refidadapter.hpp | 7 +++ apps/opencs/model/world/refidadapterimp.cpp | 60 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 8 +++ 4 files changed, 90 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/world/refidadapter.cpp b/apps/opencs/model/world/refidadapter.cpp index 94ae38c3c2..283f062feb 100644 --- a/apps/opencs/model/world/refidadapter.cpp +++ b/apps/opencs/model/world/refidadapter.cpp @@ -1,6 +1,20 @@ #include "refidadapter.hpp" +#include "cassert" +#include + CSMWorld::RefIdAdapter::RefIdAdapter() {} -CSMWorld::RefIdAdapter::~RefIdAdapter() {} \ No newline at end of file +CSMWorld::RefIdAdapter::~RefIdAdapter() {} + +QVariant CSMWorld::RefIdAdapter::getData (const CSMWorld::RefIdColumn* column, const CSMWorld::RefIdData& data, int idnex, int subRowIndex, int subColIndex) const +{ + assert(false); + return QVariant(); +} + +void CSMWorld::RefIdAdapter::setData (const CSMWorld::RefIdColumn* column, CSMWorld::RefIdData& data, const QVariant& value, int index, int subRowIndex, int subColIndex) const +{ + assert(false); +} diff --git a/apps/opencs/model/world/refidadapter.hpp b/apps/opencs/model/world/refidadapter.hpp index 0870a2d3e6..673b1f5a44 100644 --- a/apps/opencs/model/world/refidadapter.hpp +++ b/apps/opencs/model/world/refidadapter.hpp @@ -30,6 +30,13 @@ namespace CSMWorld const QVariant& value) const = 0; ///< If the data type does not match an exception is thrown. + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, + int idnex, int subRowIndex, int subColIndex) const; + + virtual void setData (const RefIdColumn *column, RefIdData& data, + const QVariant& value, int index, + int subRowIndex, int subColIndex) const; + virtual std::string getId (const RecordBase& record) const = 0; virtual void setId(RecordBase& record, const std::string& id) = 0; }; diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index afb61acc6b..df64e9f054 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -222,6 +222,66 @@ void CSMWorld::ContainerRefIdAdapter::setData (const RefIdColumn *column, RefIdD NameRefIdAdapter::setData (column, data, index, value); } +void CSMWorld::ContainerRefIdAdapter::setData(const RefIdColumn *column, RefIdData& data, + int index, + const QVariant& value, + int subRowIndex, + int subColIndex) +{ + using RefIdAdapter::setData; + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))); + + if (column==mContent) + { + switch (subColIndex) + { + case 0: + record.get().mInventory.mList.at(subRowIndex).mItem.assign(std::string(value.toString().toUtf8().constData())); + break; + + case 1: + record.get().mInventory.mList.at(subRowIndex).mCount = value.toInt(); + break; + } + } else + { + throw "This column does not hold multiple values."; + } +} + +QVariant CSMWorld::ContainerRefIdAdapter::getData (const CSMWorld::RefIdColumn* column, + const CSMWorld::RefIdData& data, + int index, + int subRowIndex, + int subColIndex) const +{ + using RefIdAdapter::getData; + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))); + + if (column==mContent) + { + const ESM::ContItem& content = record.get().mInventory.mList.at(subRowIndex); + + switch (subColIndex) + { + case 0: + return QString::fromUtf8(content.mItem.toString().c_str()); + + case 1: + return content.mCount; + + default: + throw "Trying to access non-existing column in the nested table!"; + } + } else + { + throw "This column does not hold multiple values."; + } +} + + CSMWorld::CreatureColumns::CreatureColumns (const ActorColumns& actorColumns) : ActorColumns (actorColumns) {} diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 59c8c64614..f295016985 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -617,9 +617,17 @@ namespace CSMWorld ContainerRefIdAdapter (const NameColumns& columns, const RefIdColumn *weight, const RefIdColumn *organic, const RefIdColumn *respawn, const RefIdColumn *content); + using RefIdAdapter::getData; + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index, + int subRowIndex, int subColIndex) const; + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) const; + using RefIdAdapter::setData; + virtual void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value, int subRowIndex, int subColIndex) const; + virtual void setData (const RefIdColumn *column, RefIdData& data, int index, const QVariant& value) const; ///< If the data type does not match an exception is thrown. From 6720d85a04315ddd1d1807dfeb7646b438159790 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 27 May 2014 14:50:21 +0200 Subject: [PATCH 003/185] fixed compilation, thanks greye --- apps/opencs/model/world/refidadapterimp.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index df64e9f054..8c98e18082 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -226,9 +226,8 @@ void CSMWorld::ContainerRefIdAdapter::setData(const RefIdColumn *column, RefIdDa int index, const QVariant& value, int subRowIndex, - int subColIndex) + int subColIndex) const { - using RefIdAdapter::setData; Record& record = static_cast&> ( data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))); @@ -256,7 +255,6 @@ QVariant CSMWorld::ContainerRefIdAdapter::getData (const CSMWorld::RefIdColumn* int subRowIndex, int subColIndex) const { - using RefIdAdapter::getData; const Record& record = static_cast&> ( data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))); From 55d451febef1d0e204d5782b71c9330a2f8cd2d7 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 2 Jun 2014 20:41:37 +0200 Subject: [PATCH 004/185] changes in the model (idtable) to support nested data --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/world/collection.hpp | 8 +++ apps/opencs/model/world/collectionbase.cpp | 1 + apps/opencs/model/world/collectionbase.hpp | 2 + apps/opencs/model/world/columnbase.hpp | 10 +++- apps/opencs/model/world/idtable.cpp | 54 ++++++++++++++++++--- apps/opencs/model/world/idtable.hpp | 11 +++++ apps/opencs/model/world/refidadapter.cpp | 4 +- apps/opencs/model/world/refidadapter.hpp | 4 +- apps/opencs/model/world/refidadapterimp.cpp | 7 ++- apps/opencs/model/world/refidadapterimp.hpp | 6 +-- apps/opencs/model/world/refidcollection.cpp | 12 ++++- apps/opencs/model/world/refidcollection.hpp | 2 + apps/opencs/view/world/dialoguesubview.cpp | 46 ++++++++++-------- apps/opencs/view/world/util.cpp | 3 +- 15 files changed, 133 insertions(+), 39 deletions(-) diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index cbe90b1d3e..d41a015ca5 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -18,7 +18,7 @@ opencs_hdrs_noqt (model/doc opencs_units (model/world - idtable idtableproxymodel regionmap data + idtable idtableproxymodel regionmap data nestedtablemodel ) diff --git a/apps/opencs/model/world/collection.hpp b/apps/opencs/model/world/collection.hpp index 1fb3e1f1db..88ef59ace4 100644 --- a/apps/opencs/model/world/collection.hpp +++ b/apps/opencs/model/world/collection.hpp @@ -82,6 +82,8 @@ namespace CSMWorld virtual QVariant getData (int index, int column) const; + virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const; + virtual void setData (int index, int column, const QVariant& data); virtual const ColumnBase& getColumn (int column) const; @@ -277,6 +279,12 @@ namespace CSMWorld return mColumns.at (column)->get (mRecords.at (index)); } + template + QVariant Collection::getNestedData(int row, int column, int subRow, int subColumn) const + { + return 10; //TODO + } + template void Collection::setData (int index, int column, const QVariant& data) { diff --git a/apps/opencs/model/world/collectionbase.cpp b/apps/opencs/model/world/collectionbase.cpp index 241f198cb2..7b69125750 100644 --- a/apps/opencs/model/world/collectionbase.cpp +++ b/apps/opencs/model/world/collectionbase.cpp @@ -2,6 +2,7 @@ #include "collectionbase.hpp" #include +#include #include "columnbase.hpp" diff --git a/apps/opencs/model/world/collectionbase.hpp b/apps/opencs/model/world/collectionbase.hpp index 442055d5f3..19017047b4 100644 --- a/apps/opencs/model/world/collectionbase.hpp +++ b/apps/opencs/model/world/collectionbase.hpp @@ -44,6 +44,8 @@ namespace CSMWorld virtual QVariant getData (int index, int column) const = 0; + virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const = 0; + virtual void setData (int index, int column, const QVariant& data) = 0; // Not in use. Temporarily removed so that the implementation of RefIdCollection can continue without diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index fe310d0aa4..c8670a03b8 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -89,7 +89,9 @@ namespace CSMWorld Display_RefRecordType, Display_DialogueType, Display_QuestStatusType, - Display_Gender + Display_Gender, + + Display_Nested }; int mColumnId; @@ -125,6 +127,12 @@ namespace CSMWorld throw std::logic_error ("Column " + getTitle() + " is not editable"); } }; + + template + struct NestedColumn + { + virtual QVariant getNested(const Record& record, int subColumn, int subSow) const = 0; + }; } #endif diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index 31797d0812..04d1b333b4 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -36,7 +36,13 @@ QVariant CSMWorld::IdTable::data (const QModelIndex & index, int role) const if (role==Qt::EditRole && !mIdCollection->getColumn (index.column()).isEditable()) return QVariant(); - return mIdCollection->getData (index.row(), index.column()); + if (index.internalId() != 0) + { + std::pair parentAdress(unfoldIndexAdress(index.internalId())); + return mIdCollection->getNestedData(index.row(), index.column(), parentAdress.first, parentAdress.second); + } else { + return mIdCollection->getData (index.row(), index.column()); + } } QVariant CSMWorld::IdTable::headerData (int section, Qt::Orientation orientation, int role) const @@ -97,8 +103,11 @@ bool CSMWorld::IdTable::removeRows (int row, int count, const QModelIndex& paren QModelIndex CSMWorld::IdTable::index (int row, int column, const QModelIndex& parent) const { + unsigned int encodedId = 0; if (parent.isValid()) - return QModelIndex(); + { + encodedId = this->foldIndexAdress(parent); + } if (row<0 || row>=mIdCollection->getSize()) return QModelIndex(); @@ -106,12 +115,24 @@ QModelIndex CSMWorld::IdTable::index (int row, int column, const QModelIndex& pa if (column<0 || column>=mIdCollection->getColumns()) return QModelIndex(); - return createIndex (row, column); + return createIndex(row, column, encodedId); } QModelIndex CSMWorld::IdTable::parent (const QModelIndex& index) const { - return QModelIndex(); + if (index.internalId() == 0) //0 is used for indexs with invalid parent (top level data) + { + return QModelIndex(); + } + + unsigned int id = index.internalId(); + const std::pair& adress(unfoldIndexAdress(id)); + + if (adress.first >= this->rowCount() || adress.second >= this->columnCount()) + { + throw "Parent index is not present in the model"; + } + return createIndex(adress.first, adress.second); } void CSMWorld::IdTable::addRecord (const std::string& id, UniversalId::Type type) @@ -136,10 +157,10 @@ void CSMWorld::IdTable::cloneRecord(const std::string& origin, endInsertRows(); } - +///This method can return only indexes to the top level table cells QModelIndex CSMWorld::IdTable::getModelIndex (const std::string& id, int column) const { - return index (mIdCollection->getIndex (id), column); + return index(mIdCollection->getIndex (id), column); } void CSMWorld::IdTable::setRecord (const std::string& id, const RecordBase& record) @@ -238,7 +259,28 @@ std::pair CSMWorld::IdTable::view (int row) return std::make_pair (UniversalId (UniversalId::Type_Scene, id), hint); } +///For top level data/columns int CSMWorld::IdTable::getColumnId(int column) const { return mIdCollection->getColumn(column).getId(); +} + +unsigned int CSMWorld::IdTable::foldIndexAdress (const QModelIndex& index) const +{ + unsigned int out = index.row() * this->columnCount(); + out += index.column(); + return ++out; +} + +std::pair< int, int > CSMWorld::IdTable::unfoldIndexAdress (unsigned int id) const +{ + if (id == 0) + { + throw "Attempt to unfold index id of the top level data cell"; + } + + --id; + int row = id / this->columnCount(); + int column = id - row * this->columnCount(); + return std::make_pair(row, column); } \ No newline at end of file diff --git a/apps/opencs/model/world/idtable.hpp b/apps/opencs/model/world/idtable.hpp index 8b54628256..deb07a1b24 100644 --- a/apps/opencs/model/world/idtable.hpp +++ b/apps/opencs/model/world/idtable.hpp @@ -8,6 +8,15 @@ #include "universalid.hpp" #include "columns.hpp" +/*! \brief + * Clas for holding the model. Uses typical qt table abstraction/interface for granting access to the individiual fields of the records, + * Some records are holding nested data (for instance inventory list of the npc). In casses like this, table model offers interface + * to access nested data in the qt way – that is specify parent. Since some of those nested data require multiple columns to + * represent informations, single int (default way to index model in the qmodelindex) is not sufficiant. Therefore tablemodelindex class + * can hold two ints for the sake of indexing two dimensions of the table. This model does not support multiple levels of the nested + * data. Vast majority of methods makes sense only for the top level data. + */ + namespace CSMWorld { class CollectionBase; @@ -44,6 +53,8 @@ namespace CSMWorld // not implemented IdTable (const IdTable&); IdTable& operator= (const IdTable&); + unsigned int foldIndexAdress(const QModelIndex& index) const; + std::pair unfoldIndexAdress(unsigned int id) const; public: diff --git a/apps/opencs/model/world/refidadapter.cpp b/apps/opencs/model/world/refidadapter.cpp index 283f062feb..2259a6e445 100644 --- a/apps/opencs/model/world/refidadapter.cpp +++ b/apps/opencs/model/world/refidadapter.cpp @@ -8,13 +8,13 @@ CSMWorld::RefIdAdapter::RefIdAdapter() {} CSMWorld::RefIdAdapter::~RefIdAdapter() {} -QVariant CSMWorld::RefIdAdapter::getData (const CSMWorld::RefIdColumn* column, const CSMWorld::RefIdData& data, int idnex, int subRowIndex, int subColIndex) const +QVariant CSMWorld::RefIdAdapter::getNestedData (const CSMWorld::RefIdColumn* column, const CSMWorld::RefIdData& data, int idnex, int subRowIndex, int subColIndex) const { assert(false); return QVariant(); } -void CSMWorld::RefIdAdapter::setData (const CSMWorld::RefIdColumn* column, CSMWorld::RefIdData& data, const QVariant& value, int index, int subRowIndex, int subColIndex) const +void CSMWorld::RefIdAdapter::setNestedData (const CSMWorld::RefIdColumn* column, CSMWorld::RefIdData& data, const QVariant& value, int index, int subRowIndex, int subColIndex) const { assert(false); } diff --git a/apps/opencs/model/world/refidadapter.hpp b/apps/opencs/model/world/refidadapter.hpp index 673b1f5a44..c9c7780202 100644 --- a/apps/opencs/model/world/refidadapter.hpp +++ b/apps/opencs/model/world/refidadapter.hpp @@ -30,10 +30,10 @@ namespace CSMWorld const QVariant& value) const = 0; ///< If the data type does not match an exception is thrown. - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, + virtual QVariant getNestedData (const RefIdColumn *column, const RefIdData& data, int idnex, int subRowIndex, int subColIndex) const; - virtual void setData (const RefIdColumn *column, RefIdData& data, + virtual void setNestedData (const RefIdColumn *column, RefIdData& data, const QVariant& value, int index, int subRowIndex, int subColIndex) const; diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 8c98e18082..750e4af876 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -222,7 +222,7 @@ void CSMWorld::ContainerRefIdAdapter::setData (const RefIdColumn *column, RefIdD NameRefIdAdapter::setData (column, data, index, value); } -void CSMWorld::ContainerRefIdAdapter::setData(const RefIdColumn *column, RefIdData& data, +void CSMWorld::ContainerRefIdAdapter::setNestedData(const RefIdColumn *column, RefIdData& data, int index, const QVariant& value, int subRowIndex, @@ -242,6 +242,9 @@ void CSMWorld::ContainerRefIdAdapter::setData(const RefIdColumn *column, RefIdDa case 1: record.get().mInventory.mList.at(subRowIndex).mCount = value.toInt(); break; + + default: + throw "Trying to access non-existing column in the nested table!"; } } else { @@ -249,7 +252,7 @@ void CSMWorld::ContainerRefIdAdapter::setData(const RefIdColumn *column, RefIdDa } } -QVariant CSMWorld::ContainerRefIdAdapter::getData (const CSMWorld::RefIdColumn* column, +QVariant CSMWorld::ContainerRefIdAdapter::getNestedData (const CSMWorld::RefIdColumn* column, const CSMWorld::RefIdData& data, int index, int subRowIndex, diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index f295016985..eab0151b59 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -617,15 +617,13 @@ namespace CSMWorld ContainerRefIdAdapter (const NameColumns& columns, const RefIdColumn *weight, const RefIdColumn *organic, const RefIdColumn *respawn, const RefIdColumn *content); - using RefIdAdapter::getData; - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index, + virtual QVariant getNestedData (const RefIdColumn *column, const RefIdData& data, int index, int subRowIndex, int subColIndex) const; virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) const; - using RefIdAdapter::setData; - virtual void setData (const RefIdColumn *column, RefIdData& data, int index, + virtual void setNestedData (const RefIdColumn *column, RefIdData& data, int index, const QVariant& value, int subRowIndex, int subColIndex) const; virtual void setData (const RefIdColumn *column, RefIdData& data, int index, diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 1745ce957f..74aa67e3bf 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -165,7 +165,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn (Columns::ColumnId_Respawn, ColumnBase::Display_Boolean)); const RefIdColumn *respawn = &mColumns.back(); - mColumns.push_back(RefIdColumn (Columns::ColumnId_ContainerContent, ColumnBase::Display_None, ColumnBase::Flag_Dialogue, false, false)); + mColumns.push_back(RefIdColumn (Columns::ColumnId_ContainerContent, ColumnBase::Display_Nested, ColumnBase::Flag_Dialogue, false, false)); const RefIdColumn *content = &mColumns.back(); CreatureColumns creatureColumns (actorsColumns); @@ -419,6 +419,16 @@ QVariant CSMWorld::RefIdCollection::getData (int index, int column) const return adaptor.getData (&mColumns.at (column), mData, localIndex.first); } +QVariant CSMWorld::RefIdCollection::getNestedData (int row, int column, int subRow, int subColumn) const +{ + RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(row); + + const RefIdAdapter& adaptor = findAdaptor (localIndex.second); + + //if this overloaded, base class method was not overriden, crash will happen (assert(false)) Don't try to use this method for non-nested columns! + return adaptor.getNestedData(&mColumns.at(column), mData, localIndex.first, subRow, subColumn); +} + void CSMWorld::RefIdCollection::setData (int index, int column, const QVariant& data) { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (index); diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index dd6213677e..d03b458143 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -65,6 +65,8 @@ namespace CSMWorld virtual QVariant getData (int index, int column) const; + virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const; + virtual void setData (int index, int column, const QVariant& data); virtual void removeRows (int index, int count); diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index abdc331039..4ac8e87806 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -295,7 +295,7 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase:: { connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited())); skip = true; - } + } //lisp cond pairs would be nice in the C++ connect(proxy, SIGNAL(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display)), this, SLOT(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display))); mProxys.push_back(proxy); //deleted in the destructor @@ -361,6 +361,7 @@ void CSVWorld::EditWidget::remake(int row) int unlocked = 0; int locked = 0; const int columns = mTable->columnCount(); + for (int i=0; iheaderData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt(); @@ -368,28 +369,35 @@ void CSVWorld::EditWidget::remake(int row) if (flags & CSMWorld::ColumnBase::Flag_Dialogue) { CSMWorld::ColumnBase::Display display = static_cast - (mTable->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); + (mTable->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); - mDispatcher.makeDelegate(display); - QWidget *editor = mDispatcher.makeEditor(display, (mTable->index (row, i))); - - if (editor) + if (display != CSMWorld::ColumnBase::Display_Nested) { - mWidgetMapper->addMapping (editor, i); - QLabel* label = new QLabel(mTable->headerData (i, Qt::Horizontal).toString(), mMainWidget); - label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - editor->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - if (! (mTable->flags (mTable->index (row, i)) & Qt::ItemIsEditable)) + mDispatcher.makeDelegate (display); + QWidget* editor = mDispatcher.makeEditor (display, (mTable->index (row, i))); + + if (editor) { - lockedLayout->addWidget (label, locked, 0); - lockedLayout->addWidget (editor, locked, 1); - ++locked; - } else - { - unlockedLayout->addWidget (label, unlocked, 0); - unlockedLayout->addWidget (editor, unlocked, 1); - ++unlocked; + mWidgetMapper->addMapping (editor, i); + QLabel* label = new QLabel (mTable->headerData (i, Qt::Horizontal).toString(), mMainWidget); + label->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed); + editor->setSizePolicy (QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + + if (! (mTable->flags (mTable->index (row, i)) & Qt::ItemIsEditable)) + { + lockedLayout->addWidget (label, locked, 0); + lockedLayout->addWidget (editor, locked, 1); + ++locked; + } else + { + unlockedLayout->addWidget (label, unlocked, 0); + unlockedLayout->addWidget (editor, unlocked, 1); + ++unlocked; + } } + } else + { + //TODO } } } diff --git a/apps/opencs/view/world/util.cpp b/apps/opencs/view/world/util.cpp index b2a32b551c..5fa93fe797 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -172,7 +172,8 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO display == CSMWorld::ColumnBase::Display_Class || display == CSMWorld::ColumnBase::Display_Faction || display == CSMWorld::ColumnBase::Display_Miscellaneous || - display == CSMWorld::ColumnBase::Display_Sound) + display == CSMWorld::ColumnBase::Display_Sound || + display == CSMWorld::ColumnBase::Display_Region) { return new DropLineEdit(parent); } From 29231b8fc9a10fc3e4122bd70cfa88e571ad3ad2 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 9 Jun 2014 10:26:53 +0200 Subject: [PATCH 005/185] starting new branch --- apps/opencs/view/world/dialoguesubview.cpp | 39 +++++++++++++++------- apps/opencs/view/world/dialoguesubview.hpp | 4 +-- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 4ac8e87806..d537ac4f14 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include "../../model/world/columnbase.hpp" #include "../../model/world/idtable.hpp" @@ -261,6 +263,7 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase:: } std::map::iterator delegateIt(mDelegates.find(display)); + if (delegateIt != mDelegates.end()) { editor = delegateIt->second->createEditor(qobject_cast(mParent), QStyleOptionViewItem(), index, display); @@ -371,7 +374,20 @@ void CSVWorld::EditWidget::remake(int row) CSMWorld::ColumnBase::Display display = static_cast (mTable->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); - if (display != CSMWorld::ColumnBase::Display_Nested) + if (display == CSMWorld::ColumnBase::Display_Nested) + { + const QModelIndex& parent = mTable->index(row, i); + if (parent.data().isValid() && mTable->hasChildren(parent)) + { + qDebug()<setModel(mTable); + table->setRootIndex(mTable->index(row, i)); + } + //TODO + } else { mDispatcher.makeDelegate (display); QWidget* editor = mDispatcher.makeEditor (display, (mTable->index (row, i))); @@ -394,10 +410,9 @@ void CSVWorld::EditWidget::remake(int row) unlockedLayout->addWidget (editor, unlocked, 1); ++unlocked; } - } - } else - { - //TODO + } else { + qDebug()<<"No edit widget"; + } } } } @@ -421,13 +436,12 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM mMainLayout(NULL), mUndoStack(document.getUndoStack()), mTable(dynamic_cast(document.getData().getTableModel(id))), - mRow (-1), mLocked(false), mDocument(document) { connect(mTable, SIGNAL(dataChanged (const QModelIndex&, const QModelIndex&)), this, SLOT(dataChanged(const QModelIndex&))); - mRow = mTable->getModelIndex (id.getId(), 0).row(); + mCurrentId(id.getId()); QWidget *mainWidget = new QWidget(this); QHBoxLayout *buttonsLayout = new QHBoxLayout; @@ -477,7 +491,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM mMainLayout = new QVBoxLayout(mainWidget); - mEditWidget = new EditWidget(mainWidget, mRow, mTable, mUndoStack, false); + mEditWidget = new EditWidget(mainWidget, mCurrentId, mTable, mUndoStack, false); connect(mEditWidget, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)), this, SLOT(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*))); @@ -498,14 +512,15 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM deleteButton->setDisabled(true); } - dataChanged(mTable->index(mRow, 0)); + dataChanged(getModelIndex(mCurrentId, 0)); mMainLayout->addLayout(buttonsLayout); setWidget(mainWidget); } void CSVWorld::DialogueSubView::prevId() { - int newRow = mRow - 1; + int new Row = getModelIndex(mCurrentId, 0).row() - 1; + if (newRow < 0) { return; @@ -552,12 +567,12 @@ void CSVWorld::DialogueSubView::nextId() } CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (newRow, 1)).toInt()); - if (!(state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased)) + if (!(state == CSMWorld::RecordBase::State_Deleted)) { mEditWidget->remake(newRow); setUniversalId(CSMWorld::UniversalId (static_cast (mTable->data (mTable->index (newRow, 2)).toInt()), mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData())); - mRow = newRow; + mCurrentId = std::string(mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData()); mEditWidget->setDisabled(mLocked); return; } diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index 5642f46a0b..dd14b3095a 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -165,7 +165,7 @@ namespace CSVWorld QVBoxLayout* mMainLayout; CSMWorld::IdTable* mTable; QUndoStack& mUndoStack; - int mRow; + std::string mCurrentId; bool mLocked; const CSMDoc::Document& mDocument; TableBottomBox* mBottom; @@ -206,4 +206,4 @@ namespace CSVWorld }; } -#endif \ No newline at end of file +#endif From 21a1f6f4aef555775cdd66e4b4d7483d95f9b8cb Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 9 Jun 2014 10:35:39 +0200 Subject: [PATCH 006/185] working on the issue --- apps/opencs/model/world/collection.hpp | 20 ++++- apps/opencs/model/world/collectionbase.cpp | 19 +++- apps/opencs/model/world/collectionbase.hpp | 8 +- apps/opencs/model/world/idtable.cpp | 89 +++++++++++++++++-- apps/opencs/model/world/idtable.hpp | 22 +++++ apps/opencs/model/world/refidadapter.cpp | 10 ++- apps/opencs/model/world/refidadapter.hpp | 22 ++++- apps/opencs/model/world/refidadapterimp.cpp | 98 ++++++++++++++++++++- apps/opencs/model/world/refidadapterimp.hpp | 25 +++++- apps/opencs/model/world/refidcollection.cpp | 41 +++++++++ apps/opencs/model/world/refidcollection.hpp | 6 ++ 11 files changed, 342 insertions(+), 18 deletions(-) diff --git a/apps/opencs/model/world/collection.hpp b/apps/opencs/model/world/collection.hpp index 1fb3e1f1db..3f110b4dd7 100644 --- a/apps/opencs/model/world/collection.hpp +++ b/apps/opencs/model/world/collection.hpp @@ -73,6 +73,10 @@ namespace CSMWorld ///< Add a new record (modified) virtual int getSize() const; + + virtual int getNestedColumnsCount(int column) const; + + virtual int getNestedRowsCount(int row, int column) const; virtual std::string getId (int index) const; @@ -92,7 +96,7 @@ namespace CSMWorld virtual void purge(); ///< Remove records that are flagged as erased. - virtual void removeRows (int index, int count) ; + virtual void removeRows (int index, int count); virtual void appendBlankRecord (const std::string& id, UniversalId::Type type = UniversalId::Type_None); @@ -247,6 +251,20 @@ namespace CSMWorld { return mRecords.size(); } + + template + int Collection::getNestedRowsCount(int row, int column) const + { + //TODO + return 0; + } + + template + int Collection::getNestedColumnsCount(int column) const + { + //TODO + return 0; + } template std::string Collection::getId (int index) const diff --git a/apps/opencs/model/world/collectionbase.cpp b/apps/opencs/model/world/collectionbase.cpp index 241f198cb2..eed157a7ba 100644 --- a/apps/opencs/model/world/collectionbase.cpp +++ b/apps/opencs/model/world/collectionbase.cpp @@ -28,4 +28,21 @@ int CSMWorld::CollectionBase::findColumnIndex (Columns::ColumnId id) const throw std::logic_error ("invalid column index"); return index; -} \ No newline at end of file +} + +void CSMWorld::CollectionBase::setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn) +{ + assert(false); //TODO remove and make pure abstract +} + +int CSMWorld::CollectionBase::getNestedColumnsCount(int row, int column) const +{ + assert(false); //TODO remove and make pure abstract + return 0; +} + +int CSMWorld::CollectionBase::getNestedRowsCount(int row, int column) const +{ + assert(false); //TODO, make pure abstract + return 0; +} diff --git a/apps/opencs/model/world/collectionbase.hpp b/apps/opencs/model/world/collectionbase.hpp index 442055d5f3..4c3afc0925 100644 --- a/apps/opencs/model/world/collectionbase.hpp +++ b/apps/opencs/model/world/collectionbase.hpp @@ -33,6 +33,10 @@ namespace CSMWorld virtual ~CollectionBase(); virtual int getSize() const = 0; + + virtual int getNestedRowsCount(int row, int column) const; + + virtual int getNestedColumnsCount(int row, int column) const; virtual std::string getId (int index) const = 0; @@ -46,6 +50,8 @@ namespace CSMWorld virtual void setData (int index, int column, const QVariant& data) = 0; + virtual void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn); + // Not in use. Temporarily removed so that the implementation of RefIdCollection can continue without // these functions for now. // virtual void merge() = 0; @@ -106,4 +112,4 @@ namespace CSMWorld }; } -#endif \ No newline at end of file +#endif diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index 50998c36f1..59fc3a5081 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -1,6 +1,8 @@ #include "idtable.hpp" +#include + #include "collectionbase.hpp" #include "columnbase.hpp" @@ -14,16 +16,21 @@ CSMWorld::IdTable::~IdTable() int CSMWorld::IdTable::rowCount (const QModelIndex & parent) const { - if (parent.isValid()) - return 0; - + if (hasChildren(parent)) + { + int nestedRows = mIdCollection->getNestedRowsCount(parent.row(), parent.column()); + return nestedRows; + } + return mIdCollection->getSize(); } int CSMWorld::IdTable::columnCount (const QModelIndex & parent) const { if (parent.isValid()) - return 0; + { + return mIdCollection->getNestedColumnsCount(parent.row(), parent.column()); + } return mIdCollection->getColumns(); } @@ -36,7 +43,17 @@ QVariant CSMWorld::IdTable::data (const QModelIndex & index, int role) const if (role==Qt::EditRole && !mIdCollection->getColumn (index.column()).isEditable()) return QVariant(); +<<<<<<< Updated upstream return mIdCollection->getData (index.row(), index.column()); +======= + if (index.internalId() != 0) + { + std::pair parentAdress(unfoldIndexAdress(index.internalId())); + return mIdCollection->getNestedData(parentAdress.first, parentAdress.second, index.row(), index.column()); + } else { + return mIdCollection->getData (index.row(), index.column()); + } +>>>>>>> Stashed changes } QVariant CSMWorld::IdTable::headerData (int section, Qt::Orientation orientation, int role) const @@ -60,11 +77,18 @@ bool CSMWorld::IdTable::setData ( const QModelIndex &index, const QVariant &valu { if (mIdCollection->getColumn (index.column()).isEditable() && role==Qt::EditRole) { - mIdCollection->setData (index.row(), index.column(), value); + if (index.internalId() == 0) + { + mIdCollection->setData (index.row(), index.column(), value); - emit dataChanged (CSMWorld::IdTable::index (index.row(), 0), - CSMWorld::IdTable::index (index.row(), mIdCollection->getColumns()-1)); + emit dataChanged (CSMWorld::IdTable::index (index.row(), 0), + CSMWorld::IdTable::index (index.row(), mIdCollection->getColumns()-1)); + } else + { + const std::pair& parentAdress(unfoldIndexAdress(index.internalId())); + mIdCollection->setNestedData(parentAdress.first, parentAdress.second, value, index.row(), index.column()); + } return true; } @@ -111,7 +135,23 @@ QModelIndex CSMWorld::IdTable::index (int row, int column, const QModelIndex& pa QModelIndex CSMWorld::IdTable::parent (const QModelIndex& index) const { +<<<<<<< Updated upstream return QModelIndex(); +======= + if (index.internalId() == 0) //0 is used for indexs with invalid parent (top level data) + { + return QModelIndex(); + } + + const std::pair& adress(unfoldIndexAdress(index.internalId())); + + if (adress.first >= this->rowCount() || adress.second >= this->columnCount()) + { + qDebug()<<"Parent index is not present in the model"; + throw "Parent index is not present in the model"; + } + return createIndex(adress.first, adress.second, 0); +>>>>>>> Stashed changes } void CSMWorld::IdTable::addRecord (const std::string& id, UniversalId::Type type) @@ -240,4 +280,37 @@ std::pair CSMWorld::IdTable::view (int row) int CSMWorld::IdTable::getColumnId(int column) const { return mIdCollection->getColumn(column).getId(); -} \ No newline at end of file +<<<<<<< Updated upstream +} +======= +} + +bool CSMWorld::IdTable::hasChildren(const QModelIndex& index) const +{ + return (index.isValid() && + mIdCollection->getColumn (index.column()).mDisplayType == ColumnBase::Display_Nested && + index.data().isValid()); +} + +unsigned int CSMWorld::IdTable::foldIndexAdress (const QModelIndex& index) const +{ + unsigned int out = index.row() * this->columnCount(); + out += index.column(); + ++out; + return out; +} + +std::pair< int, int > CSMWorld::IdTable::unfoldIndexAdress (unsigned int id) const +{ + if (id == 0) + { + qDebug()<<"Attempt to unfold index id of the top level data cell"; + throw "Attempt to unfold index id of the top level data cell"; + } + + --id; + int row = id / this->columnCount(); + int column = id - row * this->columnCount(); + return std::make_pair(row, column); +} +>>>>>>> Stashed changes diff --git a/apps/opencs/model/world/idtable.hpp b/apps/opencs/model/world/idtable.hpp index 8b54628256..bf9f4a555a 100644 --- a/apps/opencs/model/world/idtable.hpp +++ b/apps/opencs/model/world/idtable.hpp @@ -8,6 +8,19 @@ #include "universalid.hpp" #include "columns.hpp" +<<<<<<< Updated upstream +======= +/*! \brief + * Clas for holding the model. Uses typical qt table abstraction/interface for granting access to the individiual fields of the records, + * Some records are holding nested data (for instance inventory list of the npc). In casses like this, table model offers interface + * to access nested data in the qt way – that is specify parent. The parent is encoded in the internalid of the index model + * See methods fold and unfold adress to see why. This approach has some serious limitations: it allows only + * a single level of the nesting. At the point of creating this code this seemed to be a good enough solution. + * If for some reason it turned out that in fact multiple levels of nesting are needed, change in the addressing of the + * index is most likely the very first to be considered. + */ + +>>>>>>> Stashed changes namespace CSMWorld { class CollectionBase; @@ -44,6 +57,13 @@ namespace CSMWorld // not implemented IdTable (const IdTable&); IdTable& operator= (const IdTable&); +<<<<<<< Updated upstream +======= + + unsigned int foldIndexAdress(const QModelIndex& index) const; + + std::pair unfoldIndexAdress(unsigned int id) const; +>>>>>>> Stashed changes public: @@ -71,6 +91,8 @@ namespace CSMWorld const; virtual QModelIndex parent (const QModelIndex& index) const; + + virtual bool hasChildren (const QModelIndex& index) const; void addRecord (const std::string& id, UniversalId::Type type = UniversalId::Type_None); ///< \param type Will be ignored, unless the collection supports multiple record types diff --git a/apps/opencs/model/world/refidadapter.cpp b/apps/opencs/model/world/refidadapter.cpp index 94ae38c3c2..785e98d5eb 100644 --- a/apps/opencs/model/world/refidadapter.cpp +++ b/apps/opencs/model/world/refidadapter.cpp @@ -3,4 +3,12 @@ CSMWorld::RefIdAdapter::RefIdAdapter() {} -CSMWorld::RefIdAdapter::~RefIdAdapter() {} \ No newline at end of file +<<<<<<< Updated upstream +CSMWorld::RefIdAdapter::~RefIdAdapter() {} +======= +CSMWorld::RefIdAdapter::~RefIdAdapter() {} + +CSMWorld::NestedRefIdAdapter::NestedRefIdAdapter() {} + +CSMWorld::NestedRefIdAdapter::~NestedRefIdAdapter() {} +>>>>>>> Stashed changes diff --git a/apps/opencs/model/world/refidadapter.hpp b/apps/opencs/model/world/refidadapter.hpp index 0870a2d3e6..3a9d02dcae 100644 --- a/apps/opencs/model/world/refidadapter.hpp +++ b/apps/opencs/model/world/refidadapter.hpp @@ -31,8 +31,28 @@ namespace CSMWorld ///< If the data type does not match an exception is thrown. virtual std::string getId (const RecordBase& record) const = 0; + virtual void setId(RecordBase& record, const std::string& id) = 0; }; + + class NestedRefIdAdapter + { + public: + NestedRefIdAdapter(); + + virtual ~NestedRefIdAdapter(); + + virtual void setNestedData (const RefIdColumn *column, RefIdData& data, int row, + const QVariant& value, int subRowIndex, int subColIndex) const = 0; + + virtual QVariant getNestedData (const RefIdColumn *column, const RefIdData& data, + int index, int subRowIndex, int subColIndex) const = 0; + + + virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const = 0; + + virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const = 0; + }; } -#endif \ No newline at end of file +#endif diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index f00e9fc77b..b67b26cdb7 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -1,6 +1,8 @@ #include "refidadapterimp.hpp" +#include + CSMWorld::PotionRefIdAdapter::PotionRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *autoCalc) : InventoryRefIdAdapter (UniversalId::Type_Potion, columns), @@ -178,6 +180,32 @@ CSMWorld::ContainerRefIdAdapter::ContainerRefIdAdapter (const NameColumns& colum mOrganic (organic), mRespawn (respawn) {} +int CSMWorld::ContainerRefIdAdapter::getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const +{ + qDebug()<<"getting nested columns count"; + if (column==mContent) + { + return 2; + } else { + throw "Trying to obtain nested columns count, but column does not have nested columns!"; + } +} + +int CSMWorld::ContainerRefIdAdapter::getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const +{ + qDebug()<<"getting nested rows count"; + const Record& record = static_cast&> ( + data.getRecord(RefIdData::LocalIndex (index, UniversalId::Type_Container))); + + qDebug() << "exception above"; + if (column==mContent) + { + qDebug() << record.get().mInventory.mList.size(); + return record.get().mInventory.mList.size(); + } else { + throw "Trying to obtain nested rows count, but column does not have nested columns!"; + } +} QVariant CSMWorld::ContainerRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, int index) const { @@ -192,6 +220,9 @@ QVariant CSMWorld::ContainerRefIdAdapter::getData (const RefIdColumn *column, co if (column==mRespawn) return (record.get().mFlags & ESM::Container::Respawn)!=0; + + if (column==mContent) + return true; return NameRefIdAdapter::getData (column, data, index); } @@ -222,6 +253,71 @@ void CSMWorld::ContainerRefIdAdapter::setData (const RefIdColumn *column, RefIdD NameRefIdAdapter::setData (column, data, index, value); } +<<<<<<< Updated upstream +======= +void CSMWorld::ContainerRefIdAdapter::setNestedData(const RefIdColumn *column, RefIdData& data, + int row, + const QVariant& value, + int subRowIndex, + int subColIndex) const +{ + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (row, UniversalId::Type_Container))); + + if (column==mContent) + { + switch (subColIndex) + { + case 0: + record.get().mInventory.mList.at(subRowIndex).mItem.assign(std::string(value.toString().toUtf8().constData())); + break; + + case 1: + record.get().mInventory.mList.at(subRowIndex).mCount = value.toInt(); + break; + + default: + throw "Trying to access non-existing column in the nested table!"; + } + } else + { + throw "This column does not hold multiple values."; + } +} + +QVariant CSMWorld::ContainerRefIdAdapter::getNestedData (const CSMWorld::RefIdColumn* column, + const CSMWorld::RefIdData& data, + int index, + int subRowIndex, + int subColIndex) const +{ + qDebug()<<"Accessing content column"; + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))); + + if (column==mContent) + { + const ESM::ContItem& content = record.get().mInventory.mList.at(subRowIndex); + + switch (subColIndex) + { + case 0: + return QString::fromUtf8(content.mItem.toString().c_str()); + + case 1: + return content.mCount; + + default: + throw "Trying to access non-existing column in the nested table!"; + } + } else + { + throw "This column does not hold multiple values."; + } +} + + +>>>>>>> Stashed changes CSMWorld::CreatureColumns::CreatureColumns (const ActorColumns& actorColumns) : ActorColumns (actorColumns) {} @@ -572,4 +668,4 @@ void CSMWorld::WeaponRefIdAdapter::setData (const RefIdColumn *column, RefIdData else EnchantableRefIdAdapter::setData (column, data, index, value); } -} \ No newline at end of file +} diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index bd509a86b6..ed6c50fe3f 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -23,6 +23,7 @@ namespace CSMWorld }; /// \brief Base adapter for all refereceable record types + /// Adapters that can handle nested tables, needs to return valid qvariant for parent columns template class BaseRefIdAdapter : public RefIdAdapter { @@ -605,7 +606,7 @@ namespace CSMWorld ///< If the data type does not match an exception is thrown. }; - class ContainerRefIdAdapter : public NameRefIdAdapter + class ContainerRefIdAdapter : public NameRefIdAdapter, public NestedRefIdAdapter { const RefIdColumn *mWeight; const RefIdColumn *mOrganic; @@ -614,14 +615,30 @@ namespace CSMWorld public: ContainerRefIdAdapter (const NameColumns& columns, const RefIdColumn *weight, +<<<<<<< Updated upstream const RefIdColumn *organic, const RefIdColumn *respawn); +======= + const RefIdColumn *organic, const RefIdColumn *respawn, const RefIdColumn *content); - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const; + virtual QVariant getNestedData (const RefIdColumn *column, const RefIdData& data, + int index, int subRowIndex, int subColIndex) const; +>>>>>>> Stashed changes + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) const; + +<<<<<<< Updated upstream +======= + virtual void setNestedData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value, int subRowIndex, int subColIndex) const; + +>>>>>>> Stashed changes virtual void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const; + const QVariant& value) const; ///< If the data type does not match an exception is thrown. + + virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const; + + virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const; }; struct CreatureColumns : public ActorColumns diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index f515e34d8e..c9d6700b5e 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -3,6 +3,7 @@ #include #include +#include #include @@ -416,6 +417,19 @@ QVariant CSMWorld::RefIdCollection::getData (int index, int column) const return adaptor.getData (&mColumns.at (column), mData, localIndex.first); } +<<<<<<< Updated upstream +======= +QVariant CSMWorld::RefIdCollection::getNestedData (int row, int column, int subRow, int subColumn) const +{ + RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(row); + + const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdaptor (localIndex.second)); + + //if this overloaded, base class method was not overriden, crash will happen (assert(false)) Don't try to use this method for non-nested columns! + return adaptor.getNestedData (&mColumns.at (column), mData, localIndex.first, subRow, subColumn); +} + +>>>>>>> Stashed changes void CSMWorld::RefIdCollection::setData (int index, int column, const QVariant& data) { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (index); @@ -425,6 +439,15 @@ void CSMWorld::RefIdCollection::setData (int index, int column, const QVariant& adaptor.setData (&mColumns.at (column), mData, localIndex.first, data); } +void CSMWorld::RefIdCollection::setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn) +{ + RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + + const RefIdAdapter& adaptor = findAdaptor (localIndex.second); + + dynamic_cast(adaptor).setNestedData (&mColumns.at (column), mData, localIndex.first, data, subRow, subColumn); +} + void CSMWorld::RefIdCollection::removeRows (int index, int count) { mData.erase (index, count); @@ -566,3 +589,21 @@ const CSMWorld::RefIdData& CSMWorld::RefIdCollection::getDataSet() const return mData; } +int CSMWorld::RefIdCollection::getNestedRowsCount(int row, int column) const +{ + RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + + const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdaptor (localIndex.second)); + + const int count = adaptor.getNestedRowsCount(&mColumns.at(column), mData, localIndex.first); + return count; +} + +int CSMWorld::RefIdCollection::getNestedColumnsCount(int row, int column) const +{ + RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + + const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdaptor (localIndex.second)); + + return adaptor.getNestedColumnsCount(&mColumns.at(column), mData); +} diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index dd6213677e..f4ac556cf3 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -55,6 +55,10 @@ namespace CSMWorld virtual int getSize() const; + virtual int getNestedRowsCount(int row, int column) const; + + virtual int getNestedColumnsCount(int row, int column) const; + virtual std::string getId (int index) const; virtual int getIndex (const std::string& id) const; @@ -67,6 +71,8 @@ namespace CSMWorld virtual void setData (int index, int column, const QVariant& data); + virtual void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn); + virtual void removeRows (int index, int count); virtual void cloneRecord(const std::string& origin, From 6f5935edb38dd30e00360053b9d1fd8b26b28b05 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 9 Jun 2014 11:37:48 +0200 Subject: [PATCH 007/185] subview does not store row number anymore --- apps/opencs/view/world/dialoguesubview.cpp | 93 +++++++++++++--------- 1 file changed, 56 insertions(+), 37 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index d537ac4f14..03321728ba 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -379,14 +379,15 @@ void CSVWorld::EditWidget::remake(int row) const QModelIndex& parent = mTable->index(row, i); if (parent.data().isValid() && mTable->hasChildren(parent)) { + /* qDebug()<setModel(mTable); table->setRootIndex(mTable->index(row, i)); + */ } - //TODO } else { mDispatcher.makeDelegate (display); @@ -410,9 +411,7 @@ void CSVWorld::EditWidget::remake(int row) unlockedLayout->addWidget (editor, unlocked, 1); ++unlocked; } - } else { - qDebug()<<"No edit widget"; - } + } } } } @@ -441,7 +440,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM { connect(mTable, SIGNAL(dataChanged (const QModelIndex&, const QModelIndex&)), this, SLOT(dataChanged(const QModelIndex&))); - mCurrentId(id.getId()); + mCurrentId = id.getId(); QWidget *mainWidget = new QWidget(this); QHBoxLayout *buttonsLayout = new QHBoxLayout; @@ -491,7 +490,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM mMainLayout = new QVBoxLayout(mainWidget); - mEditWidget = new EditWidget(mainWidget, mCurrentId, mTable, mUndoStack, false); + mEditWidget = new EditWidget(mainWidget, mTable->getModelIndex(mCurrentId, 0).row(), mTable, mUndoStack, false); connect(mEditWidget, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)), this, SLOT(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*))); @@ -512,14 +511,14 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM deleteButton->setDisabled(true); } - dataChanged(getModelIndex(mCurrentId, 0)); + dataChanged(mTable->getModelIndex(mCurrentId, 0)); mMainLayout->addLayout(buttonsLayout); setWidget(mainWidget); } void CSVWorld::DialogueSubView::prevId() { - int new Row = getModelIndex(mCurrentId, 0).row() - 1; + int newRow = mTable->getModelIndex(mCurrentId, 0).row() - 1; if (newRow < 0) { @@ -540,7 +539,7 @@ void CSVWorld::DialogueSubView::prevId() mEditWidget->remake(newRow); setUniversalId(CSMWorld::UniversalId (static_cast (mTable->data (mTable->index (newRow, 2)).toInt()), mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData())); - mRow = newRow; + mCurrentId = std::string(mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData()); mEditWidget->setDisabled(mLocked); return; } @@ -550,7 +549,7 @@ void CSVWorld::DialogueSubView::prevId() void CSVWorld::DialogueSubView::nextId() { - int newRow = mRow + 1; + int newRow = mTable->getModelIndex(mCurrentId, 0).row() + 1; if (newRow >= mTable->rowCount()) { @@ -571,7 +570,7 @@ void CSVWorld::DialogueSubView::nextId() { mEditWidget->remake(newRow); setUniversalId(CSMWorld::UniversalId (static_cast (mTable->data (mTable->index (newRow, 2)).toInt()), - mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData())); + mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData())); mCurrentId = std::string(mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData()); mEditWidget->setDisabled(mLocked); return; @@ -583,8 +582,10 @@ void CSVWorld::DialogueSubView::nextId() void CSVWorld::DialogueSubView::setEditLock (bool locked) { mLocked = locked; - CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (mRow, 1)).toInt()); - if (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased) + QModelIndex index(mTable->getModelIndex(mCurrentId, 0)); + + CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (index.row(), 1)).toInt()); + if (state == CSMWorld::RecordBase::State_Deleted) { mEditWidget->setDisabled(true); } else @@ -595,10 +596,12 @@ void CSVWorld::DialogueSubView::setEditLock (bool locked) void CSVWorld::DialogueSubView::dataChanged(const QModelIndex & index) { - if (index.row() == mRow) + QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0)); + + if (!currentIndex.isValid() && index.row() == currentIndex.row()) { - CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (mRow, 1)).toInt()); - if (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased) + CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (currentIndex.row(), 1)).toInt()); + if (state == CSMWorld::RecordBase::State_Deleted) { mEditWidget->setDisabled(true); } else @@ -621,15 +624,24 @@ void CSVWorld::DialogueSubView::tableMimeDataDropped(QWidget* editor, void CSVWorld::DialogueSubView::revertRecord() { - int rows = mTable->rowCount(); - if (!mLocked && mTable->columnCount() > 0 && mRow < mTable->rowCount() ) + const int rows = mTable->rowCount(); + QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0)); + + if (!currentIndex.isValid()) + { + return; + } + + const int currentRow = currentIndex.row(); + + if (!mLocked && mTable->columnCount() > 0 && currentRow < mTable->rowCount() ) { CSMWorld::RecordBase::State state = - static_cast (mTable->data (mTable->index (mRow, 1)).toInt()); + static_cast (mTable->data (mTable->index (currentRow, 1)).toInt()); if (state!=CSMWorld::RecordBase::State_BaseOnly) { - mUndoStack.push(new CSMWorld::RevertCommand(*mTable, mTable->data(mTable->index (mRow, 0)).toString().toUtf8().constData())); + mUndoStack.push(new CSMWorld::RevertCommand(*mTable, mCurrentId)); } if (rows != mTable->rowCount()) { @@ -638,11 +650,11 @@ void CSVWorld::DialogueSubView::revertRecord() mEditWidget->setDisabled(true); //closing the editor is other option return; } - if (mRow >= mTable->rowCount()) + if (currentIndex.row() >= mTable->rowCount()) { prevId(); } else { - dataChanged(mTable->index(mRow, 0)); + dataChanged(currentIndex); } } } @@ -650,19 +662,20 @@ void CSVWorld::DialogueSubView::revertRecord() void CSVWorld::DialogueSubView::deleteRecord() { - int rows = mTable->rowCount(); + const int rows = mTable->rowCount(); + QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0)); //easier than disabling the button - CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (mRow, 1)).toInt()); - bool deledetedOrErased = (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased); + CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (currentIndex.row(), 1)).toInt()); + bool deledetedOrErased = (state == CSMWorld::RecordBase::State_Deleted); if (!mLocked && mTable->columnCount() > 0 && !deledetedOrErased && - mRow < rows && + currentIndex.row() < rows && mBottom->canCreateAndDelete()) { - mUndoStack.push(new CSMWorld::DeleteCommand(*mTable, mTable->data(mTable->index (mRow, 0)).toString().toUtf8().constData())); + mUndoStack.push(new CSMWorld::DeleteCommand(*mTable, mCurrentId)); if (rows != mTable->rowCount()) { if (mTable->rowCount() == 0) @@ -670,11 +683,11 @@ void CSVWorld::DialogueSubView::deleteRecord() mEditWidget->setDisabled(true); //closing the editor is other option return; } - if (mRow >= mTable->rowCount()) + if (currentIndex.row() >= mTable->rowCount()) { prevId(); } else { - dataChanged(mTable->index(mRow, 0)); + dataChanged(currentIndex); } } } @@ -682,29 +695,35 @@ void CSVWorld::DialogueSubView::deleteRecord() void CSVWorld::DialogueSubView::requestFocus (const std::string& id) { - mRow = mTable->getModelIndex (id, 0).row(); - mEditWidget->remake(mRow); + mCurrentId = std::string(id); + mEditWidget->remake(mTable->getModelIndex (id, 0).row()); } void CSVWorld::DialogueSubView::cloneRequest () { - mBottom->cloneRequest(mTable->data(mTable->index (mRow, 0)).toString().toUtf8().constData(), - static_cast(mTable->data(mTable->index(mRow, 2)).toInt())); + mBottom->cloneRequest(mCurrentId, static_cast(mTable->data(mTable->getModelIndex(mCurrentId, 2)).toInt())); } void CSVWorld::DialogueSubView::showPreview () { - if (mTable->hasPreview() && mRow < mTable->rowCount()) + QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0)); + + if (currentIndex.isValid() && + mTable->hasPreview() && + currentIndex.row() < mTable->rowCount()) { - emit focusId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Preview, mTable->data(mTable->index (mRow, 0)).toString().toUtf8().constData()), ""); + emit focusId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Preview, mCurrentId), ""); } } void CSVWorld::DialogueSubView::viewRecord() { - if (mRow < mTable->rowCount()) + QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0)); + + if (currentIndex.isValid() && + currentIndex.row() < mTable->rowCount()) { - std::pair params = mTable->view (mRow); + std::pair params = mTable->view (currentIndex.row()); if (params.first.getType()!=CSMWorld::UniversalId::Type_None) emit focusId (params.first, params.second); From 649ce543698db2f87460f9b26c0d84c9b48606a2 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 9 Jun 2014 11:53:06 +0200 Subject: [PATCH 008/185] merging --- CMakeLists.txt | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 874d65af3d..3632f1e080 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,19 +36,8 @@ if(EXISTS ${PROJECT_SOURCE_DIR}/.git) string(REGEX REPLACE "^openmw-[0-9]+\\.([0-9]+).*" "\\1" GIT_VERSION_MINOR "${VERSION}") string(REGEX REPLACE "^openmw-[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" GIT_VERSION_RELEASE "${VERSION}") -<<<<<<< HEAD - set(GIT_VERSION "${GIT_VERSION_MAJOR}.${GIT_VERSION_MINOR}.${GIT_VERSION_RELEASE}") - - set(OPENMW_VERSION_MAJOR ${GIT_VERSION_MAJOR}) - set(OPENMW_VERSION_MINOR ${GIT_VERSION_MINOR}) - set(OPENMW_VERSION_RELEASE ${GIT_VERSION_RELEASE}) - - set(OPENMW_VERSION_COMMITHASH "${COMMITHASH}") - set(OPENMW_VERSION_TAGHASH "${TAGHASH}") -======= set(OPENMW_VERSION_COMMITHASH "${COMMITHASH}") set(OPENMW_VERSION_TAGHASH "${TAGHASH}") ->>>>>>> master/refs message(STATUS "OpenMW version ${OPENMW_VERSION}") else(MATCH) From c8458654ac19121fdf2851658a3737121829bf94 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 9 Jun 2014 13:16:10 +0200 Subject: [PATCH 009/185] correcting problems --- apps/opencs/view/world/dialoguesubview.cpp | 43 +++++++--------------- 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 523b358aef..db80af0258 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include "../../model/world/columnbase.hpp" #include "../../model/world/idtable.hpp" @@ -375,22 +374,21 @@ void CSVWorld::EditWidget::remake(int row) { CSMWorld::ColumnBase::Display display = static_cast (mTable->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); - +/* commented out for now TODO if (display == CSMWorld::ColumnBase::Display_Nested) { const QModelIndex& parent = mTable->index(row, i); if (parent.data().isValid() && mTable->hasChildren(parent)) { - /* qDebug()<setModel(mTable); table->setRootIndex(mTable->index(row, i)); - */ + } - } else + } else */ { mDispatcher.makeDelegate (display); QWidget* editor = mDispatcher.makeEditor (display, (mTable->index (row, i))); @@ -583,40 +581,28 @@ void CSVWorld::DialogueSubView::nextId() void CSVWorld::DialogueSubView::setEditLock (bool locked) { mLocked = locked; - QModelIndex index(mTable->getModelIndex(mCurrentId, 0)); - - CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (index.row(), 1)).toInt()); - if (state == CSMWorld::RecordBase::State_Deleted) - { - mEditWidget->setDisabled(true); - } else - { - mEditWidget->setDisabled(mLocked); - } - - CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (mRow, 1)).toInt()); + QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0)); mEditWidget->setDisabled (state==CSMWorld::RecordBase::State_Deleted || locked); + + if (currentIndex.isValid()) + { + CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (currentIndex.row(), 1)).toInt()); + + mCommandDispatcher.setEditLock (locked); + } - mCommandDispatcher.setEditLock (locked); } void CSVWorld::DialogueSubView::dataChanged(const QModelIndex & index) { QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0)); - if (!currentIndex.isValid() && index.row() == currentIndex.row()) + mEditWidget->setDisabled (state==CSMWorld::RecordBase::State_Deleted || mLocked); + + if (currentIndex.isValid() && index.row() == currentIndex.row()) { CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (currentIndex.row(), 1)).toInt()); - if (state == CSMWorld::RecordBase::State_Deleted) - { - mEditWidget->setDisabled(true); - } else - { - mEditWidget->setDisabled(mLocked); - } - - mEditWidget->setDisabled (state==CSMWorld::RecordBase::State_Deleted || mLocked); } } @@ -719,7 +705,6 @@ void CSVWorld::DialogueSubView::showPreview () if (currentIndex.isValid() && mTable->getFeatures() & CSMWorld::IdTable::Feature_Preview && - mTable->hasPreview() && currentIndex.row() < mTable->rowCount()) { emit focusId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Preview, mCurrentId), ""); From 9ee00534b9818226232bc7b7aaf832b37cbcd4b0 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 9 Jun 2014 13:18:17 +0200 Subject: [PATCH 010/185] check if index is valid before attempting to use it --- apps/opencs/view/world/dialoguesubview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index db80af0258..8ffc0da563 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -660,11 +660,11 @@ void CSVWorld::DialogueSubView::deleteRecord() const int rows = mTable->rowCount(); QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0)); - //easier than disabling the button CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (currentIndex.row(), 1)).toInt()); bool deledetedOrErased = (state == CSMWorld::RecordBase::State_Deleted); if (!mLocked && + currentIndex.isValid() && mTable->columnCount() > 0 && !deledetedOrErased && currentIndex.row() < rows && From 8763309a1bdc0e15839cdfd3509ed68e28fc0917 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 9 Jun 2014 13:31:15 +0200 Subject: [PATCH 011/185] reformatting to make code easier to read --- apps/opencs/view/world/dialoguesubview.cpp | 63 ++++++++++++++-------- 1 file changed, 42 insertions(+), 21 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 8ffc0da563..9d6538c1ce 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -133,25 +133,25 @@ void CSVWorld::DialogueDelegateDispatcherProxy::tableMimeDataDropped(const std:: if (mDisplay == CSMWorld::ColumnBase::Display_Referenceable) { if ( type == CSMWorld::UniversalId::Type_Activator - || type == CSMWorld::UniversalId::Type_Potion - || type == CSMWorld::UniversalId::Type_Apparatus - || type == CSMWorld::UniversalId::Type_Armor - || type == CSMWorld::UniversalId::Type_Book - || type == CSMWorld::UniversalId::Type_Clothing - || type == CSMWorld::UniversalId::Type_Container - || type == CSMWorld::UniversalId::Type_Creature - || type == CSMWorld::UniversalId::Type_Door - || type == CSMWorld::UniversalId::Type_Ingredient - || type == CSMWorld::UniversalId::Type_CreatureLevelledList - || type == CSMWorld::UniversalId::Type_ItemLevelledList - || type == CSMWorld::UniversalId::Type_Light - || type == CSMWorld::UniversalId::Type_Lockpick - || type == CSMWorld::UniversalId::Type_Miscellaneous - || type == CSMWorld::UniversalId::Type_Npc - || type == CSMWorld::UniversalId::Type_Probe - || type == CSMWorld::UniversalId::Type_Repair - || type == CSMWorld::UniversalId::Type_Static - || type == CSMWorld::UniversalId::Type_Weapon) + || type == CSMWorld::UniversalId::Type_Potion + || type == CSMWorld::UniversalId::Type_Apparatus + || type == CSMWorld::UniversalId::Type_Armor + || type == CSMWorld::UniversalId::Type_Book + || type == CSMWorld::UniversalId::Type_Clothing + || type == CSMWorld::UniversalId::Type_Container + || type == CSMWorld::UniversalId::Type_Creature + || type == CSMWorld::UniversalId::Type_Door + || type == CSMWorld::UniversalId::Type_Ingredient + || type == CSMWorld::UniversalId::Type_CreatureLevelledList + || type == CSMWorld::UniversalId::Type_ItemLevelledList + || type == CSMWorld::UniversalId::Type_Light + || type == CSMWorld::UniversalId::Type_Lockpick + || type == CSMWorld::UniversalId::Type_Miscellaneous + || type == CSMWorld::UniversalId::Type_Npc + || type == CSMWorld::UniversalId::Type_Probe + || type == CSMWorld::UniversalId::Type_Repair + || type == CSMWorld::UniversalId::Type_Static + || type == CSMWorld::UniversalId::Type_Weapon) { type = CSMWorld::UniversalId::Type_Referenceable; } @@ -266,16 +266,20 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase:: if (delegateIt != mDelegates.end()) { editor = delegateIt->second->createEditor(qobject_cast(mParent), QStyleOptionViewItem(), index, display); + DialogueDelegateDispatcherProxy* proxy = new DialogueDelegateDispatcherProxy(editor, display); bool skip = false; if (qobject_cast(editor)) { connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited())); + connect(editor, SIGNAL(tableMimeDataDropped(const std::vector&, const CSMDoc::Document*)), proxy, SLOT(tableMimeDataDropped(const std::vector&, const CSMDoc::Document*))); + connect(proxy, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)), this, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*))); + skip = true; } if(!skip && qobject_cast(editor)) @@ -299,7 +303,9 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase:: skip = true; } //lisp cond pairs would be nice in the C++ - connect(proxy, SIGNAL(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display)), this, SLOT(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display))); + connect(proxy, SIGNAL(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display)), + this, SLOT(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display))); + mProxys.push_back(proxy); //deleted in the destructor } return editor; @@ -326,7 +332,9 @@ mUndoStack(undoStack), mTable(table) { remake (row); - connect(&mDispatcher, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)), this, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*))); + + connect(&mDispatcher, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)), + this, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*))); } void CSVWorld::EditWidget::remake(int row) @@ -345,6 +353,7 @@ void CSVWorld::EditWidget::remake(int row) mWidgetMapper = 0; } mWidgetMapper = new QDataWidgetMapper (this); + mWidgetMapper->setModel(mTable); mWidgetMapper->setItemDelegate(&mDispatcher); @@ -536,10 +545,14 @@ void CSVWorld::DialogueSubView::prevId() if (!(state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased)) { mEditWidget->remake(newRow); + setUniversalId(CSMWorld::UniversalId (static_cast (mTable->data (mTable->index (newRow, 2)).toInt()), mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData())); + mCurrentId = std::string(mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData()); + mEditWidget->setDisabled(mLocked); + return; } --newRow; @@ -568,10 +581,14 @@ void CSVWorld::DialogueSubView::nextId() if (!(state == CSMWorld::RecordBase::State_Deleted)) { mEditWidget->remake(newRow); + setUniversalId(CSMWorld::UniversalId (static_cast (mTable->data (mTable->index (newRow, 2)).toInt()), mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData())); + mCurrentId = std::string(mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData()); + mEditWidget->setDisabled(mLocked); + return; } ++newRow; @@ -620,6 +637,7 @@ void CSVWorld::DialogueSubView::tableMimeDataDropped(QWidget* editor, void CSVWorld::DialogueSubView::revertRecord() { const int rows = mTable->rowCount(); + QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0)); if (!currentIndex.isValid()) @@ -643,6 +661,7 @@ void CSVWorld::DialogueSubView::revertRecord() if (mTable->rowCount() == 0) { mEditWidget->setDisabled(true); //closing the editor is other option + return; } if (currentIndex.row() >= mTable->rowCount()) @@ -676,6 +695,7 @@ void CSVWorld::DialogueSubView::deleteRecord() if (mTable->rowCount() == 0) { mEditWidget->setDisabled(true); //closing the editor is other option + return; } if (currentIndex.row() >= mTable->rowCount()) @@ -691,6 +711,7 @@ void CSVWorld::DialogueSubView::deleteRecord() void CSVWorld::DialogueSubView::requestFocus (const std::string& id) { mCurrentId = std::string(id); + mEditWidget->remake(mTable->getModelIndex (id, 0).row()); } From 7eb82f74aecfc97cadc014c8f13bfaaf50661016 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 16 Jun 2014 10:22:14 +0200 Subject: [PATCH 012/185] Fixed complitaion. --- apps/opencs/view/world/dialoguesubview.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 9d6538c1ce..e9910f42b5 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -600,12 +600,12 @@ void CSVWorld::DialogueSubView::setEditLock (bool locked) mLocked = locked; QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0)); - mEditWidget->setDisabled (state==CSMWorld::RecordBase::State_Deleted || locked); - if (currentIndex.isValid()) { CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (currentIndex.row(), 1)).toInt()); + mEditWidget->setDisabled (state==CSMWorld::RecordBase::State_Deleted || locked); + mCommandDispatcher.setEditLock (locked); } @@ -615,11 +615,12 @@ void CSVWorld::DialogueSubView::dataChanged(const QModelIndex & index) { QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0)); - mEditWidget->setDisabled (state==CSMWorld::RecordBase::State_Deleted || mLocked); if (currentIndex.isValid() && index.row() == currentIndex.row()) { CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (currentIndex.row(), 1)).toInt()); + + mEditWidget->setDisabled (state==CSMWorld::RecordBase::State_Deleted || mLocked); } } From 786c68f09a2f31c699c7753faa785d117f18b0e5 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 16 Jun 2014 11:31:57 +0200 Subject: [PATCH 013/185] refactoring dialogue subview --- apps/opencs/view/world/dialoguesubview.cpp | 20 ++++++++++++++++---- apps/opencs/view/world/dialoguesubview.hpp | 3 +++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index e9910f42b5..0f2ae73dde 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -448,7 +448,9 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM mCommandDispatcher (document, CSMWorld::UniversalId::getParentType (id.getType())) { connect(mTable, SIGNAL(dataChanged (const QModelIndex&, const QModelIndex&)), this, SLOT(dataChanged(const QModelIndex&))); - mCurrentId = id.getId(); + + changeCurrentId(id.getId()); + QWidget *mainWidget = new QWidget(this); QHBoxLayout *buttonsLayout = new QHBoxLayout; @@ -509,7 +511,9 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM new TableBottomBox (creatorFactory, document.getData(), document.getUndoStack(), id, this)); mBottom->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); + connect(mBottom, SIGNAL(requestFocus(const std::string&)), this, SLOT(requestFocus(const std::string&))); + connect(addButton, SIGNAL(clicked()), mBottom, SLOT(createRequest())); if(!mBottom->canCreateAndDelete()) @@ -549,7 +553,7 @@ void CSVWorld::DialogueSubView::prevId() setUniversalId(CSMWorld::UniversalId (static_cast (mTable->data (mTable->index (newRow, 2)).toInt()), mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData())); - mCurrentId = std::string(mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData()); + changeCurrentId(std::string(mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData())); mEditWidget->setDisabled(mLocked); @@ -585,7 +589,7 @@ void CSVWorld::DialogueSubView::nextId() setUniversalId(CSMWorld::UniversalId (static_cast (mTable->data (mTable->index (newRow, 2)).toInt()), mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData())); - mCurrentId = std::string(mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData()); + changeCurrentId(std::string(mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData())); mEditWidget->setDisabled(mLocked); @@ -615,7 +619,6 @@ void CSVWorld::DialogueSubView::dataChanged(const QModelIndex & index) { QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0)); - if (currentIndex.isValid() && index.row() == currentIndex.row()) { CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (currentIndex.row(), 1)).toInt()); @@ -746,3 +749,12 @@ void CSVWorld::DialogueSubView::viewRecord() emit focusId (params.first, params.second); } } + +void CSVWorld::DialogueSubView::changeCurrentId(const std::string& newId) +{ + std::vector selection; + mCurrentId = std::string(newId); + + selection.push_back(mCurrentId); + mCommandDispatcher.setSelection(selection); +} diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index 2a9dd2e4f6..2fdceacb1e 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -181,6 +181,9 @@ namespace CSVWorld bool sorting = false); virtual void setEditLock (bool locked); + + private: + void changeCurrentId(const std::string& newCurrent); private slots: From d6288a805512b1113896c8f2d09b052045af7369 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 16 Jun 2014 11:58:55 +0200 Subject: [PATCH 014/185] Remove unneded revert and delete slots --- apps/opencs/view/world/dialoguesubview.cpp | 80 +--------------------- apps/opencs/view/world/dialoguesubview.hpp | 4 -- 2 files changed, 3 insertions(+), 81 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 0f2ae73dde..e798c83200 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -495,8 +495,8 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM connect(nextButton, SIGNAL(clicked()), this, SLOT(nextId())); connect(prevButton, SIGNAL(clicked()), this, SLOT(prevId())); connect(cloneButton, SIGNAL(clicked()), this, SLOT(cloneRequest())); - connect(revertButton, SIGNAL(clicked()), this, SLOT(revertRecord())); - connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteRecord())); + connect(revertButton, SIGNAL(clicked()), &mCommandDispatcher, SLOT(executeRevert())); + connect(deleteButton, SIGNAL(clicked()), &mCommandDispatcher, SLOT(executeDelete())); mMainLayout = new QVBoxLayout(mainWidget); @@ -638,83 +638,9 @@ void CSVWorld::DialogueSubView::tableMimeDataDropped(QWidget* editor, } } -void CSVWorld::DialogueSubView::revertRecord() -{ - const int rows = mTable->rowCount(); - - QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0)); - - if (!currentIndex.isValid()) - { - return; - } - - const int currentRow = currentIndex.row(); - - if (!mLocked && mTable->columnCount() > 0 && currentRow < mTable->rowCount() ) - { - CSMWorld::RecordBase::State state = - static_cast (mTable->data (mTable->index (currentRow, 1)).toInt()); - - if (state!=CSMWorld::RecordBase::State_BaseOnly) - { - mUndoStack.push(new CSMWorld::RevertCommand(*mTable, mCurrentId)); - } - if (rows != mTable->rowCount()) - { - if (mTable->rowCount() == 0) - { - mEditWidget->setDisabled(true); //closing the editor is other option - - return; - } - if (currentIndex.row() >= mTable->rowCount()) - { - prevId(); - } else { - dataChanged(currentIndex); - } - } - } -} - -void CSVWorld::DialogueSubView::deleteRecord() -{ - const int rows = mTable->rowCount(); - QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0)); - - CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (currentIndex.row(), 1)).toInt()); - bool deledetedOrErased = (state == CSMWorld::RecordBase::State_Deleted); - - if (!mLocked && - currentIndex.isValid() && - mTable->columnCount() > 0 && - !deledetedOrErased && - currentIndex.row() < rows && - mBottom->canCreateAndDelete()) - { - mUndoStack.push(new CSMWorld::DeleteCommand(*mTable, mCurrentId)); - if (rows != mTable->rowCount()) - { - if (mTable->rowCount() == 0) - { - mEditWidget->setDisabled(true); //closing the editor is other option - - return; - } - if (currentIndex.row() >= mTable->rowCount()) - { - prevId(); - } else { - dataChanged(currentIndex); - } - } - } -} - void CSVWorld::DialogueSubView::requestFocus (const std::string& id) { - mCurrentId = std::string(id); + changeCurrentId(id); mEditWidget->remake(mTable->getModelIndex (id, 0).row()); } diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index 2fdceacb1e..050aad947f 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -195,10 +195,6 @@ namespace CSVWorld void viewRecord(); - void revertRecord(); - - void deleteRecord(); - void cloneRequest(); void dataChanged(const QModelIndex & index); From bbe7854968d5ecb44b767bc1b64963fd8bceddcc Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 17 Jun 2014 10:46:54 +0200 Subject: [PATCH 015/185] Corrected formatting to follow our standard better. --- apps/opencs/view/world/dialoguesubview.cpp | 32 +++++++++++----------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index e798c83200..bc2a6048ad 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -518,17 +518,17 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM if(!mBottom->canCreateAndDelete()) { - cloneButton->setDisabled(true); - addButton->setDisabled(true); - deleteButton->setDisabled(true); + cloneButton->setDisabled (true); + addButton->setDisabled (true); + deleteButton->setDisabled (true); } - dataChanged(mTable->getModelIndex(mCurrentId, 0)); - mMainLayout->addLayout(buttonsLayout); - setWidget(mainWidget); + dataChanged(mTable->getModelIndex (mCurrentId, 0)); + mMainLayout->addLayout (buttonsLayout); + setWidget (mainWidget); } -void CSVWorld::DialogueSubView::prevId() +void CSVWorld::DialogueSubView::prevId () { int newRow = mTable->getModelIndex(mCurrentId, 0).row() - 1; @@ -563,7 +563,7 @@ void CSVWorld::DialogueSubView::prevId() } } -void CSVWorld::DialogueSubView::nextId() +void CSVWorld::DialogueSubView::nextId () { int newRow = mTable->getModelIndex(mCurrentId, 0).row() + 1; @@ -615,7 +615,7 @@ void CSVWorld::DialogueSubView::setEditLock (bool locked) } -void CSVWorld::DialogueSubView::dataChanged(const QModelIndex & index) +void CSVWorld::DialogueSubView::dataChanged (const QModelIndex & index) { QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0)); @@ -627,10 +627,10 @@ void CSVWorld::DialogueSubView::dataChanged(const QModelIndex & index) } } -void CSVWorld::DialogueSubView::tableMimeDataDropped(QWidget* editor, - const QModelIndex& index, - const CSMWorld::UniversalId& id, - const CSMDoc::Document* document) +void CSVWorld::DialogueSubView::tableMimeDataDropped (QWidget* editor, + const QModelIndex& index, + const CSMWorld::UniversalId& id, + const CSMDoc::Document* document) { if (document == &mDocument) { @@ -662,9 +662,9 @@ void CSVWorld::DialogueSubView::showPreview () } } -void CSVWorld::DialogueSubView::viewRecord() +void CSVWorld::DialogueSubView::viewRecord () { - QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0)); + QModelIndex currentIndex(mTable->getModelIndex (mCurrentId, 0)); if (currentIndex.isValid() && currentIndex.row() < mTable->rowCount()) @@ -676,7 +676,7 @@ void CSVWorld::DialogueSubView::viewRecord() } } -void CSVWorld::DialogueSubView::changeCurrentId(const std::string& newId) +void CSVWorld::DialogueSubView::changeCurrentId (const std::string& newId) { std::vector selection; mCurrentId = std::string(newId); From 32fcc9ad6194533f7e367f46ae500c133cffb102 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 17 Jun 2014 11:14:12 +0200 Subject: [PATCH 016/185] Trying to merge. --- apps/opencs/model/world/idtable.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index 59fc3a5081..cbfb7f9233 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -43,9 +43,6 @@ QVariant CSMWorld::IdTable::data (const QModelIndex & index, int role) const if (role==Qt::EditRole && !mIdCollection->getColumn (index.column()).isEditable()) return QVariant(); -<<<<<<< Updated upstream - return mIdCollection->getData (index.row(), index.column()); -======= if (index.internalId() != 0) { std::pair parentAdress(unfoldIndexAdress(index.internalId())); @@ -53,7 +50,6 @@ QVariant CSMWorld::IdTable::data (const QModelIndex & index, int role) const } else { return mIdCollection->getData (index.row(), index.column()); } ->>>>>>> Stashed changes } QVariant CSMWorld::IdTable::headerData (int section, Qt::Orientation orientation, int role) const @@ -135,9 +131,6 @@ QModelIndex CSMWorld::IdTable::index (int row, int column, const QModelIndex& pa QModelIndex CSMWorld::IdTable::parent (const QModelIndex& index) const { -<<<<<<< Updated upstream - return QModelIndex(); -======= if (index.internalId() == 0) //0 is used for indexs with invalid parent (top level data) { return QModelIndex(); @@ -151,7 +144,6 @@ QModelIndex CSMWorld::IdTable::parent (const QModelIndex& index) const throw "Parent index is not present in the model"; } return createIndex(adress.first, adress.second, 0); ->>>>>>> Stashed changes } void CSMWorld::IdTable::addRecord (const std::string& id, UniversalId::Type type) @@ -280,9 +272,6 @@ std::pair CSMWorld::IdTable::view (int row) int CSMWorld::IdTable::getColumnId(int column) const { return mIdCollection->getColumn(column).getId(); -<<<<<<< Updated upstream -} -======= } bool CSMWorld::IdTable::hasChildren(const QModelIndex& index) const @@ -313,4 +302,3 @@ std::pair< int, int > CSMWorld::IdTable::unfoldIndexAdress (unsigned int id) con int column = id - row * this->columnCount(); return std::make_pair(row, column); } ->>>>>>> Stashed changes From 5bee682bb3dce1ccddddcb6bb4cf82e7055c2564 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 17 Jun 2014 14:58:25 +0200 Subject: [PATCH 017/185] modified: ../../view/world/dialoguesubview.cpp --- apps/opencs/model/world/idtable.cpp | 2 +- apps/opencs/model/world/refidadapterimp.hpp | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index 2a0ba43ea4..7db4662bad 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -42,7 +42,7 @@ QVariant CSMWorld::IdTable::data (const QModelIndex & index, int role) const if (role==Qt::EditRole && !mIdCollection->getColumn (index.column()).isEditable()) return QVariant(); - if (index.hasChildren()) + if (hasChildren(index)) { std::pair parentAdress(unfoldIndexAdress(index.internalId())); return mIdCollection->getNestedData(parentAdress.first, parentAdress.second, index.row(), index.column()); diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index cde5dc4550..a01e593712 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -624,11 +624,7 @@ namespace CSMWorld virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) const; virtual void setNestedData (const RefIdColumn *column, RefIdData& data, int index, -<<<<<<< HEAD const QVariant& value, int subRowIndex, int subColIndex) const; -======= - const QVariant& value, int subRowIndex, int subColIndex) const; ->>>>>>> 187fccc8cc630f1f469b4f5fc4e23a28ad8253ec virtual void setData (const RefIdColumn *column, RefIdData& data, int index, const QVariant& value) const; From ce5e889015ca9d8b585db2f1f24854e854ff5064 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 17 Jun 2014 18:28:49 +0200 Subject: [PATCH 018/185] Nested table sits inside it's own layout now. --- apps/opencs/model/world/idtable.cpp | 25 ++++---- apps/opencs/model/world/refidcollection.cpp | 3 +- apps/opencs/view/world/dialoguesubview.cpp | 59 +++++++++---------- apps/opencs/view/world/dialoguesubview.hpp | 64 ++++++++++++++------- 4 files changed, 88 insertions(+), 63 deletions(-) diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index 7db4662bad..49d23bed46 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -1,4 +1,3 @@ - #include "idtable.hpp" #include @@ -17,8 +16,7 @@ int CSMWorld::IdTable::rowCount (const QModelIndex & parent) const { if (hasChildren(parent)) { - int nestedRows = mIdCollection->getNestedRowsCount(parent.row(), parent.column()); - return nestedRows; + return mIdCollection->getNestedRowsCount(parent.row(), parent.column()); } return mIdCollection->getSize(); @@ -26,7 +24,8 @@ int CSMWorld::IdTable::rowCount (const QModelIndex & parent) const int CSMWorld::IdTable::columnCount (const QModelIndex & parent) const { - if (parent.isValid()) + if (parent.isValid() && + parent.data().isValid()) { return mIdCollection->getNestedColumnsCount(parent.row(), parent.column()); } @@ -42,16 +41,21 @@ QVariant CSMWorld::IdTable::data (const QModelIndex & index, int role) const if (role==Qt::EditRole && !mIdCollection->getColumn (index.column()).isEditable()) return QVariant(); - if (hasChildren(index)) + if (index.internalId() != 0) { std::pair parentAdress(unfoldIndexAdress(index.internalId())); - return mIdCollection->getNestedData(parentAdress.first, parentAdress.second, index.row(), index.column()); + return mIdCollection->getNestedData(parentAdress.first, + parentAdress.second, + index.row(), + index.column()); } else { return mIdCollection->getData (index.row(), index.column()); } } -QVariant CSMWorld::IdTable::headerData (int section, Qt::Orientation orientation, int role) const +QVariant CSMWorld::IdTable::headerData (int section, + Qt::Orientation orientation, + int role) const { if (orientation==Qt::Vertical) return QVariant(); @@ -68,7 +72,7 @@ QVariant CSMWorld::IdTable::headerData (int section, Qt::Orientation orientation return QVariant(); } -bool CSMWorld::IdTable::setData ( const QModelIndex &index, const QVariant &value, int role) +bool CSMWorld::IdTable::setData (const QModelIndex &index, const QVariant &value, int role) { if (mIdCollection->getColumn (index.column()).isEditable() && role==Qt::EditRole) { @@ -291,10 +295,7 @@ std::pair< int, int > CSMWorld::IdTable::unfoldIndexAdress (unsigned int id) con bool CSMWorld::IdTable::hasChildren(const QModelIndex& index) const { return (index.isValid() && - CSMWorld::ColumnBase::Display_Nested == static_cast (headerData - (index.column(), - Qt::Horizontal, - CSMWorld::ColumnBase::Role_Display).toInt()) && + CSMWorld::ColumnBase::Display_Nested == static_cast (headerData (index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()) && index.internalId() == 0 && index.data().isValid()); } diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index ad7fbd049d..9366633993 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -601,8 +601,7 @@ int CSMWorld::RefIdCollection::getNestedRowsCount(int row, int column) const const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdaptor (localIndex.second)); - const int count = adaptor.getNestedRowsCount(&mColumns.at(column), mData, localIndex.first); - return count; + return adaptor.getNestedRowsCount(&mColumns.at(column), mData, localIndex.first); } int CSMWorld::RefIdCollection::getNestedColumnsCount(int row, int column) const diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index a9a1bb96e5..08bac8b08d 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include "../../model/world/columnbase.hpp" #include "../../model/world/idtable.hpp" @@ -133,25 +134,25 @@ void CSVWorld::DialogueDelegateDispatcherProxy::tableMimeDataDropped(const std:: if (mDisplay == CSMWorld::ColumnBase::Display_Referenceable) { if ( type == CSMWorld::UniversalId::Type_Activator - || type == CSMWorld::UniversalId::Type_Potion - || type == CSMWorld::UniversalId::Type_Apparatus - || type == CSMWorld::UniversalId::Type_Armor - || type == CSMWorld::UniversalId::Type_Book - || type == CSMWorld::UniversalId::Type_Clothing - || type == CSMWorld::UniversalId::Type_Container - || type == CSMWorld::UniversalId::Type_Creature - || type == CSMWorld::UniversalId::Type_Door - || type == CSMWorld::UniversalId::Type_Ingredient - || type == CSMWorld::UniversalId::Type_CreatureLevelledList - || type == CSMWorld::UniversalId::Type_ItemLevelledList - || type == CSMWorld::UniversalId::Type_Light - || type == CSMWorld::UniversalId::Type_Lockpick - || type == CSMWorld::UniversalId::Type_Miscellaneous - || type == CSMWorld::UniversalId::Type_Npc - || type == CSMWorld::UniversalId::Type_Probe - || type == CSMWorld::UniversalId::Type_Repair - || type == CSMWorld::UniversalId::Type_Static - || type == CSMWorld::UniversalId::Type_Weapon) + || type == CSMWorld::UniversalId::Type_Potion + || type == CSMWorld::UniversalId::Type_Apparatus + || type == CSMWorld::UniversalId::Type_Armor + || type == CSMWorld::UniversalId::Type_Book + || type == CSMWorld::UniversalId::Type_Clothing + || type == CSMWorld::UniversalId::Type_Container + || type == CSMWorld::UniversalId::Type_Creature + || type == CSMWorld::UniversalId::Type_Door + || type == CSMWorld::UniversalId::Type_Ingredient + || type == CSMWorld::UniversalId::Type_CreatureLevelledList + || type == CSMWorld::UniversalId::Type_ItemLevelledList + || type == CSMWorld::UniversalId::Type_Light + || type == CSMWorld::UniversalId::Type_Lockpick + || type == CSMWorld::UniversalId::Type_Miscellaneous + || type == CSMWorld::UniversalId::Type_Npc + || type == CSMWorld::UniversalId::Type_Probe + || type == CSMWorld::UniversalId::Type_Repair + || type == CSMWorld::UniversalId::Type_Static + || type == CSMWorld::UniversalId::Type_Weapon) { type = CSMWorld::UniversalId::Type_Referenceable; } @@ -304,7 +305,7 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase:: } //lisp cond pairs would be nice in the C++ connect(proxy, SIGNAL(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display)), - this, SLOT(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display))); + this, SLOT(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display))); mProxys.push_back(proxy); //deleted in the destructor } @@ -334,7 +335,7 @@ mTable(table) remake (row); connect(&mDispatcher, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)), - this, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*))); + this, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*))); } void CSVWorld::EditWidget::remake(int row) @@ -366,9 +367,12 @@ void CSVWorld::EditWidget::remake(int row) QVBoxLayout *mainLayout = new QVBoxLayout(mMainWidget); QGridLayout *unlockedLayout = new QGridLayout(); QGridLayout *lockedLayout = new QGridLayout(); + QVBoxLayout *tablesLayout = new QVBoxLayout(); + mainLayout->addLayout(lockedLayout, 0); mainLayout->addWidget(line, 1); mainLayout->addLayout(unlockedLayout, 2); + mainLayout->addLayout(tablesLayout, 3); mainLayout->addStretch(1); int unlocked = 0; @@ -384,15 +388,12 @@ void CSVWorld::EditWidget::remake(int row) CSMWorld::ColumnBase::Display display = static_cast (mTable->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); - if (display == CSMWorld::ColumnBase::Display_Nested) + if (mTable->hasChildren(mTable->index(row, i))) { - const QModelIndex& parent = mTable->index(row, i); - if (parent.data().isValid() && mTable->hasChildren(parent)) - { - QTableView* table = new QTableView(this); - table->setModel(mTable); - table->setRootIndex(mTable->index(row, i)); - } + QTableView* table = new QTableView(); + table->setModel(mTable); + table->setRootIndex(mTable->index(row, i)); + tablesLayout->addWidget(table); } else { mDispatcher.makeDelegate (display); diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index 050aad947f..f36785e887 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -38,16 +38,23 @@ namespace CSVWorld { const CSMWorld::IdTable* mTable; public: - NotEditableSubDelegate(const CSMWorld::IdTable* table, QObject * parent = 0); + NotEditableSubDelegate(const CSMWorld::IdTable* table, + QObject * parent = 0); - virtual void setEditorData (QLabel* editor, const QModelIndex& index) const; + virtual void setEditorData (QLabel* editor, + const QModelIndex& index) const; - virtual void setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const; + virtual void setModelData (QWidget* editor, QAbstractItemModel* model, + const QModelIndex& index, + CSMWorld::ColumnBase::Display display) const; - virtual void paint (QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; + virtual void paint (QPainter* painter, + const QStyleOptionViewItem& option, + const QModelIndex& index) const; ///< does nothing - virtual QSize sizeHint (const QStyleOptionViewItem& option, const QModelIndex& index) const; + virtual QSize sizeHint (const QStyleOptionViewItem& option, + const QModelIndex& index) const; ///< does nothing virtual QWidget *createEditor (QWidget *parent, @@ -75,16 +82,20 @@ namespace CSVWorld std::auto_ptr mIndexWrapper; public: - DialogueDelegateDispatcherProxy(QWidget* editor, CSMWorld::ColumnBase::Display display); + DialogueDelegateDispatcherProxy(QWidget* editor, + CSMWorld::ColumnBase::Display display); QWidget* getEditor() const; public slots: void editorDataCommited(); void setIndex(const QModelIndex& index); - void tableMimeDataDropped(const std::vector& data, const CSMDoc::Document* document); + void tableMimeDataDropped(const std::vector& data, + const CSMDoc::Document* document); signals: - void editorDataCommited(QWidget* editor, const QModelIndex& index, CSMWorld::ColumnBase::Display display); + void editorDataCommited(QWidget* editor, + const QModelIndex& index, + CSMWorld::ColumnBase::Display display); void tableMimeDataDropped(QWidget* editor, const QModelIndex& index, const CSMWorld::UniversalId& id, @@ -105,30 +116,42 @@ namespace CSVWorld NotEditableSubDelegate mNotEditableDelegate; - std::vector mProxys; //once we move to the C++11 we should use unique_ptr + std::vector mProxys; +//once we move to the C++11 we should use unique_ptr public: - DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, QUndoStack& undoStack); + DialogueDelegateDispatcher(QObject* parent, + CSMWorld::IdTable* table, + QUndoStack& undoStack); ~DialogueDelegateDispatcher(); CSVWorld::CommandDelegate* makeDelegate(CSMWorld::ColumnBase::Display display); - QWidget* makeEditor(CSMWorld::ColumnBase::Display display, const QModelIndex& index); + QWidget* makeEditor(CSMWorld::ColumnBase::Display display, + const QModelIndex& index); ///< will return null if delegate is not present, parent of the widget is same as for dispatcher itself - virtual void setEditorData (QWidget* editor, const QModelIndex& index) const; + virtual void setEditorData (QWidget* editor, + const QModelIndex& index) const; - virtual void setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const; + virtual void setModelData (QWidget* editor, + QAbstractItemModel* model, + const QModelIndex& index, + CSMWorld::ColumnBase::Display display) const; - virtual void paint (QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; + virtual void paint (QPainter* painter, + const QStyleOptionViewItem& option, + const QModelIndex& index) const; ///< does nothing - virtual QSize sizeHint (const QStyleOptionViewItem& option, const QModelIndex& index) const; + virtual QSize sizeHint (const QStyleOptionViewItem& option, + const QModelIndex& index) const; ///< does nothing private slots: - void editorDataCommited(QWidget* editor, const QModelIndex& index, CSMWorld::ColumnBase::Display display); + void editorDataCommited(QWidget* editor, const QModelIndex& index, + CSMWorld::ColumnBase::Display display); signals: void tableMimeDataDropped(QWidget* editor, const QModelIndex& index, @@ -149,7 +172,8 @@ namespace CSVWorld public: - EditWidget (QWidget *parent, int row, CSMWorld::IdTable* table, QUndoStack& undoStack, bool createAndDelete = false); + EditWidget (QWidget *parent, int row, CSMWorld::IdTable* table, + QUndoStack& undoStack, bool createAndDelete = false); void remake(int row); @@ -167,7 +191,7 @@ namespace CSVWorld QVBoxLayout* mMainLayout; CSMWorld::IdTable* mTable; QUndoStack& mUndoStack; - std::string mCurrentId; + std::string mCurrentId; bool mLocked; const CSMDoc::Document& mDocument; TableBottomBox* mBottom; @@ -181,9 +205,9 @@ namespace CSVWorld bool sorting = false); virtual void setEditLock (bool locked); - + private: - void changeCurrentId(const std::string& newCurrent); + void changeCurrentId(const std::string& newCurrent); private slots: From 75b5513c6c4d6f59eced88b4e60deae43ad218fb Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 17 Jun 2014 22:02:20 +0200 Subject: [PATCH 019/185] Column is responsible for telling that it can nest columns now. --- apps/opencs/model/world/columnbase.cpp | 11 ++++++++--- apps/opencs/model/world/columnbase.hpp | 11 +++++++---- apps/opencs/model/world/idtable.cpp | 4 +--- apps/opencs/model/world/refidcollection.cpp | 6 +++--- apps/opencs/model/world/refidcollection.hpp | 4 ++-- 5 files changed, 21 insertions(+), 15 deletions(-) diff --git a/apps/opencs/model/world/columnbase.cpp b/apps/opencs/model/world/columnbase.cpp index f6363fe2eb..e81943843a 100644 --- a/apps/opencs/model/world/columnbase.cpp +++ b/apps/opencs/model/world/columnbase.cpp @@ -3,8 +3,8 @@ #include "columns.hpp" -CSMWorld::ColumnBase::ColumnBase (int columnId, Display displayType, int flags) -: mColumnId (columnId), mDisplayType (displayType), mFlags (flags) +CSMWorld::ColumnBase::ColumnBase (int columnId, Display displayType, int flags, bool canNest) + : mColumnId (columnId), mDisplayType (displayType), mFlags (flags), mCanNest(canNest) {} CSMWorld::ColumnBase::~ColumnBase() {} @@ -22,4 +22,9 @@ std::string CSMWorld::ColumnBase::getTitle() const int CSMWorld::ColumnBase::getId() const { return mColumnId; -} \ No newline at end of file +} + +bool CSMWorld::ColumnBase::canHaveNestedColumns() const +{ + return mCanNest; +} diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index c8670a03b8..9761b95aa0 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -91,14 +91,15 @@ namespace CSMWorld Display_QuestStatusType, Display_Gender, - Display_Nested + Display_NestedItemList }; int mColumnId; int mFlags; Display mDisplayType; + const bool mCanNest; - ColumnBase (int columnId, Display displayType, int flag); + ColumnBase (int columnId, Display displayType, int flag, bool canNest = false); virtual ~ColumnBase(); @@ -110,6 +111,8 @@ namespace CSMWorld virtual std::string getTitle() const; virtual int getId() const; + + bool canHaveNestedColumns() const; }; template @@ -117,8 +120,8 @@ namespace CSMWorld { int mFlags; - Column (int columnId, Display displayType, int flags = Flag_Table | Flag_Dialogue) - : ColumnBase (columnId, displayType, flags) {} + Column (int columnId, Display displayType, int flags = Flag_Table | Flag_Dialogue, bool canNest = false) + : ColumnBase (columnId, displayType, flags, canNest) {} virtual QVariant get (const Record& record) const = 0; diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index 49d23bed46..6aba322c14 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -1,7 +1,5 @@ #include "idtable.hpp" -#include - #include "collectionbase.hpp" #include "columnbase.hpp" @@ -295,7 +293,7 @@ std::pair< int, int > CSMWorld::IdTable::unfoldIndexAdress (unsigned int id) con bool CSMWorld::IdTable::hasChildren(const QModelIndex& index) const { return (index.isValid() && - CSMWorld::ColumnBase::Display_Nested == static_cast (headerData (index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()) && index.internalId() == 0 && + mIdCollection->getColumn (index.column()).canHaveNestedColumns() && index.data().isValid()); } diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 9366633993..a8fac216bc 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -12,8 +12,8 @@ #include "columns.hpp" CSMWorld::RefIdColumn::RefIdColumn (int columnId, Display displayType, int flag, - bool editable, bool userEditable) -: ColumnBase (columnId, displayType, flag), mEditable (editable), mUserEditable (userEditable) + bool editable, bool userEditable, bool canNest) + : ColumnBase (columnId, displayType, flag, canNest), mEditable (editable), mUserEditable (userEditable) {} bool CSMWorld::RefIdColumn::isEditable() const @@ -166,7 +166,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn (Columns::ColumnId_Respawn, ColumnBase::Display_Boolean)); const RefIdColumn *respawn = &mColumns.back(); - mColumns.push_back(RefIdColumn (Columns::ColumnId_ContainerContent, ColumnBase::Display_Nested, ColumnBase::Flag_Dialogue, false, false)); + mColumns.push_back(RefIdColumn (Columns::ColumnId_ContainerContent, ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue, true, true, true)); const RefIdColumn *content = &mColumns.back(); CreatureColumns creatureColumns (actorsColumns); diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index cb0baa45be..fec621ac1d 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -26,8 +26,8 @@ namespace CSMWorld public: RefIdColumn (int columnId, Display displayType, - int flag = Flag_Table | Flag_Dialogue, bool editable = true, - bool userEditable = true); + int flag = Flag_Table | Flag_Dialogue, bool editable = true, + bool userEditable = true, bool canNest = false); virtual bool isEditable() const; From 1fb18873cbe88d3e41c6e66c1a4fce7132d72c11 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 18 Jun 2014 15:35:31 +0200 Subject: [PATCH 020/185] adding proxy model that is ment to be used by the dialoguesubview --- apps/opencs/CMakeLists.txt | 1 + apps/opencs/model/world/columns.hpp | 1 + apps/opencs/model/world/nestedtablemodel.cpp | 34 ++++++++++++++++ apps/opencs/model/world/nestedtablemodel.hpp | 42 ++++++++++++++++++++ 4 files changed, 78 insertions(+) create mode 100644 apps/opencs/model/world/nestedtablemodel.cpp create mode 100644 apps/opencs/model/world/nestedtablemodel.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index d9cac95f33..e76e64610e 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -19,6 +19,7 @@ opencs_hdrs_noqt (model/doc opencs_units (model/world idtable idtableproxymodel regionmap data commanddispatcher + nestedtablemodel ) diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index fa9c92e7d6..e824c4392e 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -168,6 +168,7 @@ namespace CSMWorld ColumnId_Scope = 155, ColumnId_ReferenceableId = 156, ColumnId_ContainerContent = 157, + ColumnId_ItemCount = 158, // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. diff --git a/apps/opencs/model/world/nestedtablemodel.cpp b/apps/opencs/model/world/nestedtablemodel.cpp new file mode 100644 index 0000000000..20a68faad8 --- /dev/null +++ b/apps/opencs/model/world/nestedtablemodel.cpp @@ -0,0 +1,34 @@ +#include "nestedtablemodel.hpp" + +#include "./idtable.hpp" + +CSMWorld::NestedTableModel::NestedTableModel(const QModelIndex& parent, + ColumnBase::Display columnId, + CSMWorld::IdTable* parentModel) + : mParentColumn(parent.column()) +{ + const int parentRow = parent.row(); + mId = std::string(parentModel->index(parentRow, 0).data().toString().toUtf8()); + QAbstractProxyModel::setSourceModel(parentModel); +} + +QModelIndex CSMWorld::NestedTableModel::mapFromSource(const QModelIndex& sourceIndex) const +{ + const QModelIndex& testedParent = sourceModel()->parent(sourceIndex); + const QModelIndex& parent = dynamic_cast(sourceModel())->getModelIndex (mId, mParentColumn); + if (testedParent == parent) + { + return createIndex(sourceIndex.row(), sourceIndex.column()); + } + else + { + return QModelIndex(); + } + +} + +QModelIndex CSMWorld::NestedTableModel::mapToSource(const QModelIndex& proxyIndex) const +{ + const QModelIndex& parent = dynamic_cast(sourceModel())->getModelIndex (mId, mParentColumn); + return sourceModel()->index(proxyIndex.row(), proxyIndex.column(), parent); +} diff --git a/apps/opencs/model/world/nestedtablemodel.hpp b/apps/opencs/model/world/nestedtablemodel.hpp new file mode 100644 index 0000000000..acab1f8510 --- /dev/null +++ b/apps/opencs/model/world/nestedtablemodel.hpp @@ -0,0 +1,42 @@ + +#ifndef CSM_WOLRD_NESTEDTABLEMODEL_H +#define CSM_WOLRD_NESTEDTABLEMODEL_H + +#include + +#include + +#include "universalid.hpp" +#include "columns.hpp" +#include "columnbase.hpp" + +/*! \brief + * Proxy model used to connect view in the dialogue into the nested columns of the main model. + */ + +namespace CSMWorld +{ + class CollectionBase; + class RecordBase; + class IdTable; + + class NestedTableModel : public QAbstractProxyModel + { + const int mParentColumn; + std::string mId; + std::vector mHeaderTitle; + std::vector mHeaderDisplay; + + public: + NestedTableModel(const QModelIndex& parent, + ColumnBase::Display displayType, + IdTable* parentModel); + //parent is the parent of columns to work with. Columnid provides information about the column + + virtual QModelIndex mapFromSource(const QModelIndex& sourceIndex) const; + + virtual QModelIndex mapToSource(const QModelIndex& proxyIndex) const; + }; +} + +#endif From b63f2f4cd538651643d9084f89d30cebbdcee89d Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 18 Jun 2014 16:53:46 +0200 Subject: [PATCH 021/185] Actually using new nestedmodel --- apps/opencs/model/world/nestedtablemodel.cpp | 48 +++++++++++++++++++- apps/opencs/model/world/nestedtablemodel.hpp | 15 ++++-- apps/opencs/view/world/dialoguesubview.cpp | 23 ++++++++-- apps/opencs/view/world/dialoguesubview.hpp | 4 ++ 4 files changed, 81 insertions(+), 9 deletions(-) diff --git a/apps/opencs/model/world/nestedtablemodel.cpp b/apps/opencs/model/world/nestedtablemodel.cpp index 20a68faad8..9a685557eb 100644 --- a/apps/opencs/model/world/nestedtablemodel.cpp +++ b/apps/opencs/model/world/nestedtablemodel.cpp @@ -1,10 +1,11 @@ #include "nestedtablemodel.hpp" +#include #include "./idtable.hpp" CSMWorld::NestedTableModel::NestedTableModel(const QModelIndex& parent, ColumnBase::Display columnId, - CSMWorld::IdTable* parentModel) + CSMWorld::IdTable* parentModel) : mParentColumn(parent.column()) { const int parentRow = parent.row(); @@ -20,7 +21,7 @@ QModelIndex CSMWorld::NestedTableModel::mapFromSource(const QModelIndex& sourceI { return createIndex(sourceIndex.row(), sourceIndex.column()); } - else + else { return QModelIndex(); } @@ -32,3 +33,46 @@ QModelIndex CSMWorld::NestedTableModel::mapToSource(const QModelIndex& proxyInde const QModelIndex& parent = dynamic_cast(sourceModel())->getModelIndex (mId, mParentColumn); return sourceModel()->index(proxyIndex.row(), proxyIndex.column(), parent); } + +int CSMWorld::NestedTableModel::rowCount(const QModelIndex& index) const +{ + assert (!index.isValid()); + + CSMWorld::IdTable* table = dynamic_cast(sourceModel()); + + return table->rowCount(table->getModelIndex(mId, mParentColumn)); +} + +int CSMWorld::NestedTableModel::columnCount(const QModelIndex& parent) const +{ + assert (!parent.isValid()); + + CSMWorld::IdTable* table = dynamic_cast(sourceModel()); + + return table->columnCount(table->getModelIndex(mId, mParentColumn)); +} + +QModelIndex CSMWorld::NestedTableModel::index(int row, int column, const QModelIndex& parent) const +{ + assert (!parent.isValid()); + + CSMWorld::IdTable* table = dynamic_cast(sourceModel()); + + unsigned rows = table->rowCount(parent); + usigned columns = table->columnCount(parent); + + if (row < 0 || + row >= rows || + column < 0 || + column >= columns) + { + return QModelIndex(); + } + + return createIndex(row, column); +} + +QModelIndex CSMWorld::NestedTableModel::parent(const QModelIndex& index) const +{ + return QModelIndex(); +} diff --git a/apps/opencs/model/world/nestedtablemodel.hpp b/apps/opencs/model/world/nestedtablemodel.hpp index acab1f8510..be29be2ca2 100644 --- a/apps/opencs/model/world/nestedtablemodel.hpp +++ b/apps/opencs/model/world/nestedtablemodel.hpp @@ -1,4 +1,3 @@ - #ifndef CSM_WOLRD_NESTEDTABLEMODEL_H #define CSM_WOLRD_NESTEDTABLEMODEL_H @@ -26,16 +25,24 @@ namespace CSMWorld std::string mId; std::vector mHeaderTitle; std::vector mHeaderDisplay; - + public: NestedTableModel(const QModelIndex& parent, ColumnBase::Display displayType, IdTable* parentModel); //parent is the parent of columns to work with. Columnid provides information about the column - + virtual QModelIndex mapFromSource(const QModelIndex& sourceIndex) const; - + virtual QModelIndex mapToSource(const QModelIndex& proxyIndex) const; + + virtual int rowCount(const QModelIndex& parent) const; + + virtual int columnCount(const QModelIndex& parent) const; + + virtual QModelIndex index(int row, int column, const QModelIndex& parent) const; + + virtual QModelIndex parent(const QModelIndex& index) const; }; } diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 08bac8b08d..7a0e2efec8 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -22,6 +22,7 @@ #include #include +#include "../../model/world/nestedtablemodel.hpp" #include "../../model/world/columnbase.hpp" #include "../../model/world/idtable.hpp" #include "../../model/world/columns.hpp" @@ -324,6 +325,14 @@ CSVWorld::DialogueDelegateDispatcher::~DialogueDelegateDispatcher() =============================================================EditWidget===================================================== */ +CSVWorld::EditWidget::~EditWidget() +{ + for (unsigned i = 0; i < mNestedModels.size(); ++i) + { + delete mNestedModels[i]; + } +} + CSVWorld::EditWidget::EditWidget(QWidget *parent, int row, CSMWorld::IdTable* table, QUndoStack& undoStack, bool createAndDelete) : mDispatcher(this, table, undoStack), QScrollArea(parent), @@ -340,6 +349,11 @@ mTable(table) void CSVWorld::EditWidget::remake(int row) { + for (unsigned i = 0; i < mNestedModels.size(); ++i) + { + delete mNestedModels[i]; + } + if (mMainWidget) { delete mMainWidget; @@ -379,7 +393,7 @@ void CSVWorld::EditWidget::remake(int row) int locked = 0; const int columns = mTable->columnCount(); - for (int i=0; iheaderData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt(); @@ -390,9 +404,12 @@ void CSVWorld::EditWidget::remake(int row) if (mTable->hasChildren(mTable->index(row, i))) { + mNestedModels.push_back(new CSMWorld::NestedTableModel (mTable->index(row, i), display, mTable)); + QTableView* table = new QTableView(); - table->setModel(mTable); - table->setRootIndex(mTable->index(row, i)); + + table->setModel(*(mNestedModels.rbegin())); + tablesLayout->addWidget(table); } else { diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index f36785e887..90a3655924 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -21,6 +21,7 @@ class QVBoxLayout; namespace CSMWorld { class IdTable; + class NestedTableModel; } namespace CSMDoc @@ -169,12 +170,15 @@ namespace CSVWorld QWidget* mMainWidget; CSMWorld::IdTable* mTable; QUndoStack& mUndoStack; + std::vector mNestedModels; //Plain, raw C pointers, deleted in the dtor public: EditWidget (QWidget *parent, int row, CSMWorld::IdTable* table, QUndoStack& undoStack, bool createAndDelete = false); + ~EditWidget(); + void remake(int row); signals: From 873cfcf447136b4e442b550c48573d8efc55ad47 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 18 Jun 2014 17:34:21 +0200 Subject: [PATCH 022/185] implemented basic headerData (still work in progress) --- apps/opencs/model/world/nestedtablemodel.cpp | 44 +++++++++++++++++++- apps/opencs/model/world/nestedtablemodel.hpp | 5 +++ apps/opencs/view/world/dialoguesubview.cpp | 2 +- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/world/nestedtablemodel.cpp b/apps/opencs/model/world/nestedtablemodel.cpp index 9a685557eb..9ae4bdfd36 100644 --- a/apps/opencs/model/world/nestedtablemodel.cpp +++ b/apps/opencs/model/world/nestedtablemodel.cpp @@ -9,8 +9,12 @@ CSMWorld::NestedTableModel::NestedTableModel(const QModelIndex& parent, : mParentColumn(parent.column()) { const int parentRow = parent.row(); + mId = std::string(parentModel->index(parentRow, 0).data().toString().toUtf8()); + QAbstractProxyModel::setSourceModel(parentModel); + + setupHeaderVectors(columnId); } QModelIndex CSMWorld::NestedTableModel::mapFromSource(const QModelIndex& sourceIndex) const @@ -58,8 +62,8 @@ QModelIndex CSMWorld::NestedTableModel::index(int row, int column, const QModelI CSMWorld::IdTable* table = dynamic_cast(sourceModel()); - unsigned rows = table->rowCount(parent); - usigned columns = table->columnCount(parent); + int rows = table->rowCount(parent); + int columns = table->columnCount(parent); if (row < 0 || row >= rows || @@ -76,3 +80,39 @@ QModelIndex CSMWorld::NestedTableModel::parent(const QModelIndex& index) const { return QModelIndex(); } + +QVariant CSMWorld::NestedTableModel::headerData(int section, + Qt::Orientation orientation, + int role) const +{ + if (orientation==Qt::Vertical) + return QVariant(); + + if (role==Qt::DisplayRole) + return tr (mHeaderTitle[section].c_str()); + + if (role==ColumnBase::Role_Flags) + return QVariant(); //TODO + + if (role==ColumnBase::Role_Display) + return mHeaderDisplay[section]; + + return QVariant(); +} + +void CSMWorld::NestedTableModel::setupHeaderVectors(ColumnBase::Display columnId) +{ + switch(columnId) + { + case ColumnBase::Display_NestedItemList: + mHeaderTitle.push_back("test1"); + mHeaderTitle.push_back("test2"); + + mHeaderDisplay.push_back(ColumnBase::Display_String); + mHeaderDisplay.push_back(ColumnBase::Display_Integer); + break; + + default: + assert(false); + } +} diff --git a/apps/opencs/model/world/nestedtablemodel.hpp b/apps/opencs/model/world/nestedtablemodel.hpp index be29be2ca2..80c7f5a8e8 100644 --- a/apps/opencs/model/world/nestedtablemodel.hpp +++ b/apps/opencs/model/world/nestedtablemodel.hpp @@ -43,6 +43,11 @@ namespace CSMWorld virtual QModelIndex index(int row, int column, const QModelIndex& parent) const; virtual QModelIndex parent(const QModelIndex& index) const; + + virtual QVariant headerData ( int section, Qt::Orientation orientation, int role ) const; + + private: + void setupHeaderVectors(ColumnBase::Display columnId); }; } diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 7a0e2efec8..109f0c3fa9 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -393,7 +393,7 @@ void CSVWorld::EditWidget::remake(int row) int locked = 0; const int columns = mTable->columnCount(); - for (unsigned i=0; iheaderData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt(); From 256b075914b97194e408d208c6db7b6fe5300f76 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 19 Jun 2014 16:11:31 +0200 Subject: [PATCH 023/185] getting rid of not needed abstract class --- apps/opencs/model/world/columnbase.hpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 9761b95aa0..164ca4302f 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -130,12 +130,6 @@ namespace CSMWorld throw std::logic_error ("Column " + getTitle() + " is not editable"); } }; - - template - struct NestedColumn - { - virtual QVariant getNested(const Record& record, int subColumn, int subSow) const = 0; - }; } #endif From a076798f8febb9034b9dc0944c7899230d867b16 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 19 Jun 2014 18:46:09 +0200 Subject: [PATCH 024/185] Quick and dirty prototype of actual nested header data implementation --- apps/opencs/model/world/columnbase.cpp | 14 +++++ apps/opencs/model/world/columnbase.hpp | 6 ++ apps/opencs/model/world/columns.cpp | 15 +++++ apps/opencs/model/world/columns.hpp | 4 ++ apps/opencs/model/world/idtable.cpp | 21 +++++++ apps/opencs/model/world/idtable.hpp | 2 + apps/opencs/model/world/nestedtablemodel.cpp | 58 ++++---------------- apps/opencs/model/world/nestedtablemodel.hpp | 3 +- apps/opencs/model/world/refidcollection.cpp | 2 + 9 files changed, 76 insertions(+), 49 deletions(-) diff --git a/apps/opencs/model/world/columnbase.cpp b/apps/opencs/model/world/columnbase.cpp index e81943843a..c0a264a1fa 100644 --- a/apps/opencs/model/world/columnbase.cpp +++ b/apps/opencs/model/world/columnbase.cpp @@ -3,6 +3,8 @@ #include "columns.hpp" +#include + CSMWorld::ColumnBase::ColumnBase (int columnId, Display displayType, int flags, bool canNest) : mColumnId (columnId), mDisplayType (displayType), mFlags (flags), mCanNest(canNest) {} @@ -28,3 +30,15 @@ bool CSMWorld::ColumnBase::canHaveNestedColumns() const { return mCanNest; } + +std::string CSMWorld::ColumnBase::getNestedColumnTitle(int columnNumber) const +{ + return Columns::getName (mDisplayType, columnNumber); +} + +void CSMWorld::ColumnBase::addNestedColumnDisplay(CSMWorld::ColumnBase::Display displayDefinition) +{ + assert (canHaveNestedColumns()); + + mNestedDisplayType.push_back(displayDefinition); +} diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 164ca4302f..0cd1f722ff 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -2,6 +2,7 @@ #define CSM_WOLRD_COLUMNBASE_H #include +#include #include #include @@ -97,6 +98,7 @@ namespace CSMWorld int mColumnId; int mFlags; Display mDisplayType; + std::vector mNestedDisplayType; const bool mCanNest; ColumnBase (int columnId, Display displayType, int flag, bool canNest = false); @@ -110,6 +112,10 @@ namespace CSMWorld virtual std::string getTitle() const; + std::string getNestedColumnTitle(int columnNumber) const; + + virtual void addNestedColumnDisplay(Display displayDefinition); + virtual int getId() const; bool canHaveNestedColumns() const; diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 7410780e08..e39badeb51 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -216,6 +216,21 @@ std::string CSMWorld::Columns::getName (ColumnId column) return ""; } +std::string CSMWorld::Columns::getName(CSMWorld::ColumnBase::Display displayType, int columnNumber) +{ +//TODO, this is just temporary solution + switch (displayType) + { + case CSMWorld::ColumnBase::Display_NestedItemList: + if (columnNumber == 0) + return "ID"; + + if (columnNumber == 1) + return "Count"; + } + return "Do yourself a favor and take a look at the columns.cpp"; +} + int CSMWorld::Columns::getId (const std::string& name) { std::string name2 = Misc::StringUtils::lowerCase (name); diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index e824c4392e..436ca1334b 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -4,6 +4,8 @@ #include #include +#include "columnbase.hpp" + namespace CSMWorld { namespace Columns @@ -208,6 +210,8 @@ namespace CSMWorld std::string getName (ColumnId column); + std::string getName (ColumnBase::Display displayType, int columnNumber); + int getId (const std::string& name); ///< Will return -1 for an invalid name. diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index 6aba322c14..fd2547ecf6 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -1,5 +1,7 @@ #include "idtable.hpp" +#include + #include "collectionbase.hpp" #include "columnbase.hpp" @@ -70,6 +72,25 @@ QVariant CSMWorld::IdTable::headerData (int section, return QVariant(); } +QVariant CSMWorld::IdTable::nestedHeaderData(int section, int subSection, Qt::Orientation orientation, int role) const +{ + assert(mIdCollection->getColumn(section).canHaveNestedColumns()); + + if (orientation==Qt::Vertical) + return QVariant(); + + if (role==Qt::DisplayRole) + return tr (mIdCollection->getColumn(section).getNestedColumnTitle(subSection).c_str()); + + if (role==ColumnBase::Role_Flags) + return mIdCollection->getColumn (section).mFlags; + + if (role==ColumnBase::Role_Display) + return mIdCollection->getColumn (section).mNestedDisplayType.at(subSection); + + return QVariant(); +} + bool CSMWorld::IdTable::setData (const QModelIndex &index, const QVariant &value, int role) { if (mIdCollection->getColumn (index.column()).isEditable() && role==Qt::EditRole) diff --git a/apps/opencs/model/world/idtable.hpp b/apps/opencs/model/world/idtable.hpp index 6dc6f3e33b..29d1f134ad 100644 --- a/apps/opencs/model/world/idtable.hpp +++ b/apps/opencs/model/world/idtable.hpp @@ -72,6 +72,8 @@ namespace CSMWorld virtual QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + QVariant nestedHeaderData(int section, int subSection, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + virtual bool setData ( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); virtual Qt::ItemFlags flags (const QModelIndex & index) const; diff --git a/apps/opencs/model/world/nestedtablemodel.cpp b/apps/opencs/model/world/nestedtablemodel.cpp index 9ae4bdfd36..534ec5d100 100644 --- a/apps/opencs/model/world/nestedtablemodel.cpp +++ b/apps/opencs/model/world/nestedtablemodel.cpp @@ -6,21 +6,20 @@ CSMWorld::NestedTableModel::NestedTableModel(const QModelIndex& parent, ColumnBase::Display columnId, CSMWorld::IdTable* parentModel) - : mParentColumn(parent.column()) + : mParentColumn(parent.column()), + mMainModel(parentModel) { const int parentRow = parent.row(); mId = std::string(parentModel->index(parentRow, 0).data().toString().toUtf8()); QAbstractProxyModel::setSourceModel(parentModel); - - setupHeaderVectors(columnId); } QModelIndex CSMWorld::NestedTableModel::mapFromSource(const QModelIndex& sourceIndex) const { - const QModelIndex& testedParent = sourceModel()->parent(sourceIndex); - const QModelIndex& parent = dynamic_cast(sourceModel())->getModelIndex (mId, mParentColumn); + const QModelIndex& testedParent = mMainModel->parent(sourceIndex); + const QModelIndex& parent = mMainModel->getModelIndex (mId, mParentColumn); if (testedParent == parent) { return createIndex(sourceIndex.row(), sourceIndex.column()); @@ -34,36 +33,30 @@ QModelIndex CSMWorld::NestedTableModel::mapFromSource(const QModelIndex& sourceI QModelIndex CSMWorld::NestedTableModel::mapToSource(const QModelIndex& proxyIndex) const { - const QModelIndex& parent = dynamic_cast(sourceModel())->getModelIndex (mId, mParentColumn); - return sourceModel()->index(proxyIndex.row(), proxyIndex.column(), parent); + const QModelIndex& parent = mMainModel->getModelIndex (mId, mParentColumn); + return mMainModel->index(proxyIndex.row(), proxyIndex.column(), parent); } int CSMWorld::NestedTableModel::rowCount(const QModelIndex& index) const { assert (!index.isValid()); - CSMWorld::IdTable* table = dynamic_cast(sourceModel()); - - return table->rowCount(table->getModelIndex(mId, mParentColumn)); + return mMainModel->rowCount(mMainModel->getModelIndex(mId, mParentColumn)); } int CSMWorld::NestedTableModel::columnCount(const QModelIndex& parent) const { assert (!parent.isValid()); - CSMWorld::IdTable* table = dynamic_cast(sourceModel()); - - return table->columnCount(table->getModelIndex(mId, mParentColumn)); + return mMainModel->columnCount(mMainModel->getModelIndex(mId, mParentColumn)); } QModelIndex CSMWorld::NestedTableModel::index(int row, int column, const QModelIndex& parent) const { assert (!parent.isValid()); - CSMWorld::IdTable* table = dynamic_cast(sourceModel()); - - int rows = table->rowCount(parent); - int columns = table->columnCount(parent); + int rows = mMainModel->rowCount(parent); + int columns = mMainModel->columnCount(parent); if (row < 0 || row >= rows || @@ -85,34 +78,5 @@ QVariant CSMWorld::NestedTableModel::headerData(int section, Qt::Orientation orientation, int role) const { - if (orientation==Qt::Vertical) - return QVariant(); - - if (role==Qt::DisplayRole) - return tr (mHeaderTitle[section].c_str()); - - if (role==ColumnBase::Role_Flags) - return QVariant(); //TODO - - if (role==ColumnBase::Role_Display) - return mHeaderDisplay[section]; - - return QVariant(); -} - -void CSMWorld::NestedTableModel::setupHeaderVectors(ColumnBase::Display columnId) -{ - switch(columnId) - { - case ColumnBase::Display_NestedItemList: - mHeaderTitle.push_back("test1"); - mHeaderTitle.push_back("test2"); - - mHeaderDisplay.push_back(ColumnBase::Display_String); - mHeaderDisplay.push_back(ColumnBase::Display_Integer); - break; - - default: - assert(false); - } + return mMainModel->nestedHeaderData(mParentColumn, section, orientation, role); } diff --git a/apps/opencs/model/world/nestedtablemodel.hpp b/apps/opencs/model/world/nestedtablemodel.hpp index 80c7f5a8e8..404051efc3 100644 --- a/apps/opencs/model/world/nestedtablemodel.hpp +++ b/apps/opencs/model/world/nestedtablemodel.hpp @@ -22,9 +22,8 @@ namespace CSMWorld class NestedTableModel : public QAbstractProxyModel { const int mParentColumn; + IdTable* mMainModel; std::string mId; - std::vector mHeaderTitle; - std::vector mHeaderDisplay; public: NestedTableModel(const QModelIndex& parent, diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index a8fac216bc..47c8ec800f 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -168,6 +168,8 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back(RefIdColumn (Columns::ColumnId_ContainerContent, ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue, true, true, true)); const RefIdColumn *content = &mColumns.back(); + (&mColumns.back())->addNestedColumnDisplay(CSMWorld::ColumnBase::Display_String); + (&mColumns.back())->addNestedColumnDisplay(CSMWorld::ColumnBase::Display_Integer); CreatureColumns creatureColumns (actorsColumns); From 894c98ee89479294fff69a674030a51d93353493 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 20 Jun 2014 13:40:54 +0200 Subject: [PATCH 025/185] Added extra columnid type to use for ID of the inventory item --- apps/opencs/model/world/columnbase.cpp | 16 ++++++++++++---- apps/opencs/model/world/columnbase.hpp | 12 ++++++++---- apps/opencs/model/world/columns.cpp | 17 ++--------------- apps/opencs/model/world/columns.hpp | 3 +-- apps/opencs/model/world/refidcollection.cpp | 2 ++ 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/apps/opencs/model/world/columnbase.cpp b/apps/opencs/model/world/columnbase.cpp index c0a264a1fa..59ee391263 100644 --- a/apps/opencs/model/world/columnbase.cpp +++ b/apps/opencs/model/world/columnbase.cpp @@ -1,4 +1,3 @@ - #include "columnbase.hpp" #include "columns.hpp" @@ -33,12 +32,21 @@ bool CSMWorld::ColumnBase::canHaveNestedColumns() const std::string CSMWorld::ColumnBase::getNestedColumnTitle(int columnNumber) const { - return Columns::getName (mDisplayType, columnNumber); + assert (mCanNest); + + return Columns::getName(static_cast(mNestedColumnId[columnNumber])); } void CSMWorld::ColumnBase::addNestedColumnDisplay(CSMWorld::ColumnBase::Display displayDefinition) { - assert (canHaveNestedColumns()); - + assert (mCanNest); + mNestedDisplayType.push_back(displayDefinition); } + +void CSMWorld::ColumnBase::addNestedColumnId(int columnId) +{ + assert (mCanNest); + + mNestedColumnId.push_back(columnId); +} diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 0cd1f722ff..1cc45780ff 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -31,7 +31,7 @@ namespace CSMWorld Display_String, Display_LongString, - //CONCRETE TYPES STARTS HERE + //CONCRETE TYPES STARTS HERE (for drag and drop) Display_Skill, Display_Class, Display_Faction, @@ -92,13 +92,15 @@ namespace CSMWorld Display_QuestStatusType, Display_Gender, + //Those are top level columns that nest other columns Display_NestedItemList }; int mColumnId; int mFlags; Display mDisplayType; - std::vector mNestedDisplayType; + std::vector mNestedDisplayType; //used only for the columns that actually nest other columns + std::vector mNestedColumnId; //used only for the columns that actually nest other columns const bool mCanNest; ColumnBase (int columnId, Display displayType, int flag, bool canNest = false); @@ -113,8 +115,10 @@ namespace CSMWorld virtual std::string getTitle() const; std::string getNestedColumnTitle(int columnNumber) const; - - virtual void addNestedColumnDisplay(Display displayDefinition); + + void addNestedColumnDisplay(Display displayDefinition); + + void addNestedColumnId(int columnId); virtual int getId() const; diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index e39badeb51..1898277a5d 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -174,6 +174,8 @@ namespace CSMWorld { ColumnId_PcRank, "PC Rank" }, { ColumnId_Scope, "Scope" }, { ColumnId_ReferenceableId, "Referenceable ID" }, + { ColumnId_InventoryItemId, "ID"}, + { ColumnId_ItemCount, "Count"}, { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, @@ -216,21 +218,6 @@ std::string CSMWorld::Columns::getName (ColumnId column) return ""; } -std::string CSMWorld::Columns::getName(CSMWorld::ColumnBase::Display displayType, int columnNumber) -{ -//TODO, this is just temporary solution - switch (displayType) - { - case CSMWorld::ColumnBase::Display_NestedItemList: - if (columnNumber == 0) - return "ID"; - - if (columnNumber == 1) - return "Count"; - } - return "Do yourself a favor and take a look at the columns.cpp"; -} - int CSMWorld::Columns::getId (const std::string& name) { std::string name2 = Misc::StringUtils::lowerCase (name); diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 436ca1334b..5d8ddb87d7 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -171,6 +171,7 @@ namespace CSMWorld ColumnId_ReferenceableId = 156, ColumnId_ContainerContent = 157, ColumnId_ItemCount = 158, + ColumnId_InventoryItemId = 159, // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. @@ -210,8 +211,6 @@ namespace CSMWorld std::string getName (ColumnId column); - std::string getName (ColumnBase::Display displayType, int columnNumber); - int getId (const std::string& name); ///< Will return -1 for an invalid name. diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 47c8ec800f..9fe42af962 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -170,6 +170,8 @@ CSMWorld::RefIdCollection::RefIdCollection() const RefIdColumn *content = &mColumns.back(); (&mColumns.back())->addNestedColumnDisplay(CSMWorld::ColumnBase::Display_String); (&mColumns.back())->addNestedColumnDisplay(CSMWorld::ColumnBase::Display_Integer); + (&mColumns.back())->addNestedColumnId(Columns::ColumnId_InventoryItemId); + (&mColumns.back())->addNestedColumnId(Columns::ColumnId_ItemCount); CreatureColumns creatureColumns (actorsColumns); From 88c5288eafb5a7260e616c0943eba3f6935f3daf Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 24 Jun 2014 10:22:42 +0200 Subject: [PATCH 026/185] Create removeNestedRow (for deleting rows of nested columns) --- apps/opencs/model/world/refidadapter.hpp | 2 + apps/opencs/model/world/refidadapterimp.cpp | 52 ++++++++++++--------- apps/opencs/model/world/refidadapterimp.hpp | 3 ++ 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/apps/opencs/model/world/refidadapter.hpp b/apps/opencs/model/world/refidadapter.hpp index 039f44a5ee..928c0eaabc 100644 --- a/apps/opencs/model/world/refidadapter.hpp +++ b/apps/opencs/model/world/refidadapter.hpp @@ -51,6 +51,8 @@ namespace CSMWorld virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const = 0; virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const = 0; + + virtual void removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, unsigned rowToRemove) const = 0; }; } diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 19b8b06b87..6377db040c 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -1,7 +1,6 @@ - #include "refidadapterimp.hpp" -#include +#include CSMWorld::PotionRefIdAdapter::PotionRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *autoCalc) @@ -182,26 +181,21 @@ CSMWorld::ContainerRefIdAdapter::ContainerRefIdAdapter (const NameColumns& colum int CSMWorld::ContainerRefIdAdapter::getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const { - if (column==mContent) - { - return 2; - } else { - throw "Trying to obtain nested columns count, but column does not have nested columns!"; - } + assert(column==mContent); + + return 2; } int CSMWorld::ContainerRefIdAdapter::getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const { + assert(column==mContent); + const Record& record = static_cast&> ( data.getRecord(RefIdData::LocalIndex (index, UniversalId::Type_Container))); - if (column==mContent) - { - return record.get().mInventory.mList.size(); - } else { - throw "Trying to obtain nested rows count, but column does not have nested columns!"; - } + return record.get().mInventory.mList.size(); } + QVariant CSMWorld::ContainerRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, int index) const { @@ -223,6 +217,18 @@ QVariant CSMWorld::ContainerRefIdAdapter::getData (const RefIdColumn *column, co return NameRefIdAdapter::getData (column, data, index); } +void CSMWorld::ContainerRefIdAdapter::removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, unsigned rowToRemove) const +{ + assert(column==mContent); + + std::vector& list = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))).get().mInventory.mList; + + list.erase (list.begin () + rowToRemove); +} + + + void CSMWorld::ContainerRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, const QVariant& value) const { @@ -249,17 +255,19 @@ void CSMWorld::ContainerRefIdAdapter::setData (const RefIdColumn *column, RefIdD NameRefIdAdapter::setData (column, data, index, value); } -void CSMWorld::ContainerRefIdAdapter::setNestedData(const RefIdColumn *column, RefIdData& data, - int index, - const QVariant& value, - int subRowIndex, - int subColIndex) const +void CSMWorld::ContainerRefIdAdapter::setNestedData(const RefIdColumn *column, + RefIdData& data, + int index, + const QVariant& value, + int subRowIndex, + int subColIndex) const { - Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))); if (column==mContent) { + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))); + switch (subColIndex) { case 0: @@ -275,7 +283,7 @@ void CSMWorld::ContainerRefIdAdapter::setNestedData(const RefIdColumn *column, R } } else { - throw "This column does not hold multiple values."; + assert(false); } } diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index a01e593712..eeb859d84b 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -633,6 +633,9 @@ namespace CSMWorld virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const; virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const; + + + virtual void removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, unsigned rowToRemove) const; }; struct CreatureColumns : public ActorColumns From c45061614b22fc9244a59ec34109866759cb8416 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 24 Jun 2014 12:21:40 +0200 Subject: [PATCH 027/185] Added code to delete nestedRows --- apps/opencs/model/world/collectionbase.cpp | 5 +++++ apps/opencs/model/world/collectionbase.hpp | 2 ++ apps/opencs/model/world/idtable.cpp | 8 +++++++- apps/opencs/model/world/refidadapter.hpp | 2 +- apps/opencs/model/world/refidadapterimp.cpp | 4 +--- apps/opencs/model/world/refidadapterimp.hpp | 3 +-- apps/opencs/model/world/refidcollection.cpp | 9 +++++++++ apps/opencs/model/world/refidcollection.hpp | 2 ++ apps/opencs/model/world/refiddata.hpp | 4 ++-- 9 files changed, 30 insertions(+), 9 deletions(-) diff --git a/apps/opencs/model/world/collectionbase.cpp b/apps/opencs/model/world/collectionbase.cpp index 7ea25770a0..70f1fdf9fb 100644 --- a/apps/opencs/model/world/collectionbase.cpp +++ b/apps/opencs/model/world/collectionbase.cpp @@ -47,3 +47,8 @@ int CSMWorld::CollectionBase::getNestedRowsCount(int row, int column) const assert(false); //TODO, make pure abstract return 0; } + +void CSMWorld::CollectionBase::removeNestedRows(int row, int column, int subRow) +{ + assert(false); //todo, make pure abstract +} diff --git a/apps/opencs/model/world/collectionbase.hpp b/apps/opencs/model/world/collectionbase.hpp index b6aad7eff0..01fde1c8c4 100644 --- a/apps/opencs/model/world/collectionbase.hpp +++ b/apps/opencs/model/world/collectionbase.hpp @@ -64,6 +64,8 @@ namespace CSMWorld virtual void removeRows (int index, int count) = 0; + virtual void removeNestedRows(int row, int column, int subRow); + virtual void appendBlankRecord (const std::string& id, UniversalId::Type type = UniversalId::Type_None) = 0; ///< \param type Will be ignored, unless the collection supports multiple record types diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index fd2547ecf6..6e43cfeac9 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -126,7 +126,13 @@ Qt::ItemFlags CSMWorld::IdTable::flags (const QModelIndex & index) const bool CSMWorld::IdTable::removeRows (int row, int count, const QModelIndex& parent) { if (parent.isValid()) - return false; + { + for (int i = 0; i < count; ++i) + { + mIdCollection->removeNestedRows(parent.row(), parent.column(), row+i); + } + return true; + } beginRemoveRows (parent, row, row+count-1); diff --git a/apps/opencs/model/world/refidadapter.hpp b/apps/opencs/model/world/refidadapter.hpp index 928c0eaabc..fddb073a2b 100644 --- a/apps/opencs/model/world/refidadapter.hpp +++ b/apps/opencs/model/world/refidadapter.hpp @@ -52,7 +52,7 @@ namespace CSMWorld virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const = 0; - virtual void removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, unsigned rowToRemove) const = 0; + virtual void removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, int rowToRemove) const = 0; }; } diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 6377db040c..01652ea7ea 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -217,7 +217,7 @@ QVariant CSMWorld::ContainerRefIdAdapter::getData (const RefIdColumn *column, co return NameRefIdAdapter::getData (column, data, index); } -void CSMWorld::ContainerRefIdAdapter::removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, unsigned rowToRemove) const +void CSMWorld::ContainerRefIdAdapter::removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, int rowToRemove) const { assert(column==mContent); @@ -227,8 +227,6 @@ void CSMWorld::ContainerRefIdAdapter::removeNestedRow (const RefIdColumn *column list.erase (list.begin () + rowToRemove); } - - void CSMWorld::ContainerRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, const QVariant& value) const { diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index eeb859d84b..1f3a07dc0f 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -633,9 +633,8 @@ namespace CSMWorld virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const; virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const; - - virtual void removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, unsigned rowToRemove) const; + virtual void removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, int rowToRemove) const; }; struct CreatureColumns : public ActorColumns diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 9fe42af962..47e52289f1 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -463,6 +463,15 @@ void CSMWorld::RefIdCollection::removeRows (int index, int count) mData.erase (index, count); } +void CSMWorld::RefIdCollection::removeNestedRows(int row, int column, int subRow) +{ + RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + + const RefIdAdapter& adaptor = findAdaptor (localIndex.second); + + dynamic_cast(adaptor).removeNestedRow(&mColumns.at (column), mData, localIndex.first, subRow); +} + void CSMWorld::RefIdCollection::appendBlankRecord (const std::string& id, UniversalId::Type type) { mData.appendRecord (type, id, false); diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index fec621ac1d..08fb410a56 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -76,6 +76,8 @@ namespace CSMWorld virtual void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn); virtual void removeRows (int index, int count); + + virtual void removeNestedRows(int row, int column, int subRow); virtual void cloneRecord(const std::string& origin, const std::string& destination, diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index 535e914ee0..bfdd4f9eec 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -52,7 +52,7 @@ namespace CSMWorld virtual void load (int index, ESM::ESMReader& reader, bool base) = 0; virtual void erase (int index, int count) = 0; - + virtual std::string getId (int index) const = 0; virtual void save (int index, ESM::ESMWriter& writer) const = 0; @@ -134,7 +134,7 @@ namespace CSMWorld throw std::runtime_error ("invalid RefIdDataContainer index"); mContainer.erase (mContainer.begin()+index, mContainer.begin()+index+count); - } + } template std::string RefIdDataContainer::getId (int index) const From 7430e1e1bbc2232cb3656bc50303f51819b2394b Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 24 Jun 2014 12:35:26 +0200 Subject: [PATCH 028/185] Added delete nested rows command (undo still needs to be done) --- apps/opencs/model/world/commands.cpp | 43 ++++++++++++++++++++++++++-- apps/opencs/model/world/commands.hpp | 26 +++++++++++++++-- 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/apps/opencs/model/world/commands.cpp b/apps/opencs/model/world/commands.cpp index b60ffeb29c..019a3d3976 100644 --- a/apps/opencs/model/world/commands.cpp +++ b/apps/opencs/model/world/commands.cpp @@ -1,4 +1,3 @@ - #include "commands.hpp" #include @@ -171,4 +170,44 @@ void CSMWorld::CloneCommand::redo() void CSMWorld::CloneCommand::undo() { mModel.removeRow (mModel.getModelIndex (mIdDestination, 0).row()); -} \ No newline at end of file +} + +CSMWorld::DeleteNestedCommand::DeleteNestedCommand (IdTable& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent) + : mId(id), + mModel(model), + mParentColumn(parentColumn), + QUndoCommand(parent), + mNestedRow(nestedRow) +{ + setText (("Delete nested row in " + mId).c_str()); + + const QModelIndex& parentIndex = mModel.getModelIndex(mId, mParentColumn); + + const int columnsCount = mModel.columnCount(parentIndex); + + for (int i = 0; i < columnsCount; ++i) + { + const QModelIndex& childIndex = mModel.index(nestedRow, i, parentIndex); + + QVariant data = childIndex.data(); + if (!data.isValid()) + { + data = childIndex.data(Qt::DisplayRole); + } + + mOld.push_back(data); + } +} + +void CSMWorld::DeleteNestedCommand::redo() +{ + const QModelIndex& parentIndex = mModel.getModelIndex(mId, mParentColumn); + + mModel.removeRows (mNestedRow, 1, parentIndex); +} + + +void CSMWorld::DeleteNestedCommand::undo() +{ + //TODO +} diff --git a/apps/opencs/model/world/commands.hpp b/apps/opencs/model/world/commands.hpp index ec6350658f..192b161ef0 100644 --- a/apps/opencs/model/world/commands.hpp +++ b/apps/opencs/model/world/commands.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include "universalid.hpp" @@ -49,7 +50,7 @@ namespace CSMWorld public: - CloneCommand (IdTable& model, const std::string& idOrigin, + CloneCommand (IdTable& model, const std::string& idOrigin, const std::string& IdDestination, const UniversalId::Type type, QUndoCommand* parent = 0); @@ -135,6 +136,27 @@ namespace CSMWorld virtual void undo(); }; + + class DeleteNestedCommand : public QUndoCommand + { + IdTable& mModel; + + std::string mId; + + std::vector mOld; + + int mParentColumn; + + int mNestedRow; + + public: + + DeleteNestedCommand (IdTable& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent); + + virtual void redo(); + + virtual void undo(); + }; } -#endif \ No newline at end of file +#endif From befdeb18897d5e9da0b0678de74e49b45d2658a0 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 24 Jun 2014 12:42:49 +0200 Subject: [PATCH 029/185] use beginRemovRow when removing nested row. --- apps/opencs/model/world/idtable.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index 6e43cfeac9..90d7e35b55 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -127,10 +127,12 @@ bool CSMWorld::IdTable::removeRows (int row, int count, const QModelIndex& paren { if (parent.isValid()) { + beginRemoveRows(parent, row, row+count-1); for (int i = 0; i < count; ++i) { mIdCollection->removeNestedRows(parent.row(), parent.column(), row+i); } + endRemoveRows(); return true; } From 7b5bf637abd3cf884dcb7fcb49cad8c64b5e876c Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 24 Jun 2014 19:03:29 +0200 Subject: [PATCH 030/185] Changes needed to add new nested row. --- apps/opencs/model/world/collectionbase.cpp | 5 +++++ apps/opencs/model/world/collectionbase.hpp | 2 ++ apps/opencs/model/world/idtable.cpp | 7 +++++++ apps/opencs/model/world/idtable.hpp | 2 ++ apps/opencs/model/world/refidadapter.hpp | 2 ++ apps/opencs/model/world/refidadapterimp.cpp | 19 +++++++++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 2 ++ apps/opencs/model/world/refidcollection.cpp | 9 +++++++++ apps/opencs/model/world/refidcollection.hpp | 2 ++ 9 files changed, 50 insertions(+) diff --git a/apps/opencs/model/world/collectionbase.cpp b/apps/opencs/model/world/collectionbase.cpp index 70f1fdf9fb..a1f4f4a70d 100644 --- a/apps/opencs/model/world/collectionbase.cpp +++ b/apps/opencs/model/world/collectionbase.cpp @@ -52,3 +52,8 @@ void CSMWorld::CollectionBase::removeNestedRows(int row, int column, int subRow) { assert(false); //todo, make pure abstract } + +void CSMWorld::CollectionBase::addNestedRow(int row, int col, int position) +{ + assert(false); +} diff --git a/apps/opencs/model/world/collectionbase.hpp b/apps/opencs/model/world/collectionbase.hpp index 01fde1c8c4..aad40d36bc 100644 --- a/apps/opencs/model/world/collectionbase.hpp +++ b/apps/opencs/model/world/collectionbase.hpp @@ -66,6 +66,8 @@ namespace CSMWorld virtual void removeNestedRows(int row, int column, int subRow); + virtual void addNestedRow(int row, int col, int position); + virtual void appendBlankRecord (const std::string& id, UniversalId::Type type = UniversalId::Type_None) = 0; ///< \param type Will be ignored, unless the collection supports multiple record types diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index 90d7e35b55..a4e4972b4c 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -145,6 +145,13 @@ bool CSMWorld::IdTable::removeRows (int row, int count, const QModelIndex& paren return true; } +void CSMWorld::IdTable::addNestedRow(const QModelIndex& parent, int position) +{ + assert(parent.isValid()); + + mIdCollection->addNestedRow(parent.row(), parent.column(), position); +} + QModelIndex CSMWorld::IdTable::index (int row, int column, const QModelIndex& parent) const { unsigned int encodedId = 0; diff --git a/apps/opencs/model/world/idtable.hpp b/apps/opencs/model/world/idtable.hpp index 29d1f134ad..bf72b80265 100644 --- a/apps/opencs/model/world/idtable.hpp +++ b/apps/opencs/model/world/idtable.hpp @@ -80,6 +80,8 @@ namespace CSMWorld virtual bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex()); + void addNestedRow (const QModelIndex& parent, int position); + virtual QModelIndex index (int row, int column, const QModelIndex& parent = QModelIndex()) const; diff --git a/apps/opencs/model/world/refidadapter.hpp b/apps/opencs/model/world/refidadapter.hpp index fddb073a2b..068347fda5 100644 --- a/apps/opencs/model/world/refidadapter.hpp +++ b/apps/opencs/model/world/refidadapter.hpp @@ -53,6 +53,8 @@ namespace CSMWorld virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const = 0; virtual void removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, int rowToRemove) const = 0; + + virtual void addNestedRow (const RefIdColumn *column, RefIdData& data, int index, int position) const = 0; }; } diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 01652ea7ea..5b92ae941a 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -227,6 +227,25 @@ void CSMWorld::ContainerRefIdAdapter::removeNestedRow (const RefIdColumn *column list.erase (list.begin () + rowToRemove); } +void CSMWorld::ContainerRefIdAdapter::addNestedRow (const RefIdColumn *column, RefIdData& data, int index, int position) const +{ + assert(column==mContent); + + std::vector& list = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))).get().mInventory.mList; + + ESM::ContItem newRow = {0, ""}; + if (position >= (int)list.size()) + { + list.push_back(newRow); + return; + } + + list.insert(list.begin()+position, newRow); + + return; +} + void CSMWorld::ContainerRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, const QVariant& value) const { diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 1f3a07dc0f..6fc56271bb 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -635,6 +635,8 @@ namespace CSMWorld virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const; virtual void removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, int rowToRemove) const; + + virtual void addNestedRow (const RefIdColumn *column, RefIdData& data, int index, int position) const; }; struct CreatureColumns : public ActorColumns diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 47e52289f1..57a42d9fbc 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -625,3 +625,12 @@ int CSMWorld::RefIdCollection::getNestedColumnsCount(int row, int column) const return adaptor.getNestedColumnsCount(&mColumns.at(column), mData); } + +void CSMWorld::RefIdCollection::addNestedRow(int row, int col, int position) +{ + RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + + const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdaptor (localIndex.second)); + + adaptor.addNestedRow(&mColumns.at(col), mData, localIndex.first, position); +} diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index 08fb410a56..7801811ff6 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -79,6 +79,8 @@ namespace CSMWorld virtual void removeNestedRows(int row, int column, int subRow); + virtual void addNestedRow(int row, int col, int position); + virtual void cloneRecord(const std::string& origin, const std::string& destination, const UniversalId::Type type); From d73f4cbd7bf3829ee277caaadcc0bd609f32fa4b Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 24 Jun 2014 19:19:40 +0200 Subject: [PATCH 031/185] added add nested command --- apps/opencs/model/world/commands.cpp | 24 ++++++++++++++++++++++++ apps/opencs/model/world/commands.hpp | 19 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/apps/opencs/model/world/commands.cpp b/apps/opencs/model/world/commands.cpp index 019a3d3976..42a5a7f7ea 100644 --- a/apps/opencs/model/world/commands.cpp +++ b/apps/opencs/model/world/commands.cpp @@ -211,3 +211,27 @@ void CSMWorld::DeleteNestedCommand::undo() { //TODO } + +CSMWorld::AddNestedCommand::AddNestedCommand(IdTable& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent) + : mModel(model), + mId(id), + mNewRow(nestedRow), + mParentColumn(parentColumn), + QUndoCommand(parent) +{ + setText (("Added nested row in " + mId).c_str()); +} + +void CSMWorld::AddNestedCommand::redo() +{ + const QModelIndex& parentIndex = mModel.getModelIndex(mId, mParentColumn); + + mModel.addNestedRow (parentIndex, mNewRow); +} + +void CSMWorld::AddNestedCommand::undo() +{ + const QModelIndex& parentIndex = mModel.getModelIndex(mId, mParentColumn); + + mModel.removeRows(mNewRow, 1, parentIndex); +} diff --git a/apps/opencs/model/world/commands.hpp b/apps/opencs/model/world/commands.hpp index 192b161ef0..9cfc0b293b 100644 --- a/apps/opencs/model/world/commands.hpp +++ b/apps/opencs/model/world/commands.hpp @@ -157,6 +157,25 @@ namespace CSMWorld virtual void undo(); }; + + class AddNestedCommand : public QUndoCommand + { + IdTable& mModel; + + std::string mId; + + int mNewRow; + + int mParentColumn; + + public: + + AddNestedCommand(IdTable& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent); + + virtual void redo(); + + virtual void undo(); + }; } #endif From a0146e2e28cc58c409962c719f3047529327fa32 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 24 Jun 2014 19:34:02 +0200 Subject: [PATCH 032/185] Added undo for delete command --- apps/opencs/model/world/commands.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/world/commands.cpp b/apps/opencs/model/world/commands.cpp index 42a5a7f7ea..0127366978 100644 --- a/apps/opencs/model/world/commands.cpp +++ b/apps/opencs/model/world/commands.cpp @@ -209,7 +209,16 @@ void CSMWorld::DeleteNestedCommand::redo() void CSMWorld::DeleteNestedCommand::undo() { - //TODO + const QModelIndex& parentIndex = mModel.getModelIndex(mId, mParentColumn); + + mModel.addNestedRow(parentIndex, mNestedRow); + + for (int i = 0; i < mModel.columnCount(parentIndex); ++i) + { + const QModelIndex& current = mModel.index(mNestedRow, i, parentIndex); + + mModel.setData(current, mOld[i]); + } } CSMWorld::AddNestedCommand::AddNestedCommand(IdTable& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent) From 8c6a0d9a4f1b2729dd078c51d4c51697945aaf39 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 29 Jun 2014 21:12:31 +0200 Subject: [PATCH 033/185] created new files --- apps/opencs/view/world/dialoguesubview.hpp | 2 +- apps/opencs/view/world/nestedtable.cpp | 20 +++++++++++++ apps/opencs/view/world/nestedtable.hpp | 34 ++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 apps/opencs/view/world/nestedtable.cpp create mode 100644 apps/opencs/view/world/nestedtable.hpp diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index 90a3655924..a6b944d7ab 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -170,7 +170,7 @@ namespace CSVWorld QWidget* mMainWidget; CSMWorld::IdTable* mTable; QUndoStack& mUndoStack; - std::vector mNestedModels; //Plain, raw C pointers, deleted in the dtor + std::vector mNestedModels; //Plain, raw C pointers, deleted in the dtor public: diff --git a/apps/opencs/view/world/nestedtable.cpp b/apps/opencs/view/world/nestedtable.cpp new file mode 100644 index 0000000000..beeafed90e --- /dev/null +++ b/apps/opencs/view/world/nestedtable.cpp @@ -0,0 +1,20 @@ +#include "nestedtable.hpp" + +NestedTable::NestedTable(CSMDoc::Document& document, CSMWorld::NestedTableModel* model, const CSMWorld::UniversalId& id, QWidget* parent) + : QTableView(parent) +{ + QTableView::setModel(model); + setAcceptDrops(true); + + int columns = mModel->columnCount(); + + for(int i = 0 ; i < columns; ++i) + { + CSMWorld::ColumnBase::Display display = static_cast ( + mModel->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); + + CommandDelegate *delegate = CommandDelegateFactoryCollection::get().makeDelegate(display, + document.getUndoStack(), + this); + } +} diff --git a/apps/opencs/view/world/nestedtable.hpp b/apps/opencs/view/world/nestedtable.hpp new file mode 100644 index 0000000000..200a73798e --- /dev/null +++ b/apps/opencs/view/world/nestedtable.hpp @@ -0,0 +1,34 @@ +#ifndef CSV_WORLD_NESTEDTABLE_H +#define CSV_WORLD_TABLE_H + +#include +#include + +class QUndoStack; +class QAction; + +namespace CSMWorld +{ + class NestedTableModel; +} + +namespace CSVWorld +{ + class NestedTable : public QTableView + { + Q_OBJECT + + std::vector mDelegates; + QAction *mAddNewRowAction; + QAction *mRemoveRowAction; + CSMWorld::CommandDispatcher *mDispatcher; + + public: + NestedTable(CSMDoc::Document& document, CSMWorld::NestedTableModel* model, const CSMWorld::UniversalId& id, QWidget* parent = NULL); + + protected: + void dragEnterEvent(QDragEnterEvent *event); + + void dragMoveEvent(QDragMoveEvent *event); + }; +} From 5eac32e3d3d2af1f4378a3bdcbd87d0fbbcc93ea Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 30 Jun 2014 13:09:10 +0200 Subject: [PATCH 034/185] added nestedtable for displaying nested content. --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/view/world/dialoguesubview.cpp | 6 ++---- apps/opencs/view/world/nestedtable.cpp | 25 +++++++++++++++++----- apps/opencs/view/world/nestedtable.hpp | 16 ++++++++++---- 4 files changed, 35 insertions(+), 14 deletions(-) diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index e76e64610e..eec1b653d6 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -61,7 +61,7 @@ opencs_hdrs_noqt (view/doc opencs_units (view/world table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator cellcreator referenceablecreator referencecreator scenesubview scenetoolbar scenetool - scenetoolmode infocreator scriptedit dialoguesubview previewsubview regionmap dragrecordtable + scenetoolmode infocreator scriptedit dialoguesubview previewsubview regionmap dragrecordtable nestedtable ) opencs_units (view/render diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 109f0c3fa9..122b173e6a 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include #include "../../model/world/nestedtablemodel.hpp" @@ -34,6 +33,7 @@ #include "recordstatusdelegate.hpp" #include "util.hpp" #include "tablebottombox.hpp" +#include "nestedtable.hpp" /* ==============================NotEditableSubDelegate========================================== */ @@ -406,9 +406,7 @@ void CSVWorld::EditWidget::remake(int row) { mNestedModels.push_back(new CSMWorld::NestedTableModel (mTable->index(row, i), display, mTable)); - QTableView* table = new QTableView(); - - table->setModel(*(mNestedModels.rbegin())); + NestedTable* table = new NestedTable(mUndoStack, *(mNestedModels.rbegin()), this); tablesLayout->addWidget(table); } else diff --git a/apps/opencs/view/world/nestedtable.cpp b/apps/opencs/view/world/nestedtable.cpp index beeafed90e..bfadfc08cb 100644 --- a/apps/opencs/view/world/nestedtable.cpp +++ b/apps/opencs/view/world/nestedtable.cpp @@ -1,20 +1,35 @@ #include "nestedtable.hpp" +#include "../../model/world/nestedtablemodel.hpp" +#include "../../model/world/universalid.hpp" +#include "util.hpp" -NestedTable::NestedTable(CSMDoc::Document& document, CSMWorld::NestedTableModel* model, const CSMWorld::UniversalId& id, QWidget* parent) +CSVWorld::NestedTable::NestedTable(QUndoStack& undoStack, + CSMWorld::NestedTableModel* model, + QWidget* parent) : QTableView(parent) { - QTableView::setModel(model); + setModel(model); setAcceptDrops(true); - int columns = mModel->columnCount(); + int columns = model->columnCount(QModelIndex()); for(int i = 0 ; i < columns; ++i) { CSMWorld::ColumnBase::Display display = static_cast ( - mModel->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); + model->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); CommandDelegate *delegate = CommandDelegateFactoryCollection::get().makeDelegate(display, - document.getUndoStack(), + undoStack, this); + + setItemDelegateForColumn(i, delegate); } } + +void CSVWorld::NestedTable::dragEnterEvent(QDragEnterEvent *event) +{ +} + +void CSVWorld::NestedTable::dragMoveEvent(QDragMoveEvent *event) +{ +} diff --git a/apps/opencs/view/world/nestedtable.hpp b/apps/opencs/view/world/nestedtable.hpp index 200a73798e..fe62141519 100644 --- a/apps/opencs/view/world/nestedtable.hpp +++ b/apps/opencs/view/world/nestedtable.hpp @@ -1,5 +1,5 @@ #ifndef CSV_WORLD_NESTEDTABLE_H -#define CSV_WORLD_TABLE_H +#define CSV_WORLD_NESTEDTABLE_H #include #include @@ -10,6 +10,12 @@ class QAction; namespace CSMWorld { class NestedTableModel; + class UniversalId; +} + +namespace CSMDoc +{ + class Document; } namespace CSVWorld @@ -18,13 +24,13 @@ namespace CSVWorld { Q_OBJECT - std::vector mDelegates; QAction *mAddNewRowAction; QAction *mRemoveRowAction; - CSMWorld::CommandDispatcher *mDispatcher; public: - NestedTable(CSMDoc::Document& document, CSMWorld::NestedTableModel* model, const CSMWorld::UniversalId& id, QWidget* parent = NULL); + NestedTable(QUndoStack& undoStack, + CSMWorld::NestedTableModel* model, + QWidget* parent = NULL); protected: void dragEnterEvent(QDragEnterEvent *event); @@ -32,3 +38,5 @@ namespace CSVWorld void dragMoveEvent(QDragMoveEvent *event); }; } + +#endif From c96d48fb914923a75d2e979ec1852415200e38ab Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 30 Jun 2014 14:12:57 +0200 Subject: [PATCH 035/185] Nested model supports editing now. --- apps/opencs/model/world/nestedtablemodel.cpp | 11 +++++++++++ apps/opencs/model/world/nestedtablemodel.hpp | 4 ++++ apps/opencs/view/world/nestedtable.cpp | 15 ++++++++++++--- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/world/nestedtablemodel.cpp b/apps/opencs/model/world/nestedtablemodel.cpp index 534ec5d100..20fbd81e10 100644 --- a/apps/opencs/model/world/nestedtablemodel.cpp +++ b/apps/opencs/model/world/nestedtablemodel.cpp @@ -80,3 +80,14 @@ QVariant CSMWorld::NestedTableModel::headerData(int section, { return mMainModel->nestedHeaderData(mParentColumn, section, orientation, role); } + + +bool CSMWorld::NestedTableModel::setData ( const QModelIndex & index, const QVariant & value, int role) +{ + return mMainModel->setData(mapToSource(index), value, role); +} + +Qt::ItemFlags CSMWorld::NestedTableModel::flags(const QModelIndex& index) const +{ + return mMainModel->flags(mMainModel->index(0, mParentColumn)); +} diff --git a/apps/opencs/model/world/nestedtablemodel.hpp b/apps/opencs/model/world/nestedtablemodel.hpp index 404051efc3..0af261f4d6 100644 --- a/apps/opencs/model/world/nestedtablemodel.hpp +++ b/apps/opencs/model/world/nestedtablemodel.hpp @@ -45,6 +45,10 @@ namespace CSMWorld virtual QVariant headerData ( int section, Qt::Orientation orientation, int role ) const; + virtual bool setData ( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole ); + + virtual Qt::ItemFlags flags(const QModelIndex& index) const; + private: void setupHeaderVectors(ColumnBase::Display columnId); }; diff --git a/apps/opencs/view/world/nestedtable.cpp b/apps/opencs/view/world/nestedtable.cpp index bfadfc08cb..b4bb63f3a0 100644 --- a/apps/opencs/view/world/nestedtable.cpp +++ b/apps/opencs/view/world/nestedtable.cpp @@ -3,13 +3,19 @@ #include "../../model/world/universalid.hpp" #include "util.hpp" +#include + CSVWorld::NestedTable::NestedTable(QUndoStack& undoStack, CSMWorld::NestedTableModel* model, QWidget* parent) : QTableView(parent) { - setModel(model); - setAcceptDrops(true); + + setSelectionBehavior (QAbstractItemView::SelectRows); + setSelectionMode (QAbstractItemView::ExtendedSelection); + + horizontalHeader()->setResizeMode (QHeaderView::Interactive); + verticalHeader()->hide(); int columns = model->columnCount(QModelIndex()); @@ -17,13 +23,16 @@ CSVWorld::NestedTable::NestedTable(QUndoStack& undoStack, { CSMWorld::ColumnBase::Display display = static_cast ( model->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); - + CommandDelegate *delegate = CommandDelegateFactoryCollection::get().makeDelegate(display, undoStack, this); setItemDelegateForColumn(i, delegate); } + + setModel(model); + setAcceptDrops(true); } void CSVWorld::NestedTable::dragEnterEvent(QDragEnterEvent *event) From 6dc199743c489ea5ae8d5586131bf39298e71280 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 30 Jun 2014 16:03:38 +0200 Subject: [PATCH 036/185] store undoStack in the nestedtable --- apps/opencs/view/world/nestedtable.cpp | 3 ++- apps/opencs/view/world/nestedtable.hpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/world/nestedtable.cpp b/apps/opencs/view/world/nestedtable.cpp index b4bb63f3a0..ec5d01bbeb 100644 --- a/apps/opencs/view/world/nestedtable.cpp +++ b/apps/opencs/view/world/nestedtable.cpp @@ -8,7 +8,8 @@ CSVWorld::NestedTable::NestedTable(QUndoStack& undoStack, CSMWorld::NestedTableModel* model, QWidget* parent) - : QTableView(parent) + : QTableView(parent), + mUndoStack(undoStack) { setSelectionBehavior (QAbstractItemView::SelectRows); diff --git a/apps/opencs/view/world/nestedtable.hpp b/apps/opencs/view/world/nestedtable.hpp index fe62141519..14a46480e8 100644 --- a/apps/opencs/view/world/nestedtable.hpp +++ b/apps/opencs/view/world/nestedtable.hpp @@ -26,6 +26,7 @@ namespace CSVWorld QAction *mAddNewRowAction; QAction *mRemoveRowAction; + QUndoStack& mUndoStack; public: NestedTable(QUndoStack& undoStack, From 3ebc469f04d5c9ab03b942fdc683b0194a090ebf Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 30 Jun 2014 20:06:18 +0200 Subject: [PATCH 037/185] prepering for merge --- apps/opencs/view/world/nestedtable.cpp | 6 ++++++ apps/opencs/view/world/nestedtable.hpp | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/apps/opencs/view/world/nestedtable.cpp b/apps/opencs/view/world/nestedtable.cpp index ec5d01bbeb..ffb1aaa47f 100644 --- a/apps/opencs/view/world/nestedtable.cpp +++ b/apps/opencs/view/world/nestedtable.cpp @@ -4,6 +4,7 @@ #include "util.hpp" #include +#include CSVWorld::NestedTable::NestedTable(QUndoStack& undoStack, CSMWorld::NestedTableModel* model, @@ -43,3 +44,8 @@ void CSVWorld::NestedTable::dragEnterEvent(QDragEnterEvent *event) void CSVWorld::NestedTable::dragMoveEvent(QDragMoveEvent *event) { } + +void CSVWorld::NestedTable::contextMenuEvent (QContextMenuEvent *event) +{ + QModelIndexList selectedRows = selectionModel()->selectedRows(); +} diff --git a/apps/opencs/view/world/nestedtable.hpp b/apps/opencs/view/world/nestedtable.hpp index 14a46480e8..bdd3db3fa5 100644 --- a/apps/opencs/view/world/nestedtable.hpp +++ b/apps/opencs/view/world/nestedtable.hpp @@ -6,6 +6,7 @@ class QUndoStack; class QAction; +class QContextMenuEvent; namespace CSMWorld { @@ -37,6 +38,9 @@ namespace CSVWorld void dragEnterEvent(QDragEnterEvent *event); void dragMoveEvent(QDragMoveEvent *event); + + private: + void contextMenuEvent (QContextMenuEvent *event); }; } From fcd082c6a53ea2b2d69167a25cc0f8d0992e0830 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 1 Jul 2014 20:52:27 +0200 Subject: [PATCH 038/185] added option to add or remove rows --- apps/opencs/model/world/commands.hpp | 4 +- apps/opencs/model/world/nestedtablemodel.cpp | 15 +++++++ apps/opencs/model/world/nestedtablemodel.hpp | 6 +++ apps/opencs/view/world/nestedtable.cpp | 41 +++++++++++++++++++- apps/opencs/view/world/nestedtable.hpp | 11 ++++++ 5 files changed, 74 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/world/commands.hpp b/apps/opencs/model/world/commands.hpp index 9cfc0b293b..e6f2d9724f 100644 --- a/apps/opencs/model/world/commands.hpp +++ b/apps/opencs/model/world/commands.hpp @@ -151,7 +151,7 @@ namespace CSMWorld public: - DeleteNestedCommand (IdTable& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent); + DeleteNestedCommand (IdTable& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent = 0); virtual void redo(); @@ -170,7 +170,7 @@ namespace CSMWorld public: - AddNestedCommand(IdTable& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent); + AddNestedCommand(IdTable& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent = 0); virtual void redo(); diff --git a/apps/opencs/model/world/nestedtablemodel.cpp b/apps/opencs/model/world/nestedtablemodel.cpp index 20fbd81e10..133520d1dd 100644 --- a/apps/opencs/model/world/nestedtablemodel.cpp +++ b/apps/opencs/model/world/nestedtablemodel.cpp @@ -91,3 +91,18 @@ Qt::ItemFlags CSMWorld::NestedTableModel::flags(const QModelIndex& index) const { return mMainModel->flags(mMainModel->index(0, mParentColumn)); } + +std::string CSMWorld::NestedTableModel::getParentId() const +{ + return mId; +} + +int CSMWorld::NestedTableModel::getParentColumn() const +{ + return mParentColumn; +} + +CSMWorld::IdTable* CSMWorld::NestedTableModel::model() const +{ + return mMainModel; +} diff --git a/apps/opencs/model/world/nestedtablemodel.hpp b/apps/opencs/model/world/nestedtablemodel.hpp index 0af261f4d6..18563b389d 100644 --- a/apps/opencs/model/world/nestedtablemodel.hpp +++ b/apps/opencs/model/world/nestedtablemodel.hpp @@ -31,6 +31,12 @@ namespace CSMWorld IdTable* parentModel); //parent is the parent of columns to work with. Columnid provides information about the column + std::string getParentId() const; + + int getParentColumn() const; + + CSMWorld::IdTable* model() const; + virtual QModelIndex mapFromSource(const QModelIndex& sourceIndex) const; virtual QModelIndex mapToSource(const QModelIndex& proxyIndex) const; diff --git a/apps/opencs/view/world/nestedtable.cpp b/apps/opencs/view/world/nestedtable.cpp index ffb1aaa47f..ebcce15d5b 100644 --- a/apps/opencs/view/world/nestedtable.cpp +++ b/apps/opencs/view/world/nestedtable.cpp @@ -1,16 +1,19 @@ #include "nestedtable.hpp" #include "../../model/world/nestedtablemodel.hpp" #include "../../model/world/universalid.hpp" +#include "../../model/world/commands.hpp" #include "util.hpp" #include #include +#include CSVWorld::NestedTable::NestedTable(QUndoStack& undoStack, CSMWorld::NestedTableModel* model, QWidget* parent) : QTableView(parent), - mUndoStack(undoStack) + mUndoStack(undoStack), + mModel(model) { setSelectionBehavior (QAbstractItemView::SelectRows); @@ -34,7 +37,16 @@ CSVWorld::NestedTable::NestedTable(QUndoStack& undoStack, } setModel(model); + setAcceptDrops(true); + + mAddNewRowAction = new QAction (tr ("Add new row"), this); + connect(mAddNewRowAction, SIGNAL(triggered()), + this, SLOT(addNewRowActionTriggered())); + + mRemoveRowAction = new QAction (tr ("Remove row"), this); + connect(mRemoveRowAction, SIGNAL(triggered()), + this, SLOT(removeRowActionTriggered())); } void CSVWorld::NestedTable::dragEnterEvent(QDragEnterEvent *event) @@ -48,4 +60,31 @@ void CSVWorld::NestedTable::dragMoveEvent(QDragMoveEvent *event) void CSVWorld::NestedTable::contextMenuEvent (QContextMenuEvent *event) { QModelIndexList selectedRows = selectionModel()->selectedRows(); + + QMenu menu(this); + + if (selectionModel()->selectedRows().size() == 1) + menu.addAction(mRemoveRowAction); + + menu.addAction(mAddNewRowAction); + + menu.exec (event->globalPos()); +} + +void CSVWorld::NestedTable::removeRowActionTriggered() +{ + mUndoStack.push(new CSMWorld::DeleteNestedCommand(*(mModel->model()), + mModel->getParentId(), + selectionModel()->selectedRows().begin()->row(), + mModel->getParentColumn())); + +} + +void CSVWorld::NestedTable::addNewRowActionTriggered() +{ + mUndoStack.push(new CSMWorld::AddNestedCommand(*(mModel->model()), + mModel->getParentId(), + selectionModel()->selectedRows().size(), + mModel->getParentColumn())); + } diff --git a/apps/opencs/view/world/nestedtable.hpp b/apps/opencs/view/world/nestedtable.hpp index bdd3db3fa5..eb73cd885a 100644 --- a/apps/opencs/view/world/nestedtable.hpp +++ b/apps/opencs/view/world/nestedtable.hpp @@ -28,6 +28,7 @@ namespace CSVWorld QAction *mAddNewRowAction; QAction *mRemoveRowAction; QUndoStack& mUndoStack; + CSMWorld::NestedTableModel* mModel; public: NestedTable(QUndoStack& undoStack, @@ -41,6 +42,16 @@ namespace CSVWorld private: void contextMenuEvent (QContextMenuEvent *event); + + private slots: + void removeRowActionTriggered(); + + void addNewRowActionTriggered(); + + signals: + void addNewRow(); + + void removeRow(int row); }; } From c50cecdc642eec35cffa39c404b4ffd334d42c5e Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 1 Jul 2014 21:13:27 +0200 Subject: [PATCH 039/185] Small cleanup --- apps/opencs/model/world/idtable.cpp | 8 +++++--- apps/opencs/view/world/nestedtable.cpp | 2 -- apps/opencs/view/world/nestedtable.hpp | 5 ----- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index a4e4972b4c..29d2a543e7 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -127,12 +127,10 @@ bool CSMWorld::IdTable::removeRows (int row, int count, const QModelIndex& paren { if (parent.isValid()) { - beginRemoveRows(parent, row, row+count-1); for (int i = 0; i < count; ++i) { mIdCollection->removeNestedRows(parent.row(), parent.column(), row+i); } - endRemoveRows(); return true; } @@ -149,7 +147,11 @@ void CSMWorld::IdTable::addNestedRow(const QModelIndex& parent, int position) { assert(parent.isValid()); - mIdCollection->addNestedRow(parent.row(), parent.column(), position); + int row = parent.row(); + mIdCollection->addNestedRow(row, parent.column(), position); + + emit dataChanged (CSMWorld::IdTable::index (row, 0), + CSMWorld::IdTable::index (row, mIdCollection->getColumns()-1)); } QModelIndex CSMWorld::IdTable::index (int row, int column, const QModelIndex& parent) const diff --git a/apps/opencs/view/world/nestedtable.cpp b/apps/opencs/view/world/nestedtable.cpp index ebcce15d5b..2eef2e9158 100644 --- a/apps/opencs/view/world/nestedtable.cpp +++ b/apps/opencs/view/world/nestedtable.cpp @@ -77,7 +77,6 @@ void CSVWorld::NestedTable::removeRowActionTriggered() mModel->getParentId(), selectionModel()->selectedRows().begin()->row(), mModel->getParentColumn())); - } void CSVWorld::NestedTable::addNewRowActionTriggered() @@ -86,5 +85,4 @@ void CSVWorld::NestedTable::addNewRowActionTriggered() mModel->getParentId(), selectionModel()->selectedRows().size(), mModel->getParentColumn())); - } diff --git a/apps/opencs/view/world/nestedtable.hpp b/apps/opencs/view/world/nestedtable.hpp index eb73cd885a..35fa224949 100644 --- a/apps/opencs/view/world/nestedtable.hpp +++ b/apps/opencs/view/world/nestedtable.hpp @@ -47,11 +47,6 @@ namespace CSVWorld void removeRowActionTriggered(); void addNewRowActionTriggered(); - - signals: - void addNewRow(); - - void removeRow(int row); }; } From 77afb754e5d972489e028bd3146bd46ec561ceab Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 2 Jul 2014 13:13:03 +0200 Subject: [PATCH 040/185] adding new rows works --- apps/opencs/model/world/idtable.cpp | 4 +++ apps/opencs/model/world/nestedtablemodel.cpp | 36 ++++++++++++++++++++ apps/opencs/model/world/nestedtablemodel.hpp | 9 +++++ apps/opencs/view/world/nestedtable.cpp | 22 ++++++------ 4 files changed, 61 insertions(+), 10 deletions(-) diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index 29d2a543e7..f71c367f0f 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -148,10 +148,14 @@ void CSMWorld::IdTable::addNestedRow(const QModelIndex& parent, int position) assert(parent.isValid()); int row = parent.row(); + + beginInsertRows(parent, position, position); mIdCollection->addNestedRow(row, parent.column(), position); emit dataChanged (CSMWorld::IdTable::index (row, 0), CSMWorld::IdTable::index (row, mIdCollection->getColumns()-1)); + + endInsertRows(); } QModelIndex CSMWorld::IdTable::index (int row, int column, const QModelIndex& parent) const diff --git a/apps/opencs/model/world/nestedtablemodel.cpp b/apps/opencs/model/world/nestedtablemodel.cpp index 133520d1dd..17bf7b30c2 100644 --- a/apps/opencs/model/world/nestedtablemodel.cpp +++ b/apps/opencs/model/world/nestedtablemodel.cpp @@ -2,6 +2,7 @@ #include #include "./idtable.hpp" +#include CSMWorld::NestedTableModel::NestedTableModel(const QModelIndex& parent, ColumnBase::Display columnId, @@ -14,6 +15,13 @@ CSMWorld::NestedTableModel::NestedTableModel(const QModelIndex& parent, mId = std::string(parentModel->index(parentRow, 0).data().toString().toUtf8()); QAbstractProxyModel::setSourceModel(parentModel); + + connect(mMainModel, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)), + this, SLOT(forwardRowsAboutToInserted(const QModelIndex &, int, int))); + + connect(mMainModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)), + this, SLOT(forwardRowsInserted(const QModelIndex &, int, int))); + } QModelIndex CSMWorld::NestedTableModel::mapFromSource(const QModelIndex& sourceIndex) const @@ -106,3 +114,31 @@ CSMWorld::IdTable* CSMWorld::NestedTableModel::model() const { return mMainModel; } + +void CSMWorld::NestedTableModel::forwardRowsAboutToInserted(const QModelIndex& parent, int first, int last) +{ + if (indexIsParent(parent)) + { + qDebug()<<"Adding new rows "<< first<<":"<data(mMainModel->index(index.row(), 0)).toString().toUtf8().constData() == mId); +} diff --git a/apps/opencs/model/world/nestedtablemodel.hpp b/apps/opencs/model/world/nestedtablemodel.hpp index 18563b389d..2263524cf4 100644 --- a/apps/opencs/model/world/nestedtablemodel.hpp +++ b/apps/opencs/model/world/nestedtablemodel.hpp @@ -21,6 +21,8 @@ namespace CSMWorld class NestedTableModel : public QAbstractProxyModel { + Q_OBJECT + const int mParentColumn; IdTable* mMainModel; std::string mId; @@ -57,6 +59,13 @@ namespace CSMWorld private: void setupHeaderVectors(ColumnBase::Display columnId); + + bool indexIsParent(const QModelIndex& index); + + private slots: + void forwardRowsAboutToInserted(const QModelIndex & parent, int first, int last); + + void forwardRowsInserted(const QModelIndex & parent, int first, int last); }; } diff --git a/apps/opencs/view/world/nestedtable.cpp b/apps/opencs/view/world/nestedtable.cpp index 2eef2e9158..a185fc7ce0 100644 --- a/apps/opencs/view/world/nestedtable.cpp +++ b/apps/opencs/view/world/nestedtable.cpp @@ -28,23 +28,25 @@ CSVWorld::NestedTable::NestedTable(QUndoStack& undoStack, { CSMWorld::ColumnBase::Display display = static_cast ( model->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); - + CommandDelegate *delegate = CommandDelegateFactoryCollection::get().makeDelegate(display, undoStack, this); - + setItemDelegateForColumn(i, delegate); } setModel(model); setAcceptDrops(true); - + mAddNewRowAction = new QAction (tr ("Add new row"), this); - connect(mAddNewRowAction, SIGNAL(triggered()), + + connect(mAddNewRowAction, SIGNAL(triggered()), this, SLOT(addNewRowActionTriggered())); - + mRemoveRowAction = new QAction (tr ("Remove row"), this); + connect(mRemoveRowAction, SIGNAL(triggered()), this, SLOT(removeRowActionTriggered())); } @@ -60,21 +62,21 @@ void CSVWorld::NestedTable::dragMoveEvent(QDragMoveEvent *event) void CSVWorld::NestedTable::contextMenuEvent (QContextMenuEvent *event) { QModelIndexList selectedRows = selectionModel()->selectedRows(); - + QMenu menu(this); if (selectionModel()->selectedRows().size() == 1) menu.addAction(mRemoveRowAction); menu.addAction(mAddNewRowAction); - + menu.exec (event->globalPos()); } void CSVWorld::NestedTable::removeRowActionTriggered() { - mUndoStack.push(new CSMWorld::DeleteNestedCommand(*(mModel->model()), - mModel->getParentId(), + mUndoStack.push(new CSMWorld::DeleteNestedCommand(*(mModel->model()), + mModel->getParentId(), selectionModel()->selectedRows().begin()->row(), mModel->getParentColumn())); } @@ -82,7 +84,7 @@ void CSVWorld::NestedTable::removeRowActionTriggered() void CSVWorld::NestedTable::addNewRowActionTriggered() { mUndoStack.push(new CSMWorld::AddNestedCommand(*(mModel->model()), - mModel->getParentId(), + mModel->getParentId(), selectionModel()->selectedRows().size(), mModel->getParentColumn())); } From bb675ff41d1a7a5f38d8a18d6f6d5fd188c9c074 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 2 Jul 2014 13:29:25 +0200 Subject: [PATCH 041/185] Removing rows and undo works --- apps/opencs/model/world/idtable.cpp | 13 +++++++----- apps/opencs/model/world/nestedtablemodel.cpp | 21 ++++++++++++++++++++ apps/opencs/model/world/nestedtablemodel.hpp | 4 ++++ 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index f71c367f0f..a74bd629b4 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -125,19 +125,22 @@ Qt::ItemFlags CSMWorld::IdTable::flags (const QModelIndex & index) const bool CSMWorld::IdTable::removeRows (int row, int count, const QModelIndex& parent) { + beginRemoveRows (parent, row, row+count-1); + if (parent.isValid()) { for (int i = 0; i < count; ++i) { mIdCollection->removeNestedRows(parent.row(), parent.column(), row+i); } - return true; + } else + { + + beginRemoveRows (parent, row, row+count-1); + + mIdCollection->removeRows (row, count); } - beginRemoveRows (parent, row, row+count-1); - - mIdCollection->removeRows (row, count); - endRemoveRows(); return true; diff --git a/apps/opencs/model/world/nestedtablemodel.cpp b/apps/opencs/model/world/nestedtablemodel.cpp index 17bf7b30c2..6d66185901 100644 --- a/apps/opencs/model/world/nestedtablemodel.cpp +++ b/apps/opencs/model/world/nestedtablemodel.cpp @@ -22,6 +22,11 @@ CSMWorld::NestedTableModel::NestedTableModel(const QModelIndex& parent, connect(mMainModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(forwardRowsInserted(const QModelIndex &, int, int))); + connect(mMainModel, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)), + this, SLOT(forwardRowsAboutToRemoved(const QModelIndex &, int, int))); + + connect(mMainModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), + this, SLOT(forwardRowsRemoved(const QModelIndex &, int, int))); } QModelIndex CSMWorld::NestedTableModel::mapFromSource(const QModelIndex& sourceIndex) const @@ -142,3 +147,19 @@ bool CSMWorld::NestedTableModel::indexIsParent(const QModelIndex& index) index.column() == mParentColumn && mMainModel->data(mMainModel->index(index.row(), 0)).toString().toUtf8().constData() == mId); } + +void CSMWorld::NestedTableModel::forwardRowsAboutToRemoved(const QModelIndex& parent, int first, int last) +{ + if (indexIsParent(parent)) + { + beginRemoveRows(QModelIndex(), first, last); + } +} + +void CSMWorld::NestedTableModel::forwardRowsRemoved(const QModelIndex& parent, int first, int last) +{ + if (indexIsParent(parent)) + { + endRemoveRows(); + } +} diff --git a/apps/opencs/model/world/nestedtablemodel.hpp b/apps/opencs/model/world/nestedtablemodel.hpp index 2263524cf4..dfb231124c 100644 --- a/apps/opencs/model/world/nestedtablemodel.hpp +++ b/apps/opencs/model/world/nestedtablemodel.hpp @@ -66,6 +66,10 @@ namespace CSMWorld void forwardRowsAboutToInserted(const QModelIndex & parent, int first, int last); void forwardRowsInserted(const QModelIndex & parent, int first, int last); + + void forwardRowsAboutToRemoved(const QModelIndex & parent, int first, int last); + + void forwardRowsRemoved(const QModelIndex & parent, int first, int last); }; } From 0bfc408ea2653c0d455f6239aa2cce21ea8b964c Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 2 Jul 2014 14:10:11 +0200 Subject: [PATCH 042/185] removed debug code --- apps/opencs/model/world/nestedtablemodel.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/apps/opencs/model/world/nestedtablemodel.cpp b/apps/opencs/model/world/nestedtablemodel.cpp index 6d66185901..cb7943f5e6 100644 --- a/apps/opencs/model/world/nestedtablemodel.cpp +++ b/apps/opencs/model/world/nestedtablemodel.cpp @@ -2,7 +2,6 @@ #include #include "./idtable.hpp" -#include CSMWorld::NestedTableModel::NestedTableModel(const QModelIndex& parent, ColumnBase::Display columnId, @@ -140,9 +139,6 @@ void CSMWorld::NestedTableModel::forwardRowsInserted(const QModelIndex& parent, bool CSMWorld::NestedTableModel::indexIsParent(const QModelIndex& index) { - qDebug()<<"Testing for parenty"; - qDebug()<data(mMainModel->index(index.row(), 0)).toString().toUtf8().constData() == mId); From 851d2f061b45ce8f758cdb22242d34af8567f675 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 3 Jul 2014 11:14:51 +0200 Subject: [PATCH 043/185] Removed qdebug calls (forgot about those). --- apps/opencs/model/world/nestedtablemodel.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/opencs/model/world/nestedtablemodel.cpp b/apps/opencs/model/world/nestedtablemodel.cpp index cb7943f5e6..d0648e5e92 100644 --- a/apps/opencs/model/world/nestedtablemodel.cpp +++ b/apps/opencs/model/world/nestedtablemodel.cpp @@ -123,7 +123,6 @@ void CSMWorld::NestedTableModel::forwardRowsAboutToInserted(const QModelIndex& p { if (indexIsParent(parent)) { - qDebug()<<"Adding new rows "<< first<<":"< Date: Mon, 7 Jul 2014 10:23:40 +0200 Subject: [PATCH 044/185] fixed segfault --- apps/opencs/view/world/dialoguesubview.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 122b173e6a..673d3573f4 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -353,6 +353,7 @@ void CSVWorld::EditWidget::remake(int row) { delete mNestedModels[i]; } + mNestedModels.clear(); if (mMainWidget) { From 3262f8d774ae3503944345c28c4caf0cea1553b4 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 7 Jul 2014 10:27:48 +0200 Subject: [PATCH 045/185] make dtor virtual --- apps/opencs/view/world/dialoguesubview.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index a6b944d7ab..c1bc962113 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -177,7 +177,7 @@ namespace CSVWorld EditWidget (QWidget *parent, int row, CSMWorld::IdTable* table, QUndoStack& undoStack, bool createAndDelete = false); - ~EditWidget(); + virtual ~EditWidget(); void remake(int row); From d221486a140cd81233b8f1f5b7897b59bd7bcc90 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 7 Jul 2014 12:07:29 +0200 Subject: [PATCH 046/185] Fixed problem in the idtable. --- apps/opencs/model/world/idtable.cpp | 40 +++++++++++++++++--------- apps/opencs/view/world/nestedtable.cpp | 3 +- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index a74bd629b4..c2eb32fa54 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -1,4 +1,5 @@ #include "idtable.hpp" +#include #include @@ -93,23 +94,34 @@ QVariant CSMWorld::IdTable::nestedHeaderData(int section, int subSection, Qt::Or bool CSMWorld::IdTable::setData (const QModelIndex &index, const QVariant &value, int role) { - if (mIdCollection->getColumn (index.column()).isEditable() && role==Qt::EditRole) + if (index.internalId() != 0) { - if (index.internalId() == 0) - { - mIdCollection->setData (index.row(), index.column(), value); - - emit dataChanged (CSMWorld::IdTable::index (index.row(), 0), - CSMWorld::IdTable::index (index.row(), mIdCollection->getColumns()-1)); - } else + if (mIdCollection->getColumn(parent(index).column()).isEditable() && role==Qt::EditRole) { const std::pair& parentAdress(unfoldIndexAdress(index.internalId())); mIdCollection->setNestedData(parentAdress.first, parentAdress.second, value, index.row(), index.column()); - } - return true; - } + + emit dataChanged (CSMWorld::IdTable::index (parentAdress.first, 0), + CSMWorld::IdTable::index (parentAdress.second, mIdCollection->getColumns()-1)); + return true; + } else + { + return false; + } + } + + if (mIdCollection->getColumn (index.column()).isEditable() && role==Qt::EditRole) + { + mIdCollection->setData (index.row(), index.column(), value); + + emit dataChanged (CSMWorld::IdTable::index (index.row(), 0), + CSMWorld::IdTable::index (index.row(), mIdCollection->getColumns()-1)); + + return true; + } + return false; } @@ -131,9 +143,9 @@ bool CSMWorld::IdTable::removeRows (int row, int count, const QModelIndex& paren { for (int i = 0; i < count; ++i) { - mIdCollection->removeNestedRows(parent.row(), parent.column(), row+i); + mIdCollection->removeNestedRows(parent.row(), parent.column(), row+i); } - } else + } else { beginRemoveRows (parent, row, row+count-1); @@ -157,7 +169,7 @@ void CSMWorld::IdTable::addNestedRow(const QModelIndex& parent, int position) emit dataChanged (CSMWorld::IdTable::index (row, 0), CSMWorld::IdTable::index (row, mIdCollection->getColumns()-1)); - + endInsertRows(); } diff --git a/apps/opencs/view/world/nestedtable.cpp b/apps/opencs/view/world/nestedtable.cpp index a185fc7ce0..21bef504bc 100644 --- a/apps/opencs/view/world/nestedtable.cpp +++ b/apps/opencs/view/world/nestedtable.cpp @@ -7,6 +7,7 @@ #include #include #include +#include CSVWorld::NestedTable::NestedTable(QUndoStack& undoStack, CSMWorld::NestedTableModel* model, @@ -32,7 +33,7 @@ CSVWorld::NestedTable::NestedTable(QUndoStack& undoStack, CommandDelegate *delegate = CommandDelegateFactoryCollection::get().makeDelegate(display, undoStack, this); - + setItemDelegateForColumn(i, delegate); } From 72392ad68c025ea634fcfc2ec280e9611969e0b4 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 7 Jul 2014 12:22:04 +0200 Subject: [PATCH 047/185] emit data changed signal when adding and removing the nested row --- apps/opencs/model/world/idtable.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index c2eb32fa54..0b5f9c5a3f 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -155,6 +155,9 @@ bool CSMWorld::IdTable::removeRows (int row, int count, const QModelIndex& paren endRemoveRows(); + emit dataChanged (CSMWorld::IdTable::index (parent.row(), 0), + CSMWorld::IdTable::index (parent.row(), mIdCollection->getColumns()-1)); + return true; } @@ -167,10 +170,10 @@ void CSMWorld::IdTable::addNestedRow(const QModelIndex& parent, int position) beginInsertRows(parent, position, position); mIdCollection->addNestedRow(row, parent.column(), position); + endInsertRows(); + emit dataChanged (CSMWorld::IdTable::index (row, 0), CSMWorld::IdTable::index (row, mIdCollection->getColumns()-1)); - - endInsertRows(); } QModelIndex CSMWorld::IdTable::index (int row, int column, const QModelIndex& parent) const From 0252d021eba082f6f30736248520b17ca20b7ffc Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 13 Jul 2014 12:37:05 +0200 Subject: [PATCH 048/185] removed pointless member field --- apps/opencs/model/world/columnbase.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 3f9e7e1a38..bf03ab5634 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -93,6 +93,7 @@ namespace CSMWorld //Those are top level columns that nest other columns Display_NestedItemList, + Display_EnchantmentType, Display_BodyPartType, Display_MeshType, @@ -138,8 +139,6 @@ namespace CSMWorld template struct Column : public ColumnBase { - int mFlags; - Column (int columnId, Display displayType, int flags = Flag_Table | Flag_Dialogue, bool canNest = false) : ColumnBase (columnId, displayType, flags, canNest) {} From f0c6ef185eb8f2735e17470d836c5475c9388544 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 16 Jul 2014 13:13:22 +0200 Subject: [PATCH 049/185] Nest columns directly, created NestedColumn class and NestColumn. --- apps/opencs/model/world/columnbase.cpp | 42 ++++++++++++------- apps/opencs/model/world/columnbase.hpp | 45 +++++++++++++++------ apps/opencs/model/world/idtable.cpp | 8 ++-- apps/opencs/model/world/refidadapterimp.cpp | 7 ++-- apps/opencs/model/world/refidcollection.cpp | 8 ++-- apps/opencs/model/world/refidcollection.hpp | 2 +- 6 files changed, 71 insertions(+), 41 deletions(-) diff --git a/apps/opencs/model/world/columnbase.cpp b/apps/opencs/model/world/columnbase.cpp index 59ee391263..60e201ba45 100644 --- a/apps/opencs/model/world/columnbase.cpp +++ b/apps/opencs/model/world/columnbase.cpp @@ -2,8 +2,6 @@ #include "columns.hpp" -#include - CSMWorld::ColumnBase::ColumnBase (int columnId, Display displayType, int flags, bool canNest) : mColumnId (columnId), mDisplayType (displayType), mFlags (flags), mCanNest(canNest) {} @@ -25,28 +23,42 @@ int CSMWorld::ColumnBase::getId() const return mColumnId; } -bool CSMWorld::ColumnBase::canHaveNestedColumns() const +bool CSMWorld::NestColumn::canHaveNestedColumns() const { return mCanNest; } -std::string CSMWorld::ColumnBase::getNestedColumnTitle(int columnNumber) const +void CSMWorld::NestColumn::addNestedColumn(int columnId, Display displayType) { - assert (mCanNest); - - return Columns::getName(static_cast(mNestedColumnId[columnNumber])); + if (!mCanNest) + throw std::logic_error("Tried to nest inside of the non-nest column"); + + mNestedColumns.push_back(CSMWorld::NestedColumn(columnId, displayType, mFlags, this)); } -void CSMWorld::ColumnBase::addNestedColumnDisplay(CSMWorld::ColumnBase::Display displayDefinition) +const CSMWorld::ColumnBase& CSMWorld::NestColumn::nestedColumn(int subColumn) const { - assert (mCanNest); - - mNestedDisplayType.push_back(displayDefinition); + if (!mCanNest) + throw std::logic_error("Tried to access nested column of the non-nest column"); + + return mNestedColumns.at(subColumn); } -void CSMWorld::ColumnBase::addNestedColumnId(int columnId) +int CSMWorld::NestColumn::nestedColumnCount() const { - assert (mCanNest); - - mNestedColumnId.push_back(columnId); + if (!mCanNest) + throw std::logic_error("Tried to access number of the subcolumns in the non-nest column"); + + return mNestedColumns.size(); +} + +CSMWorld::NestColumn::NestColumn(int columnId, Display displayType, int flags, bool canNest) + : CSMWorld::ColumnBase(columnId, displayType, flags, canNest) {} + +CSMWorld::NestedColumn::NestedColumn(int columnId, Display displayType, int flag, const CSMWorld::NestColumn* parent) + : mParent(parent), CSMWorld::ColumnBase(columnId, displayType, flag) {} + +bool CSMWorld::NestedColumn::isEditable() const +{ + return mParent->isEditable(); } diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index bf03ab5634..096491f1ec 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -110,9 +111,7 @@ namespace CSMWorld int mColumnId; int mFlags; Display mDisplayType; - std::vector mNestedDisplayType; //used only for the columns that actually nest other columns - std::vector mNestedColumnId; //used only for the columns that actually nest other columns - const bool mCanNest; + bool mCanNest; ColumnBase (int columnId, Display displayType, int flag, bool canNest = false); @@ -125,22 +124,42 @@ namespace CSMWorld virtual std::string getTitle() const; - std::string getNestedColumnTitle(int columnNumber) const; - - void addNestedColumnDisplay(Display displayDefinition); - - void addNestedColumnId(int columnId); - virtual int getId() const; - - bool canHaveNestedColumns() const; }; + class NestedColumn; + + class NestColumn : public ColumnBase + { + std::vector mNestedColumns; + + public: + NestColumn(int columnId, Display displayType, int flags, bool canNest); + + void addNestedColumn(int columnId, Display displayType); + + bool canHaveNestedColumns() const; + + const ColumnBase& nestedColumn(int subColumn) const; + + int nestedColumnCount() const; + }; + + class NestedColumn : public ColumnBase + { + const ColumnBase* mParent; + + public: + NestedColumn(int columnId, Display displayType, int flag, const NestColumn* parent); + + virtual bool isEditable() const; + }; + template - struct Column : public ColumnBase + struct Column : public NestColumn { Column (int columnId, Display displayType, int flags = Flag_Table | Flag_Dialogue, bool canNest = false) - : ColumnBase (columnId, displayType, flags, canNest) {} + : NestColumn (columnId, displayType, canNest, flags) {} virtual QVariant get (const Record& record) const = 0; diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index 00cfbd1459..a3435180c4 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -75,19 +75,19 @@ QVariant CSMWorld::IdTable::headerData (int section, QVariant CSMWorld::IdTable::nestedHeaderData(int section, int subSection, Qt::Orientation orientation, int role) const { - assert(mIdCollection->getColumn(section).canHaveNestedColumns()); + const NestColumn& parentColumn = dynamic_cast(mIdCollection->getColumn(section)); if (orientation==Qt::Vertical) return QVariant(); if (role==Qt::DisplayRole) - return tr (mIdCollection->getColumn(section).getNestedColumnTitle(subSection).c_str()); + return tr(parentColumn.nestedColumn(subSection).getTitle().c_str()); if (role==ColumnBase::Role_Flags) return mIdCollection->getColumn (section).mFlags; if (role==ColumnBase::Role_Display) - return mIdCollection->getColumn (section).mNestedDisplayType.at(subSection); + return parentColumn.nestedColumn(subSection).mDisplayType; return QVariant(); } @@ -354,6 +354,6 @@ bool CSMWorld::IdTable::hasChildren(const QModelIndex& index) const { return (index.isValid() && index.internalId() == 0 && - mIdCollection->getColumn (index.column()).canHaveNestedColumns() && + mIdCollection->getColumn(index.column()).mCanNest && index.data().isValid()); } diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 7033140ca7..8d6ab838dc 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -1,6 +1,7 @@ #include "refidadapterimp.hpp" #include +#include CSMWorld::PotionRefIdAdapter::PotionRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *autoCalc) @@ -296,7 +297,7 @@ void CSMWorld::ContainerRefIdAdapter::setNestedData(const RefIdColumn *column, break; default: - throw "Trying to access non-existing column in the nested table!"; + throw std::logic_error("Trying to access non-existing column in the nested table!"); } } else { @@ -326,11 +327,11 @@ QVariant CSMWorld::ContainerRefIdAdapter::getNestedData (const CSMWorld::RefIdCo return content.mCount; default: - throw "Trying to access non-existing column in the nested table!"; + throw std::logic_error("Trying to access non-existing column in the nested table!"); } } else { - throw "This column does not hold multiple values."; + throw std::logic_error("This column does not hold multiple values."); } } diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 7aa1d7753a..62daef903d 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -13,7 +13,7 @@ CSMWorld::RefIdColumn::RefIdColumn (int columnId, Display displayType, int flag, bool editable, bool userEditable, bool canNest) - : ColumnBase (columnId, displayType, flag, canNest), mEditable (editable), mUserEditable (userEditable) + : NestColumn (columnId, displayType, flag, canNest), mEditable (editable), mUserEditable (userEditable) {} bool CSMWorld::RefIdColumn::isEditable() const @@ -168,10 +168,8 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back(RefIdColumn (Columns::ColumnId_ContainerContent, ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue, true, true, true)); const RefIdColumn *content = &mColumns.back(); - (&mColumns.back())->addNestedColumnDisplay(CSMWorld::ColumnBase::Display_String); - (&mColumns.back())->addNestedColumnDisplay(CSMWorld::ColumnBase::Display_Integer); - (&mColumns.back())->addNestedColumnId(Columns::ColumnId_InventoryItemId); - (&mColumns.back())->addNestedColumnId(Columns::ColumnId_ItemCount); + (&mColumns.back())->addNestedColumn(Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String); + (&mColumns.back())->addNestedColumn(Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer); CreatureColumns creatureColumns (actorsColumns); diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index 7801811ff6..d1bb197e8c 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -18,7 +18,7 @@ namespace CSMWorld { class RefIdAdapter; - class RefIdColumn : public ColumnBase + class RefIdColumn : public NestColumn { bool mEditable; bool mUserEditable; From ca73ce3fe23e94fbc9d1fdceb957c9d9c756f94e Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 17 Jul 2014 12:41:43 +0200 Subject: [PATCH 050/185] trying to fix indending --- apps/opencs/model/world/refidcollection.hpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index d1bb197e8c..02b77400b6 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -18,7 +18,7 @@ namespace CSMWorld { class RefIdAdapter; - class RefIdColumn : public NestColumn + class RefIdColumn : public NestColumn { bool mEditable; bool mUserEditable; @@ -76,11 +76,11 @@ namespace CSMWorld virtual void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn); virtual void removeRows (int index, int count); - + virtual void removeNestedRows(int row, int column, int subRow); virtual void addNestedRow(int row, int col, int position); - + virtual void cloneRecord(const std::string& origin, const std::string& destination, const UniversalId::Type type); @@ -124,9 +124,8 @@ namespace CSMWorld void save (int index, ESM::ESMWriter& writer) const; - const RefIdData& getDataSet() const; //I can't figure out a better name for this one :( + const RefIdData& getDataSet() const; //I can't figure out a better name for this one :( }; } #endif - From 6e07568b43fea79c1b3acffb07f4b9aa30d1c35c Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 17 Jul 2014 12:56:51 +0200 Subject: [PATCH 051/185] Corrected syntax. --- apps/opencs/model/world/refidcollection.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 62daef903d..1a164d12f3 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -168,8 +168,8 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back(RefIdColumn (Columns::ColumnId_ContainerContent, ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue, true, true, true)); const RefIdColumn *content = &mColumns.back(); - (&mColumns.back())->addNestedColumn(Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String); - (&mColumns.back())->addNestedColumn(Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer); + mColumns.back().addNestedColumn(Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String); + mColumns.back().addNestedColumn(Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer); CreatureColumns creatureColumns (actorsColumns); From 5671a4b8e2b55f48b11fdc4c2a221bb0883a1cdb Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 17 Jul 2014 12:58:14 +0200 Subject: [PATCH 052/185] corrected include to follow our standards. --- apps/opencs/model/world/nestedtablemodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/world/nestedtablemodel.cpp b/apps/opencs/model/world/nestedtablemodel.cpp index d0648e5e92..f0b5102440 100644 --- a/apps/opencs/model/world/nestedtablemodel.cpp +++ b/apps/opencs/model/world/nestedtablemodel.cpp @@ -1,7 +1,7 @@ #include "nestedtablemodel.hpp" #include -#include "./idtable.hpp" +#include "idtable.hpp" CSMWorld::NestedTableModel::NestedTableModel(const QModelIndex& parent, ColumnBase::Display columnId, From 16292bf23ee73dd1f32332d4af0af1d2ae6d9a03 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 17 Jul 2014 13:03:53 +0200 Subject: [PATCH 053/185] removed useless todo statments. --- apps/opencs/model/world/collection.hpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/apps/opencs/model/world/collection.hpp b/apps/opencs/model/world/collection.hpp index 3b39dc6f9b..904587eaff 100644 --- a/apps/opencs/model/world/collection.hpp +++ b/apps/opencs/model/world/collection.hpp @@ -73,10 +73,10 @@ namespace CSMWorld ///< Add a new record (modified) virtual int getSize() const; - - virtual int getNestedColumnsCount(int column) const; - virtual int getNestedRowsCount(int row, int column) const; + virtual int getNestedColumnsCount(int column) const; + + virtual int getNestedRowsCount(int row, int column) const; virtual std::string getId (int index) const; @@ -253,19 +253,17 @@ namespace CSMWorld { return mRecords.size(); } - + template int Collection::getNestedRowsCount(int row, int column) const { - //TODO - return 0; + return 0; } template int Collection::getNestedColumnsCount(int column) const { - //TODO - return 0; + return 0; } template @@ -300,7 +298,7 @@ namespace CSMWorld template QVariant Collection::getNestedData(int row, int column, int subRow, int subColumn) const { - return 10; //TODO + return QVariant(); } template From 1ff8abb240e4f235e8d66af9c169cc92735e0c21 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 18 Jul 2014 18:26:22 +0200 Subject: [PATCH 054/185] store whole container representing the nested table inside of the command Static nature of C++ forced me to use templates. Bit frustraiting. --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/world/collection.hpp | 18 ++++++++++ apps/opencs/model/world/collectionbase.hpp | 11 ++++-- apps/opencs/model/world/commands.cpp | 36 ++++--------------- apps/opencs/model/world/commands.hpp | 6 +++- apps/opencs/model/world/idtable.cpp | 21 +++++++++++ apps/opencs/model/world/idtable.hpp | 5 +++ .../opencs/model/world/nestedtablewrapper.cpp | 7 ++++ .../opencs/model/world/nestedtablewrapper.hpp | 33 +++++++++++++++++ apps/opencs/model/world/refidadapter.hpp | 9 +++-- apps/opencs/model/world/refidadapterimp.cpp | 23 ++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 6 ++++ apps/opencs/model/world/refidcollection.cpp | 21 ++++++++++- apps/opencs/model/world/refidcollection.hpp | 7 +++- 14 files changed, 167 insertions(+), 38 deletions(-) create mode 100644 apps/opencs/model/world/nestedtablewrapper.cpp create mode 100644 apps/opencs/model/world/nestedtablewrapper.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 3871a4d5af..bcc64b60ad 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -19,7 +19,7 @@ opencs_hdrs_noqt (model/doc opencs_units (model/world idtable idtableproxymodel regionmap data commanddispatcher - idtablebase resourcetable nestedtablemodel + idtablebase resourcetable nestedtablemodel nestedtablewrapper ) diff --git a/apps/opencs/model/world/collection.hpp b/apps/opencs/model/world/collection.hpp index 904587eaff..ac43519863 100644 --- a/apps/opencs/model/world/collection.hpp +++ b/apps/opencs/model/world/collection.hpp @@ -16,6 +16,8 @@ #include "collectionbase.hpp" +#include "nestedtablewrapper.hpp" + namespace CSMWorld { /// \brief Access to ID field in records @@ -90,6 +92,10 @@ namespace CSMWorld virtual void setData (int index, int column, const QVariant& data); + virtual NestedTableWrapperBase nestedTable(int row, int column) const; + + virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable); + virtual const ColumnBase& getColumn (int column) const; virtual void merge(); @@ -300,6 +306,18 @@ namespace CSMWorld { return QVariant(); } + + template + NestedTableWrapperBase Collection::nestedTable(int row, int column) const + { + return NestedTableWrapperBase(); + } + + template + void Collection::setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable) + { + throw std::logic_error("setNestedTable was not overriden"); + } template void Collection::setData (int index, int column, const QVariant& data) diff --git a/apps/opencs/model/world/collectionbase.hpp b/apps/opencs/model/world/collectionbase.hpp index aad40d36bc..62f4079fc0 100644 --- a/apps/opencs/model/world/collectionbase.hpp +++ b/apps/opencs/model/world/collectionbase.hpp @@ -13,6 +13,7 @@ namespace CSMWorld { struct ColumnBase; struct RecordBase; + class NestedTableWrapperBase; /// \brief Base class for record collections /// @@ -33,10 +34,10 @@ namespace CSMWorld virtual ~CollectionBase(); virtual int getSize() const = 0; - - virtual int getNestedRowsCount(int row, int column) const; - virtual int getNestedColumnsCount(int row, int column) const; + virtual int getNestedRowsCount(int row, int column) const; + + virtual int getNestedColumnsCount(int row, int column) const; virtual std::string getId (int index) const = 0; @@ -50,6 +51,10 @@ namespace CSMWorld virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const = 0; + virtual NestedTableWrapperBase nestedTable(int row, int column) const = 0; + + virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable) = 0; + virtual void setData (int index, int column, const QVariant& data) = 0; virtual void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn); diff --git a/apps/opencs/model/world/commands.cpp b/apps/opencs/model/world/commands.cpp index 0127366978..5e886bdb4e 100644 --- a/apps/opencs/model/world/commands.cpp +++ b/apps/opencs/model/world/commands.cpp @@ -177,26 +177,10 @@ CSMWorld::DeleteNestedCommand::DeleteNestedCommand (IdTable& model, const std::s mModel(model), mParentColumn(parentColumn), QUndoCommand(parent), - mNestedRow(nestedRow) + mNestedRow(nestedRow), + mOld(model.nestedTable(model.getModelIndex(id, parentColumn))) { setText (("Delete nested row in " + mId).c_str()); - - const QModelIndex& parentIndex = mModel.getModelIndex(mId, mParentColumn); - - const int columnsCount = mModel.columnCount(parentIndex); - - for (int i = 0; i < columnsCount; ++i) - { - const QModelIndex& childIndex = mModel.index(nestedRow, i, parentIndex); - - QVariant data = childIndex.data(); - if (!data.isValid()) - { - data = childIndex.data(Qt::DisplayRole); - } - - mOld.push_back(data); - } } void CSMWorld::DeleteNestedCommand::redo() @@ -211,14 +195,7 @@ void CSMWorld::DeleteNestedCommand::undo() { const QModelIndex& parentIndex = mModel.getModelIndex(mId, mParentColumn); - mModel.addNestedRow(parentIndex, mNestedRow); - - for (int i = 0; i < mModel.columnCount(parentIndex); ++i) - { - const QModelIndex& current = mModel.index(mNestedRow, i, parentIndex); - - mModel.setData(current, mOld[i]); - } + mModel.setNestedTable(parentIndex, mOld); } CSMWorld::AddNestedCommand::AddNestedCommand(IdTable& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent) @@ -226,7 +203,8 @@ CSMWorld::AddNestedCommand::AddNestedCommand(IdTable& model, const std::string& mId(id), mNewRow(nestedRow), mParentColumn(parentColumn), - QUndoCommand(parent) + QUndoCommand(parent), + mOld(model.nestedTable(model.getModelIndex(id, parentColumn))) { setText (("Added nested row in " + mId).c_str()); } @@ -241,6 +219,6 @@ void CSMWorld::AddNestedCommand::redo() void CSMWorld::AddNestedCommand::undo() { const QModelIndex& parentIndex = mModel.getModelIndex(mId, mParentColumn); - - mModel.removeRows(mNewRow, 1, parentIndex); + + mModel.setNestedTable(parentIndex, mOld); } diff --git a/apps/opencs/model/world/commands.hpp b/apps/opencs/model/world/commands.hpp index e6f2d9724f..214a5157ef 100644 --- a/apps/opencs/model/world/commands.hpp +++ b/apps/opencs/model/world/commands.hpp @@ -13,6 +13,7 @@ #include #include "universalid.hpp" +#include "nestedtablewrapper.hpp" class QModelIndex; class QAbstractItemModel; @@ -22,6 +23,7 @@ namespace CSMWorld class IdTable; class IdTable; class RecordBase; + class NestedTableWrapperBase; class ModifyCommand : public QUndoCommand { @@ -143,7 +145,7 @@ namespace CSMWorld std::string mId; - std::vector mOld; + NestedTableWrapperBase mOld; int mParentColumn; @@ -164,6 +166,8 @@ namespace CSMWorld std::string mId; + NestedTableWrapperBase mOld; + int mNewRow; int mParentColumn; diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index a3435180c4..df0f4546d2 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -2,6 +2,7 @@ #include #include +#include "nestedtablewrapper.hpp" #include "collectionbase.hpp" #include "columnbase.hpp" @@ -357,3 +358,23 @@ bool CSMWorld::IdTable::hasChildren(const QModelIndex& index) const mIdCollection->getColumn(index.column()).mCanNest && index.data().isValid()); } + +void CSMWorld::IdTable::setNestedTable(const QModelIndex& index, const CSMWorld::NestedTableWrapperBase& nestedTable) +{ + if (!hasChildren(index)) + { + throw std::logic_error("Tried to set nested table, but index has no children"); + } + + mIdCollection->setNestedTable(index.row(), index.column(), nestedTable); +} + +CSMWorld::NestedTableWrapperBase CSMWorld::IdTable::nestedTable(const QModelIndex& index) const +{ + if (!hasChildren(index)) + { + throw std::logic_error("Tried to retrive nested table, but index has no children"); + } + + return mIdCollection->nestedTable(index.row(), index.column()); +} diff --git a/apps/opencs/model/world/idtable.hpp b/apps/opencs/model/world/idtable.hpp index fcb87c8b2b..fd3f699baa 100644 --- a/apps/opencs/model/world/idtable.hpp +++ b/apps/opencs/model/world/idtable.hpp @@ -20,6 +20,7 @@ namespace CSMWorld { class CollectionBase; class RecordBase; + class NestedTableWrapperBase; class IdTable : public IdTableBase { @@ -51,6 +52,10 @@ namespace CSMWorld virtual QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; QVariant nestedHeaderData(int section, int subSection, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + + NestedTableWrapperBase nestedTable(const QModelIndex &index) const; + + void setNestedTable(const QModelIndex &index, const NestedTableWrapperBase& nestedTable); virtual bool setData ( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); diff --git a/apps/opencs/model/world/nestedtablewrapper.cpp b/apps/opencs/model/world/nestedtablewrapper.cpp new file mode 100644 index 0000000000..387bc6e7b5 --- /dev/null +++ b/apps/opencs/model/world/nestedtablewrapper.cpp @@ -0,0 +1,7 @@ +#include "nestedtablewrapper.hpp" + +CSMWorld::NestedTableWrapperBase::NestedTableWrapperBase() +{} + +CSMWorld::NestedTableWrapperBase::~NestedTableWrapperBase() +{} diff --git a/apps/opencs/model/world/nestedtablewrapper.hpp b/apps/opencs/model/world/nestedtablewrapper.hpp new file mode 100644 index 0000000000..9fc21f8e06 --- /dev/null +++ b/apps/opencs/model/world/nestedtablewrapper.hpp @@ -0,0 +1,33 @@ +#ifndef CSM_WOLRD_NESTEDTABLEWRAPPER_H +#define CSM_WOLRD_NESTEDTABLEWRAPPER_H + +#include + +#include +namespace CSMWorld +{ + struct NestedTableWrapperBase + { + virtual ~NestedTableWrapperBase(); + + NestedTableWrapperBase(); + }; + + template + class NestedTableWrapper : public NestedTableWrapperBase + { + NestedTable mNestedTable; + + public: + + NestedTableWrapper(const NestedTable& nestedTable) {} + + NestedTable getNestedTable() const + { + return mNestedTable; + } + + virtual ~NestedTableWrapper() {} + }; +} +#endif diff --git a/apps/opencs/model/world/refidadapter.hpp b/apps/opencs/model/world/refidadapter.hpp index 068347fda5..f4aa769fd3 100644 --- a/apps/opencs/model/world/refidadapter.hpp +++ b/apps/opencs/model/world/refidadapter.hpp @@ -10,6 +10,7 @@ namespace CSMWorld class RefIdColumn; class RefIdData; class RecordBase; + class NestedTableWrapperBase; class RefIdAdapter { @@ -41,7 +42,7 @@ namespace CSMWorld NestedRefIdAdapter(); virtual ~NestedRefIdAdapter(); - + virtual void setNestedData (const RefIdColumn *column, RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const = 0; @@ -53,8 +54,12 @@ namespace CSMWorld virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const = 0; virtual void removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, int rowToRemove) const = 0; - + virtual void addNestedRow (const RefIdColumn *column, RefIdData& data, int index, int position) const = 0; + + virtual void setNestedTable (const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) = 0; + + virtual NestedTableWrapperBase nestedTable (const RefIdColumn * column, const RefIdData& data, int index) const = 0; }; } diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 8d6ab838dc..cb078ab740 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -1,7 +1,9 @@ #include "refidadapterimp.hpp" +#include "nestedtablewrapper.hpp" #include #include +#include CSMWorld::PotionRefIdAdapter::PotionRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *autoCalc) @@ -305,6 +307,27 @@ void CSMWorld::ContainerRefIdAdapter::setNestedData(const RefIdColumn *column, } } +void CSMWorld::ContainerRefIdAdapter::setNestedTable(const RefIdColumn* column, + RefIdData& data, + int index, + const NestedTableWrapperBase& nestedTable) +{ + Record& record = dynamic_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))); + + record.get().mInventory.mList = dynamic_cast >&>(nestedTable).getNestedTable(); +} + +CSMWorld::NestedTableWrapperBase CSMWorld::ContainerRefIdAdapter::nestedTable (const RefIdColumn* column, + const RefIdData& data, + int index) const +{ + const Record& record = dynamic_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))); + + return NestedTableWrapper >(record.get().mInventory.mList); +} + QVariant CSMWorld::ContainerRefIdAdapter::getNestedData (const CSMWorld::RefIdColumn* column, const CSMWorld::RefIdData& data, int index, diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 500b18ef84..4198fb3678 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -15,6 +15,8 @@ namespace CSMWorld { + class NestedTableWrapperBase; + struct BaseColumns { const RefIdColumn *mId; @@ -637,6 +639,10 @@ namespace CSMWorld virtual void removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, int rowToRemove) const; virtual void addNestedRow (const RefIdColumn *column, RefIdData& data, int index, int position) const; + + virtual NestedTableWrapperBase nestedTable (const RefIdColumn * column, const RefIdData& data, int index) const; + + virtual void setNestedTable (const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable); }; struct CreatureColumns : public ActorColumns diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 1a164d12f3..6ff0df8020 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -10,6 +10,7 @@ #include "refidadapter.hpp" #include "refidadapterimp.hpp" #include "columns.hpp" +#include "nestedtablewrapper.hpp" CSMWorld::RefIdColumn::RefIdColumn (int columnId, Display displayType, int flag, bool editable, bool userEditable, bool canNest) @@ -27,7 +28,7 @@ bool CSMWorld::RefIdColumn::isUserEditable() const } -const CSMWorld::RefIdAdapter& CSMWorld::RefIdCollection::findAdaptor (UniversalId::Type type) const +CSMWorld::RefIdAdapter& CSMWorld::RefIdCollection::findAdaptor (UniversalId::Type type) const { std::map::const_iterator iter = mAdapters.find (type); @@ -641,3 +642,21 @@ void CSMWorld::RefIdCollection::addNestedRow(int row, int col, int position) adaptor.addNestedRow(&mColumns.at(col), mData, localIndex.first, position); } + +void CSMWorld::RefIdCollection::setNestedTable(int row, int column, const CSMWorld::NestedTableWrapperBase& nestedTable) +{ + RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + + CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdaptor (localIndex.second)); + + adaptor.setNestedTable(&mColumns.at(column), mData, localIndex.first, nestedTable); +} + +CSMWorld::NestedTableWrapperBase CSMWorld::RefIdCollection::nestedTable(int row, int column) const +{ + RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + + const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdaptor (localIndex.second)); + + return adaptor.nestedTable(&mColumns.at(column), mData, localIndex.first); +} diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index 02b77400b6..927331c933 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -17,6 +17,7 @@ namespace ESM namespace CSMWorld { class RefIdAdapter; + class NestedTableWrapperBase; class RefIdColumn : public NestColumn { @@ -44,7 +45,7 @@ namespace CSMWorld private: - const RefIdAdapter& findAdaptor (UniversalId::Type) const; + RefIdAdapter& findAdaptor (UniversalId::Type) const; ///< Throws an exception if no adaptor for \a Type can be found. public: @@ -70,6 +71,10 @@ namespace CSMWorld virtual QVariant getData (int index, int column) const; virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const; + + virtual NestedTableWrapperBase nestedTable(int row, int column) const; + + virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable); virtual void setData (int index, int column, const QVariant& data); From 0017fc68ef719135cdf82060fbf19e1df4582377 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 19 Jul 2014 13:08:28 +0200 Subject: [PATCH 055/185] fixed ctor of nestedwrapper (missing initialization of member data field) --- apps/opencs/model/world/nestedtablewrapper.hpp | 3 ++- apps/opencs/model/world/refidadapterimp.cpp | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/world/nestedtablewrapper.hpp b/apps/opencs/model/world/nestedtablewrapper.hpp index 9fc21f8e06..c13a12c627 100644 --- a/apps/opencs/model/world/nestedtablewrapper.hpp +++ b/apps/opencs/model/world/nestedtablewrapper.hpp @@ -20,7 +20,8 @@ namespace CSMWorld public: - NestedTableWrapper(const NestedTable& nestedTable) {} + NestedTableWrapper(const NestedTable& nestedTable) + : mNestedTable(nestedTable) {} NestedTable getNestedTable() const { diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index cb078ab740..d669a369c8 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -1,9 +1,10 @@ #include "refidadapterimp.hpp" -#include "nestedtablewrapper.hpp" #include #include + #include +#include "nestedtablewrapper.hpp" CSMWorld::PotionRefIdAdapter::PotionRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *autoCalc) @@ -315,7 +316,7 @@ void CSMWorld::ContainerRefIdAdapter::setNestedTable(const RefIdColumn* column, Record& record = dynamic_cast&> ( data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))); - record.get().mInventory.mList = dynamic_cast >&>(nestedTable).getNestedTable(); + record.get().mInventory.mList = (dynamic_cast >&>(nestedTable)).getNestedTable(); } CSMWorld::NestedTableWrapperBase CSMWorld::ContainerRefIdAdapter::nestedTable (const RefIdColumn* column, From 4d79034dbfa1f5c19e05c56045b779430919cf59 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 20 Jul 2014 18:52:35 +0200 Subject: [PATCH 056/185] correctly handling the nestedTable for undo (but removing and adding rows in proper QT way is still TODO) --- apps/opencs/model/world/collection.hpp | 8 +++++--- apps/opencs/model/world/collectionbase.hpp | 2 +- apps/opencs/model/world/commands.cpp | 19 +++++++++++++++---- apps/opencs/model/world/commands.hpp | 8 ++++++-- apps/opencs/model/world/idtable.cpp | 5 ++++- apps/opencs/model/world/idtable.hpp | 2 +- .../opencs/model/world/nestedtablewrapper.hpp | 14 ++------------ apps/opencs/model/world/refidadapter.hpp | 2 +- apps/opencs/model/world/refidadapterimp.cpp | 18 +++++++++--------- apps/opencs/model/world/refidadapterimp.hpp | 2 +- apps/opencs/model/world/refidcollection.cpp | 2 +- apps/opencs/model/world/refidcollection.hpp | 2 +- 12 files changed, 47 insertions(+), 37 deletions(-) diff --git a/apps/opencs/model/world/collection.hpp b/apps/opencs/model/world/collection.hpp index ac43519863..591074372d 100644 --- a/apps/opencs/model/world/collection.hpp +++ b/apps/opencs/model/world/collection.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include @@ -92,7 +93,7 @@ namespace CSMWorld virtual void setData (int index, int column, const QVariant& data); - virtual NestedTableWrapperBase nestedTable(int row, int column) const; + virtual NestedTableWrapperBase* nestedTable(int row, int column) const; virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable); @@ -308,9 +309,10 @@ namespace CSMWorld } template - NestedTableWrapperBase Collection::nestedTable(int row, int column) const + NestedTableWrapperBase* Collection::nestedTable(int row, int column) const { - return NestedTableWrapperBase(); + assert(false); + return new NestedTableWrapperBase(); } template diff --git a/apps/opencs/model/world/collectionbase.hpp b/apps/opencs/model/world/collectionbase.hpp index 62f4079fc0..a6ee34e56e 100644 --- a/apps/opencs/model/world/collectionbase.hpp +++ b/apps/opencs/model/world/collectionbase.hpp @@ -51,7 +51,7 @@ namespace CSMWorld virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const = 0; - virtual NestedTableWrapperBase nestedTable(int row, int column) const = 0; + virtual NestedTableWrapperBase* nestedTable(int row, int column) const = 0; virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable) = 0; diff --git a/apps/opencs/model/world/commands.cpp b/apps/opencs/model/world/commands.cpp index 5e886bdb4e..f464d75c8f 100644 --- a/apps/opencs/model/world/commands.cpp +++ b/apps/opencs/model/world/commands.cpp @@ -4,6 +4,7 @@ #include "idtable.hpp" #include +#include "nestedtablewrapper.hpp" CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelIndex& index, const QVariant& new_, QUndoCommand* parent) @@ -178,7 +179,7 @@ CSMWorld::DeleteNestedCommand::DeleteNestedCommand (IdTable& model, const std::s mParentColumn(parentColumn), QUndoCommand(parent), mNestedRow(nestedRow), - mOld(model.nestedTable(model.getModelIndex(id, parentColumn))) + mOld (model.nestedTable(model.getModelIndex(id, parentColumn))) { setText (("Delete nested row in " + mId).c_str()); } @@ -195,7 +196,12 @@ void CSMWorld::DeleteNestedCommand::undo() { const QModelIndex& parentIndex = mModel.getModelIndex(mId, mParentColumn); - mModel.setNestedTable(parentIndex, mOld); + mModel.setNestedTable(parentIndex, *mOld); +} + +CSMWorld::DeleteNestedCommand::~DeleteNestedCommand() +{ + delete mOld; } CSMWorld::AddNestedCommand::AddNestedCommand(IdTable& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent) @@ -204,7 +210,7 @@ CSMWorld::AddNestedCommand::AddNestedCommand(IdTable& model, const std::string& mNewRow(nestedRow), mParentColumn(parentColumn), QUndoCommand(parent), - mOld(model.nestedTable(model.getModelIndex(id, parentColumn))) + mOld (model.nestedTable(model.getModelIndex(id, parentColumn))) { setText (("Added nested row in " + mId).c_str()); } @@ -220,5 +226,10 @@ void CSMWorld::AddNestedCommand::undo() { const QModelIndex& parentIndex = mModel.getModelIndex(mId, mParentColumn); - mModel.setNestedTable(parentIndex, mOld); + mModel.setNestedTable(parentIndex, *mOld); +} + +CSMWorld::AddNestedCommand::~AddNestedCommand() +{ + delete mOld; } diff --git a/apps/opencs/model/world/commands.hpp b/apps/opencs/model/world/commands.hpp index 214a5157ef..d45ec1e36d 100644 --- a/apps/opencs/model/world/commands.hpp +++ b/apps/opencs/model/world/commands.hpp @@ -145,7 +145,7 @@ namespace CSMWorld std::string mId; - NestedTableWrapperBase mOld; + NestedTableWrapperBase* mOld; int mParentColumn; @@ -155,6 +155,8 @@ namespace CSMWorld DeleteNestedCommand (IdTable& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent = 0); + ~DeleteNestedCommand(); + virtual void redo(); virtual void undo(); @@ -166,7 +168,7 @@ namespace CSMWorld std::string mId; - NestedTableWrapperBase mOld; + NestedTableWrapperBase* mOld; int mNewRow; @@ -175,6 +177,8 @@ namespace CSMWorld public: AddNestedCommand(IdTable& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent = 0); + + ~AddNestedCommand(); virtual void redo(); diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index df0f4546d2..dd045cb789 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -367,9 +367,12 @@ void CSMWorld::IdTable::setNestedTable(const QModelIndex& index, const CSMWorld: } mIdCollection->setNestedTable(index.row(), index.column(), nestedTable); + + emit dataChanged (CSMWorld::IdTable::index (index.row(), 0), + CSMWorld::IdTable::index (index.row(), mIdCollection->getColumns()-1)); } -CSMWorld::NestedTableWrapperBase CSMWorld::IdTable::nestedTable(const QModelIndex& index) const +CSMWorld::NestedTableWrapperBase* CSMWorld::IdTable::nestedTable(const QModelIndex& index) const { if (!hasChildren(index)) { diff --git a/apps/opencs/model/world/idtable.hpp b/apps/opencs/model/world/idtable.hpp index fd3f699baa..b7ba8c342d 100644 --- a/apps/opencs/model/world/idtable.hpp +++ b/apps/opencs/model/world/idtable.hpp @@ -53,7 +53,7 @@ namespace CSMWorld QVariant nestedHeaderData(int section, int subSection, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - NestedTableWrapperBase nestedTable(const QModelIndex &index) const; + NestedTableWrapperBase* nestedTable(const QModelIndex &index) const; void setNestedTable(const QModelIndex &index, const NestedTableWrapperBase& nestedTable); diff --git a/apps/opencs/model/world/nestedtablewrapper.hpp b/apps/opencs/model/world/nestedtablewrapper.hpp index c13a12c627..70e35f68a9 100644 --- a/apps/opencs/model/world/nestedtablewrapper.hpp +++ b/apps/opencs/model/world/nestedtablewrapper.hpp @@ -1,9 +1,6 @@ #ifndef CSM_WOLRD_NESTEDTABLEWRAPPER_H #define CSM_WOLRD_NESTEDTABLEWRAPPER_H -#include - -#include namespace CSMWorld { struct NestedTableWrapperBase @@ -14,20 +11,13 @@ namespace CSMWorld }; template - class NestedTableWrapper : public NestedTableWrapperBase + struct NestedTableWrapper : public NestedTableWrapperBase { NestedTable mNestedTable; - public: - - NestedTableWrapper(const NestedTable& nestedTable) + NestedTableWrapper(const NestedTable& nestedTable) : mNestedTable(nestedTable) {} - NestedTable getNestedTable() const - { - return mNestedTable; - } - virtual ~NestedTableWrapper() {} }; } diff --git a/apps/opencs/model/world/refidadapter.hpp b/apps/opencs/model/world/refidadapter.hpp index f4aa769fd3..f7064ab66e 100644 --- a/apps/opencs/model/world/refidadapter.hpp +++ b/apps/opencs/model/world/refidadapter.hpp @@ -59,7 +59,7 @@ namespace CSMWorld virtual void setNestedTable (const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) = 0; - virtual NestedTableWrapperBase nestedTable (const RefIdColumn * column, const RefIdData& data, int index) const = 0; + virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, const RefIdData& data, int index) const = 0; }; } diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index d669a369c8..173e89f56b 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -227,24 +227,24 @@ void CSMWorld::ContainerRefIdAdapter::removeNestedRow (const RefIdColumn *column std::vector& list = static_cast&> ( data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))).get().mInventory.mList; - + list.erase (list.begin () + rowToRemove); } void CSMWorld::ContainerRefIdAdapter::addNestedRow (const RefIdColumn *column, RefIdData& data, int index, int position) const { assert(column==mContent); - + std::vector& list = static_cast&> ( data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))).get().mInventory.mList; - + ESM::ContItem newRow = {0, ""}; if (position >= (int)list.size()) { list.push_back(newRow); return; } - + list.insert(list.begin()+position, newRow); return; @@ -310,23 +310,23 @@ void CSMWorld::ContainerRefIdAdapter::setNestedData(const RefIdColumn *column, void CSMWorld::ContainerRefIdAdapter::setNestedTable(const RefIdColumn* column, RefIdData& data, - int index, + int index, const NestedTableWrapperBase& nestedTable) { Record& record = dynamic_cast&> ( data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))); - record.get().mInventory.mList = (dynamic_cast >&>(nestedTable)).getNestedTable(); + record.get().mInventory.mList = (static_cast >&>(nestedTable)).mNestedTable; } -CSMWorld::NestedTableWrapperBase CSMWorld::ContainerRefIdAdapter::nestedTable (const RefIdColumn* column, - const RefIdData& data, +CSMWorld::NestedTableWrapperBase* CSMWorld::ContainerRefIdAdapter::nestedTable (const RefIdColumn* column, + const RefIdData& data, int index) const { const Record& record = dynamic_cast&> ( data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))); - return NestedTableWrapper >(record.get().mInventory.mList); + return new NestedTableWrapper >(record.get().mInventory.mList); } QVariant CSMWorld::ContainerRefIdAdapter::getNestedData (const CSMWorld::RefIdColumn* column, diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 4198fb3678..ab05cfbc50 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -640,7 +640,7 @@ namespace CSMWorld virtual void addNestedRow (const RefIdColumn *column, RefIdData& data, int index, int position) const; - virtual NestedTableWrapperBase nestedTable (const RefIdColumn * column, const RefIdData& data, int index) const; + virtual NestedTableWrapperBase* nestedTable (const RefIdColumn * column, const RefIdData& data, int index) const; virtual void setNestedTable (const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable); }; diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 6ff0df8020..80ac1cc3b1 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -652,7 +652,7 @@ void CSMWorld::RefIdCollection::setNestedTable(int row, int column, const CSMWor adaptor.setNestedTable(&mColumns.at(column), mData, localIndex.first, nestedTable); } -CSMWorld::NestedTableWrapperBase CSMWorld::RefIdCollection::nestedTable(int row, int column) const +CSMWorld::NestedTableWrapperBase* CSMWorld::RefIdCollection::nestedTable(int row, int column) const { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index 927331c933..cc7609a587 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -72,7 +72,7 @@ namespace CSMWorld virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const; - virtual NestedTableWrapperBase nestedTable(int row, int column) const; + virtual NestedTableWrapperBase* nestedTable(int row, int column) const; virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable); From 87eed066c24ddd10095b8c680fe730103718a164 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 20 Jul 2014 22:39:39 +0200 Subject: [PATCH 057/185] undo works now --- apps/opencs/CMakeLists.txt | 4 ++-- apps/opencs/model/world/idtable.cpp | 12 ++++++++++++ apps/opencs/model/world/idtable.hpp | 9 +++++++-- apps/opencs/model/world/nestedtablemodel.cpp | 18 ++++++++++++++++++ apps/opencs/model/world/nestedtablemodel.hpp | 4 ++++ apps/opencs/model/world/nestedtablewrapper.cpp | 5 +++++ apps/opencs/model/world/nestedtablewrapper.hpp | 9 ++++++++- 7 files changed, 56 insertions(+), 5 deletions(-) diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index bcc64b60ad..a9c56f9fa1 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -19,12 +19,12 @@ opencs_hdrs_noqt (model/doc opencs_units (model/world idtable idtableproxymodel regionmap data commanddispatcher - idtablebase resourcetable nestedtablemodel nestedtablewrapper + idtablebase resourcetable nestedtablemodel ) opencs_units_noqt (model/world - universalid record commands columnbase scriptcontext cell refidcollection + nestedtablewrapper universalid record commands columnbase scriptcontext cell refidcollection refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager ) diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index dd045cb789..be31d05030 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -366,10 +366,22 @@ void CSMWorld::IdTable::setNestedTable(const QModelIndex& index, const CSMWorld: throw std::logic_error("Tried to set nested table, but index has no children"); } + bool removeRowsMode = false; + if (nestedTable.size() != this->nestedTable(index)->size()) + { + emit resetStart(this->index(index.row(), 0).data().toString()); + removeRowsMode = true; + } + mIdCollection->setNestedTable(index.row(), index.column(), nestedTable); emit dataChanged (CSMWorld::IdTable::index (index.row(), 0), CSMWorld::IdTable::index (index.row(), mIdCollection->getColumns()-1)); + + if (removeRowsMode) + { + emit resetEnd(this->index(index.row(), 0).data().toString()); + } } CSMWorld::NestedTableWrapperBase* CSMWorld::IdTable::nestedTable(const QModelIndex& index) const diff --git a/apps/opencs/model/world/idtable.hpp b/apps/opencs/model/world/idtable.hpp index b7ba8c342d..d755822b5f 100644 --- a/apps/opencs/model/world/idtable.hpp +++ b/apps/opencs/model/world/idtable.hpp @@ -52,9 +52,9 @@ namespace CSMWorld virtual QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; QVariant nestedHeaderData(int section, int subSection, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - + NestedTableWrapperBase* nestedTable(const QModelIndex &index) const; - + void setNestedTable(const QModelIndex &index, const NestedTableWrapperBase& nestedTable); virtual bool setData ( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); @@ -105,6 +105,11 @@ namespace CSMWorld virtual bool isDeleted (const std::string& id) const; int getColumnId(int column) const; + + signals: + void resetStart(const QString& id); + + void resetEnd(const QString& id); }; } diff --git a/apps/opencs/model/world/nestedtablemodel.cpp b/apps/opencs/model/world/nestedtablemodel.cpp index f0b5102440..734047b8dd 100644 --- a/apps/opencs/model/world/nestedtablemodel.cpp +++ b/apps/opencs/model/world/nestedtablemodel.cpp @@ -26,6 +26,12 @@ CSMWorld::NestedTableModel::NestedTableModel(const QModelIndex& parent, connect(mMainModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SLOT(forwardRowsRemoved(const QModelIndex &, int, int))); + + connect(mMainModel, SIGNAL(resetStart(const QString&)), + this, SLOT(forwardResetStart(const QString&))); + + connect(mMainModel, SIGNAL(resetEnd(const QString&)), + this, SLOT(forwardResetEnd(const QString&))); } QModelIndex CSMWorld::NestedTableModel::mapFromSource(const QModelIndex& sourceIndex) const @@ -157,3 +163,15 @@ void CSMWorld::NestedTableModel::forwardRowsRemoved(const QModelIndex& parent, i endRemoveRows(); } } + +void CSMWorld::NestedTableModel::forwardResetStart(const QString& id) +{ + if (id.toUtf8() == mId.c_str()) + beginResetModel(); +} + +void CSMWorld::NestedTableModel::forwardResetEnd(const QString& id) +{ + if (id.toUtf8() == mId.c_str()) + endResetModel(); +} diff --git a/apps/opencs/model/world/nestedtablemodel.hpp b/apps/opencs/model/world/nestedtablemodel.hpp index dfb231124c..5fea5c0061 100644 --- a/apps/opencs/model/world/nestedtablemodel.hpp +++ b/apps/opencs/model/world/nestedtablemodel.hpp @@ -70,6 +70,10 @@ namespace CSMWorld void forwardRowsAboutToRemoved(const QModelIndex & parent, int first, int last); void forwardRowsRemoved(const QModelIndex & parent, int first, int last); + + void forwardResetStart(const QString& id); + + void forwardResetEnd(const QString& id); }; } diff --git a/apps/opencs/model/world/nestedtablewrapper.cpp b/apps/opencs/model/world/nestedtablewrapper.cpp index 387bc6e7b5..3966dbc575 100644 --- a/apps/opencs/model/world/nestedtablewrapper.cpp +++ b/apps/opencs/model/world/nestedtablewrapper.cpp @@ -5,3 +5,8 @@ CSMWorld::NestedTableWrapperBase::NestedTableWrapperBase() CSMWorld::NestedTableWrapperBase::~NestedTableWrapperBase() {} + +int CSMWorld::NestedTableWrapperBase::size() const +{ + return -5; +} diff --git a/apps/opencs/model/world/nestedtablewrapper.hpp b/apps/opencs/model/world/nestedtablewrapper.hpp index 70e35f68a9..f0ca00dbee 100644 --- a/apps/opencs/model/world/nestedtablewrapper.hpp +++ b/apps/opencs/model/world/nestedtablewrapper.hpp @@ -7,9 +7,11 @@ namespace CSMWorld { virtual ~NestedTableWrapperBase(); + virtual int size() const; + NestedTableWrapperBase(); }; - + template struct NestedTableWrapper : public NestedTableWrapperBase { @@ -19,6 +21,11 @@ namespace CSMWorld : mNestedTable(nestedTable) {} virtual ~NestedTableWrapper() {} + + virtual int size() const + { + return mNestedTable.size(); //i hope that this will be enough + } }; } #endif From 3dd2ca15da9228f1463d59800b71dfc54a31f95d Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 21 Jul 2014 09:52:09 +0200 Subject: [PATCH 058/185] Reduced code duplication through new common base class --- apps/opencs/model/world/commands.cpp | 23 +++++++++++++---------- apps/opencs/model/world/commands.hpp | 26 ++++++++++++++++---------- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/apps/opencs/model/world/commands.cpp b/apps/opencs/model/world/commands.cpp index f464d75c8f..0d9f6c7732 100644 --- a/apps/opencs/model/world/commands.cpp +++ b/apps/opencs/model/world/commands.cpp @@ -179,7 +179,7 @@ CSMWorld::DeleteNestedCommand::DeleteNestedCommand (IdTable& model, const std::s mParentColumn(parentColumn), QUndoCommand(parent), mNestedRow(nestedRow), - mOld (model.nestedTable(model.getModelIndex(id, parentColumn))) + NestedTableStoring(model, id, parentColumn) { setText (("Delete nested row in " + mId).c_str()); } @@ -196,12 +196,7 @@ void CSMWorld::DeleteNestedCommand::undo() { const QModelIndex& parentIndex = mModel.getModelIndex(mId, mParentColumn); - mModel.setNestedTable(parentIndex, *mOld); -} - -CSMWorld::DeleteNestedCommand::~DeleteNestedCommand() -{ - delete mOld; + mModel.setNestedTable(parentIndex, getOld()); } CSMWorld::AddNestedCommand::AddNestedCommand(IdTable& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent) @@ -210,7 +205,7 @@ CSMWorld::AddNestedCommand::AddNestedCommand(IdTable& model, const std::string& mNewRow(nestedRow), mParentColumn(parentColumn), QUndoCommand(parent), - mOld (model.nestedTable(model.getModelIndex(id, parentColumn))) + NestedTableStoring(model, id, parentColumn) { setText (("Added nested row in " + mId).c_str()); } @@ -226,10 +221,18 @@ void CSMWorld::AddNestedCommand::undo() { const QModelIndex& parentIndex = mModel.getModelIndex(mId, mParentColumn); - mModel.setNestedTable(parentIndex, *mOld); + mModel.setNestedTable(parentIndex, getOld()); } -CSMWorld::AddNestedCommand::~AddNestedCommand() +CSMWorld::NestedTableStoring::NestedTableStoring(const IdTable& model, const std::string& id, int parentColumn) + : mOld(model.nestedTable(model.getModelIndex(id, parentColumn))) {} + +CSMWorld::NestedTableStoring::~NestedTableStoring() { delete mOld; } + +const CSMWorld::NestedTableWrapperBase& CSMWorld::NestedTableStoring::getOld() const +{ + return *mOld; +} diff --git a/apps/opencs/model/world/commands.hpp b/apps/opencs/model/world/commands.hpp index d45ec1e36d..d868ccf460 100644 --- a/apps/opencs/model/world/commands.hpp +++ b/apps/opencs/model/world/commands.hpp @@ -139,14 +139,26 @@ namespace CSMWorld virtual void undo(); }; - class DeleteNestedCommand : public QUndoCommand + class NestedTableStoring + { + NestedTableWrapperBase* mOld; + + public: + NestedTableStoring(const IdTable& model, const std::string& id, int parentColumn); + + ~NestedTableStoring(); + + protected: + + const NestedTableWrapperBase& getOld() const; + }; + + class DeleteNestedCommand : public QUndoCommand, private NestedTableStoring { IdTable& mModel; std::string mId; - NestedTableWrapperBase* mOld; - int mParentColumn; int mNestedRow; @@ -155,21 +167,17 @@ namespace CSMWorld DeleteNestedCommand (IdTable& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent = 0); - ~DeleteNestedCommand(); - virtual void redo(); virtual void undo(); }; - class AddNestedCommand : public QUndoCommand + class AddNestedCommand : public QUndoCommand, private NestedTableStoring { IdTable& mModel; std::string mId; - NestedTableWrapperBase* mOld; - int mNewRow; int mParentColumn; @@ -177,8 +185,6 @@ namespace CSMWorld public: AddNestedCommand(IdTable& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent = 0); - - ~AddNestedCommand(); virtual void redo(); From c4598d6200e21de1df91234dad7637a04c62f36d Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 21 Jul 2014 14:09:00 +0200 Subject: [PATCH 059/185] added inventory helper (since npc and containers share same way of handling items) --- apps/opencs/CMakeLists.txt | 3 +- apps/opencs/model/world/nestedadaptors.cpp | 1 + apps/opencs/model/world/nestedadaptors.hpp | 56 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.cpp | 12 ++--- apps/opencs/model/world/refidadapterimp.hpp | 3 ++ 5 files changed, 65 insertions(+), 10 deletions(-) create mode 100644 apps/opencs/model/world/nestedadaptors.cpp create mode 100644 apps/opencs/model/world/nestedadaptors.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index a9c56f9fa1..08c105c922 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -25,7 +25,8 @@ opencs_units (model/world opencs_units_noqt (model/world nestedtablewrapper universalid record commands columnbase scriptcontext cell refidcollection - refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager + refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection + tablemimedata cellcoordinates cellselection resources resourcesmanager nestedadaptors ) opencs_hdrs_noqt (model/world diff --git a/apps/opencs/model/world/nestedadaptors.cpp b/apps/opencs/model/world/nestedadaptors.cpp new file mode 100644 index 0000000000..8ed1819b8f --- /dev/null +++ b/apps/opencs/model/world/nestedadaptors.cpp @@ -0,0 +1 @@ +#include "nestedadaptors.hpp" diff --git a/apps/opencs/model/world/nestedadaptors.hpp b/apps/opencs/model/world/nestedadaptors.hpp new file mode 100644 index 0000000000..c0ca9744c2 --- /dev/null +++ b/apps/opencs/model/world/nestedadaptors.hpp @@ -0,0 +1,56 @@ +#ifndef CSM_WORLD_NESTEDADAPTORS_H +#define CSM_WORLD_NESTEDADAPTORS_H + +#include + +#include "universalid.hpp" +#include "nestedtablewrapper.hpp" +#include +#include "record.hpp" +#include "refiddata.hpp" +#include "refidadapter.hpp" + +namespace CSMWorld +{ + template + class InventoryHelper + { + CSMWorld::UniversalId::Type mType; + + public: + + InventoryHelper(CSMWorld::UniversalId::Type type) : mType(type) {}; + + void setNestedTable(const RefIdColumn* column, + RefIdData& data, + int index, + const NestedTableWrapperBase& nestedTable) + { + getRecord(data, index).get().mInventory.mList = + (static_cast >&>(nestedTable)).mNestedTable; + } + + NestedTableWrapperBase* nestedTable(const RefIdColumn* column, + const RefIdData& data, + int index) const + { + return new NestedTableWrapper >(getRecord(data, index).get().mInventory.mList); + } + + private: + + const Record& getRecord(const RefIdData& data, int index) const + { + return dynamic_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, mType))); + } + + Record& getRecord(RefIdData& data, int index) const + { + return dynamic_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, mType))); + } + }; +} + +#endif diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 173e89f56b..08d8909575 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -180,7 +180,7 @@ void CSMWorld::ClothingRefIdAdapter::setData (const RefIdColumn *column, RefIdDa CSMWorld::ContainerRefIdAdapter::ContainerRefIdAdapter (const NameColumns& columns, const RefIdColumn *weight, const RefIdColumn *organic, const RefIdColumn *respawn, const RefIdColumn *content) : NameRefIdAdapter (UniversalId::Type_Container, columns), mWeight (weight), - mOrganic (organic), mRespawn (respawn), mContent(content) + mOrganic (organic), mRespawn (respawn), mContent(content), mHelper(InventoryHelper(UniversalId::Type_Container)) {} int CSMWorld::ContainerRefIdAdapter::getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const @@ -313,20 +313,14 @@ void CSMWorld::ContainerRefIdAdapter::setNestedTable(const RefIdColumn* column, int index, const NestedTableWrapperBase& nestedTable) { - Record& record = dynamic_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))); - - record.get().mInventory.mList = (static_cast >&>(nestedTable)).mNestedTable; + mHelper.setNestedTable(column, data, index, nestedTable); } CSMWorld::NestedTableWrapperBase* CSMWorld::ContainerRefIdAdapter::nestedTable (const RefIdColumn* column, const RefIdData& data, int index) const { - const Record& record = dynamic_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))); - - return new NestedTableWrapper >(record.get().mInventory.mList); + return mHelper.nestedTable(column, data, index); } QVariant CSMWorld::ContainerRefIdAdapter::getNestedData (const CSMWorld::RefIdColumn* column, diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index ab05cfbc50..aac2ba8073 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -12,6 +12,7 @@ #include "refiddata.hpp" #include "universalid.hpp" #include "refidadapter.hpp" +#include "nestedadaptors.hpp" namespace CSMWorld { @@ -614,6 +615,8 @@ namespace CSMWorld const RefIdColumn *mOrganic; const RefIdColumn *mRespawn; const RefIdColumn *mContent; + + InventoryHelper mHelper; public: From 6573e3f319e27d7bbcdc3e209f941fae9fb257df Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 21 Jul 2014 14:24:54 +0200 Subject: [PATCH 060/185] moved responsibility for getNestedData to the inventory helper --- apps/opencs/model/world/nestedadaptors.hpp | 23 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.cpp | 17 +-------------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/apps/opencs/model/world/nestedadaptors.hpp b/apps/opencs/model/world/nestedadaptors.hpp index c0ca9744c2..d5edf33584 100644 --- a/apps/opencs/model/world/nestedadaptors.hpp +++ b/apps/opencs/model/world/nestedadaptors.hpp @@ -10,6 +10,8 @@ #include "refiddata.hpp" #include "refidadapter.hpp" +#include + namespace CSMWorld { template @@ -37,6 +39,27 @@ namespace CSMWorld return new NestedTableWrapper >(getRecord(data, index).get().mInventory.mList); } + QVariant getNestedData(const CSMWorld::RefIdColumn* column, + const CSMWorld::RefIdData& data, + int index, + int subRowIndex, + int subColIndex) const + { + const ESM::ContItem& content = getRecord(data, index).get().mInventory.mList.at(subRowIndex); + + switch (subColIndex) + { + case 0: + return QString::fromUtf8(content.mItem.toString().c_str()); + + case 1: + return content.mCount; + + default: + throw std::logic_error("Trying to access non-existing column in the nested table!"); + } + } + private: const Record& getRecord(const RefIdData& data, int index) const diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 08d8909575..3622c77af4 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -329,24 +329,9 @@ QVariant CSMWorld::ContainerRefIdAdapter::getNestedData (const CSMWorld::RefIdCo int subRowIndex, int subColIndex) const { - const Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))); - if (column==mContent) { - const ESM::ContItem& content = record.get().mInventory.mList.at(subRowIndex); - - switch (subColIndex) - { - case 0: - return QString::fromUtf8(content.mItem.toString().c_str()); - - case 1: - return content.mCount; - - default: - throw std::logic_error("Trying to access non-existing column in the nested table!"); - } + return mHelper.getNestedData(column, data, index, subRowIndex, subColIndex); } else { throw std::logic_error("This column does not hold multiple values."); From cb004936e03cc802211d31ee165f3670fcbe1989 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 21 Jul 2014 14:34:48 +0200 Subject: [PATCH 061/185] moved setNestedData to the helper as well --- apps/opencs/model/world/nestedadaptors.hpp | 23 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.cpp | 19 ++--------------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/apps/opencs/model/world/nestedadaptors.hpp b/apps/opencs/model/world/nestedadaptors.hpp index d5edf33584..8f82482d85 100644 --- a/apps/opencs/model/world/nestedadaptors.hpp +++ b/apps/opencs/model/world/nestedadaptors.hpp @@ -2,6 +2,7 @@ #define CSM_WORLD_NESTEDADAPTORS_H #include +#include #include "universalid.hpp" #include "nestedtablewrapper.hpp" @@ -59,6 +60,28 @@ namespace CSMWorld throw std::logic_error("Trying to access non-existing column in the nested table!"); } } + + void setNestedData (const RefIdColumn *column, + RefIdData& data, + int index, + const QVariant& value, + int subRowIndex, + int subColIndex) const + { + switch(subColIndex) + { + case 0: + getRecord(data, index).get().mInventory.mList.at(subRowIndex).mItem.assign(std::string(value.toString().toUtf8().constData())); + break; + + case 1: + getRecord(data, index).get().mInventory.mList.at(subRowIndex).mCount = value.toInt(); + break; + + default: + throw std::logic_error("Trying to access non-existing column in the nested table!"); + } + } private: diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 3622c77af4..3600562d39 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -285,23 +285,8 @@ void CSMWorld::ContainerRefIdAdapter::setNestedData(const RefIdColumn *column, { if (column==mContent) - { - Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))); - - switch (subColIndex) - { - case 0: - record.get().mInventory.mList.at(subRowIndex).mItem.assign(std::string(value.toString().toUtf8().constData())); - break; - - case 1: - record.get().mInventory.mList.at(subRowIndex).mCount = value.toInt(); - break; - - default: - throw std::logic_error("Trying to access non-existing column in the nested table!"); - } + { + mHelper.setNestedData(column, data, index, value, subRowIndex, subColIndex); } else { assert(false); From c018ca43ac1f00b4ece1215f0776b069941f71ce Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 21 Jul 2014 14:44:48 +0200 Subject: [PATCH 062/185] getting rid of the asserts --- apps/opencs/model/world/refidadapterimp.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 3600562d39..f85138d97c 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -223,7 +223,10 @@ QVariant CSMWorld::ContainerRefIdAdapter::getData (const RefIdColumn *column, co void CSMWorld::ContainerRefIdAdapter::removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, int rowToRemove) const { - assert(column==mContent); + if(column!=mContent) + { + throw std::logic_error("This column does not hold multiple values."); + } std::vector& list = static_cast&> ( data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))).get().mInventory.mList; @@ -289,7 +292,7 @@ void CSMWorld::ContainerRefIdAdapter::setNestedData(const RefIdColumn *column, mHelper.setNestedData(column, data, index, value, subRowIndex, subColIndex); } else { - assert(false); + throw std::logic_error("This column do not nest other columns"); } } @@ -319,7 +322,7 @@ QVariant CSMWorld::ContainerRefIdAdapter::getNestedData (const CSMWorld::RefIdCo return mHelper.getNestedData(column, data, index, subRowIndex, subColIndex); } else { - throw std::logic_error("This column does not hold multiple values."); + throw std::logic_error("This column do not nest other columns"); } } From 427d6efd1904a1b574f2566114c32e6147468871 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 21 Jul 2014 14:49:47 +0200 Subject: [PATCH 063/185] Moved removeNestedRow responsibility to the helper. --- apps/opencs/model/world/nestedadaptors.hpp | 7 +++++++ apps/opencs/model/world/refidadapterimp.cpp | 6 +----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/apps/opencs/model/world/nestedadaptors.hpp b/apps/opencs/model/world/nestedadaptors.hpp index 8f82482d85..a961d19e46 100644 --- a/apps/opencs/model/world/nestedadaptors.hpp +++ b/apps/opencs/model/world/nestedadaptors.hpp @@ -61,6 +61,13 @@ namespace CSMWorld } } + void removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, int rowToRemove) const + { + std::vector& list = getRecord(data, index).get().mInventory.mList; + + list.erase (list.begin () + rowToRemove); + } + void setNestedData (const RefIdColumn *column, RefIdData& data, int index, diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index f85138d97c..2a8fec01d6 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -227,11 +227,7 @@ void CSMWorld::ContainerRefIdAdapter::removeNestedRow (const RefIdColumn *column { throw std::logic_error("This column does not hold multiple values."); } - - std::vector& list = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))).get().mInventory.mList; - - list.erase (list.begin () + rowToRemove); + mHelper.removeNestedRow(column, data, index, rowToRemove); } void CSMWorld::ContainerRefIdAdapter::addNestedRow (const RefIdColumn *column, RefIdData& data, int index, int position) const From dcd90faaef82820d738f34976f7a57daf0907056 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 21 Jul 2014 14:58:45 +0200 Subject: [PATCH 064/185] moved add nested to the helper --- apps/opencs/model/world/nestedadaptors.hpp | 14 ++++++++++++++ apps/opencs/model/world/refidadapterimp.cpp | 15 +++------------ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/apps/opencs/model/world/nestedadaptors.hpp b/apps/opencs/model/world/nestedadaptors.hpp index a961d19e46..9e747164a4 100644 --- a/apps/opencs/model/world/nestedadaptors.hpp +++ b/apps/opencs/model/world/nestedadaptors.hpp @@ -90,6 +90,20 @@ namespace CSMWorld } } + void addNestedRow (const RefIdColumn *column, RefIdData& data, int index, int position) const + { + std::vector& list = getRecord(data, index).get().mInventory.mList; + + ESM::ContItem newRow = {0, ""}; + if (position >= (int)list.size()) + { + list.push_back(newRow); + return; + } + + list.insert(list.begin()+position, newRow); + } + private: const Record& getRecord(const RefIdData& data, int index) const diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 2a8fec01d6..5681b8bae8 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -232,21 +232,12 @@ void CSMWorld::ContainerRefIdAdapter::removeNestedRow (const RefIdColumn *column void CSMWorld::ContainerRefIdAdapter::addNestedRow (const RefIdColumn *column, RefIdData& data, int index, int position) const { - assert(column==mContent); - - std::vector& list = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))).get().mInventory.mList; - - ESM::ContItem newRow = {0, ""}; - if (position >= (int)list.size()) + if(column!=mContent) { - list.push_back(newRow); - return; + throw std::logic_error("This column does not hold multiple values."); } - list.insert(list.begin()+position, newRow); - - return; + mHelper.addNestedRow(column, data, index, position); } void CSMWorld::ContainerRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, From 24eb034ba357f6aa93f944d38a0f948e0bb1d4ad Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 22 Jul 2014 10:27:45 +0200 Subject: [PATCH 065/185] major refactorisation --- apps/opencs/model/world/nestedadaptors.cpp | 7 ++ apps/opencs/model/world/nestedadaptors.hpp | 93 ++++++++++++++++----- apps/opencs/model/world/refidadapter.cpp | 84 ++++++++++++++++++- apps/opencs/model/world/refidadapter.hpp | 45 +++++++++- apps/opencs/model/world/refidadapterimp.cpp | 93 ++------------------- apps/opencs/model/world/refidadapterimp.hpp | 20 ----- 6 files changed, 210 insertions(+), 132 deletions(-) diff --git a/apps/opencs/model/world/nestedadaptors.cpp b/apps/opencs/model/world/nestedadaptors.cpp index 8ed1819b8f..1e8425229a 100644 --- a/apps/opencs/model/world/nestedadaptors.cpp +++ b/apps/opencs/model/world/nestedadaptors.cpp @@ -1 +1,8 @@ #include "nestedadaptors.hpp" + +CSMWorld::HelperBase::HelperBase(CSMWorld::UniversalId::Type type) + : mType(type) +{} + +CSMWorld::HelperBase::~HelperBase() +{} diff --git a/apps/opencs/model/world/nestedadaptors.hpp b/apps/opencs/model/world/nestedadaptors.hpp index 9e747164a4..806dc587de 100644 --- a/apps/opencs/model/world/nestedadaptors.hpp +++ b/apps/opencs/model/world/nestedadaptors.hpp @@ -6,45 +6,85 @@ #include "universalid.hpp" #include "nestedtablewrapper.hpp" -#include #include "record.hpp" #include "refiddata.hpp" #include "refidadapter.hpp" +#include #include namespace CSMWorld { - template - class InventoryHelper + class RefIdColumn; + + class HelperBase { - CSMWorld::UniversalId::Type mType; + protected: + const CSMWorld::UniversalId::Type mType; public: + HelperBase(CSMWorld::UniversalId::Type type); + + virtual ~HelperBase(); + + virtual void setNestedTable(RefIdData& data, + int index, + const NestedTableWrapperBase& nestedTable) = 0; + + virtual NestedTableWrapperBase* nestedTable(const RefIdData& data, + int index) const = 0; + + virtual QVariant getNestedData(const CSMWorld::RefIdData& data, + int index, + int subRowIndex, + int subColIndex) const = 0; - InventoryHelper(CSMWorld::UniversalId::Type type) : mType(type) {}; + virtual void removeNestedRow (RefIdData& data, + int index, + int rowToRemove) const = 0; - void setNestedTable(const RefIdColumn* column, - RefIdData& data, - int index, - const NestedTableWrapperBase& nestedTable) + virtual void setNestedData (RefIdData& data, + int index, + const QVariant& value, + int subRowIndex, + int subColIndex) const = 0; + + virtual void addNestedRow (RefIdData& data, + int index, + int position) const = 0; + + virtual int getNestedColumnsCount(const RefIdData& data) const = 0; + + virtual int getNestedRowsCount(const RefIdData& data, + int index) const = 0; + }; + + template + class InventoryHelper : public HelperBase + { + public: + + InventoryHelper(CSMWorld::UniversalId::Type type) + : HelperBase(type) {} + + virtual void setNestedTable(RefIdData& data, + int index, + const NestedTableWrapperBase& nestedTable) { getRecord(data, index).get().mInventory.mList = (static_cast >&>(nestedTable)).mNestedTable; } - NestedTableWrapperBase* nestedTable(const RefIdColumn* column, - const RefIdData& data, - int index) const + virtual NestedTableWrapperBase* nestedTable(const RefIdData& data, + int index) const { return new NestedTableWrapper >(getRecord(data, index).get().mInventory.mList); } - QVariant getNestedData(const CSMWorld::RefIdColumn* column, - const CSMWorld::RefIdData& data, - int index, - int subRowIndex, - int subColIndex) const + virtual QVariant getNestedData(const CSMWorld::RefIdData& data, + int index, + int subRowIndex, + int subColIndex) const { const ESM::ContItem& content = getRecord(data, index).get().mInventory.mList.at(subRowIndex); @@ -61,15 +101,14 @@ namespace CSMWorld } } - void removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, int rowToRemove) const + virtual void removeNestedRow (RefIdData& data, int index, int rowToRemove) const { std::vector& list = getRecord(data, index).get().mInventory.mList; list.erase (list.begin () + rowToRemove); } - void setNestedData (const RefIdColumn *column, - RefIdData& data, + void setNestedData (RefIdData& data, int index, const QVariant& value, int subRowIndex, @@ -90,7 +129,7 @@ namespace CSMWorld } } - void addNestedRow (const RefIdColumn *column, RefIdData& data, int index, int position) const + virtual void addNestedRow (RefIdData& data, int index, int position) const { std::vector& list = getRecord(data, index).get().mInventory.mList; @@ -104,6 +143,18 @@ namespace CSMWorld list.insert(list.begin()+position, newRow); } + virtual int getNestedColumnsCount(const RefIdData& data) const + { + return 2; + } + + + virtual int getNestedRowsCount(const RefIdData& data, + int index) const + { + return getRecord(data, index).get().mInventory.mList.size(); + } + private: const Record& getRecord(const RefIdData& data, int index) const diff --git a/apps/opencs/model/world/refidadapter.cpp b/apps/opencs/model/world/refidadapter.cpp index 50314e7a26..631c192fd0 100644 --- a/apps/opencs/model/world/refidadapter.cpp +++ b/apps/opencs/model/world/refidadapter.cpp @@ -1,13 +1,89 @@ - #include "refidadapter.hpp" -#include "cassert" +#include "nestedtablewrapper.hpp" + #include CSMWorld::RefIdAdapter::RefIdAdapter() {} CSMWorld::RefIdAdapter::~RefIdAdapter() {} -CSMWorld::NestedRefIdAdapter::NestedRefIdAdapter() {} +CSMWorld::NestedRefIdAdapterBase::NestedRefIdAdapterBase() {} -CSMWorld::NestedRefIdAdapter::~NestedRefIdAdapter() {} \ No newline at end of file +CSMWorld::NestedRefIdAdapterBase::~NestedRefIdAdapterBase() {} + +CSMWorld::NestedRefIdAdapter::NestedRefIdAdapter() +{} + +CSMWorld::NestedRefIdAdapter::~NestedRefIdAdapter() +{ + for (unsigned i = 0; i < mAssociatedColumns.size(); ++i) + { + delete mAssociatedColumns[i].second; + } +} + +void CSMWorld::NestedRefIdAdapter::setNestedData (const RefIdColumn *column, RefIdData& data, int row, + const QVariant& value, int subRowIndex, int subColIndex) const +{ + getHelper(column)->setNestedData(data, row, value, subRowIndex, subColIndex); +} + +QVariant CSMWorld::NestedRefIdAdapter::getNestedData(const RefIdColumn *column, const RefIdData& data, + int index, int subRowIndex, int subColIndex) const +{ + return getHelper(column)->getNestedData(data, index, subRowIndex, subColIndex); +} + +int CSMWorld::NestedRefIdAdapter::getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const +{ + return getHelper(column)->getNestedColumnsCount(data); +} + + +int CSMWorld::NestedRefIdAdapter::getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const +{ + return getHelper(column)->getNestedRowsCount(data, index); +} + + +void CSMWorld::NestedRefIdAdapter::removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, int rowToRemove) const +{ + getHelper(column)->removeNestedRow(data, index, rowToRemove); +} + +void CSMWorld::NestedRefIdAdapter::addNestedRow (const RefIdColumn *column, RefIdData& data, int index, int position) const +{ + getHelper(column)->addNestedRow(data, index, position); //This code grows more boring and boring. I would love some macros. +} + +void CSMWorld::NestedRefIdAdapter::setNestedTable (const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) +{ + getHelper(column)->setNestedTable(data, index, nestedTable); +} + + +CSMWorld::NestedTableWrapperBase* CSMWorld::NestedRefIdAdapter::nestedTable (const RefIdColumn* column, const RefIdData& data, int index) const +{ + return getHelper(column)->nestedTable(data, index); +} + +CSMWorld::HelperBase* CSMWorld::NestedRefIdAdapter::getHelper(const RefIdColumn *column) const +{ + for (unsigned i = 0; i < mAssociatedColumns.size(); ++i) + { + if (mAssociatedColumns[i].first == column) + { + return mAssociatedColumns[i].second; + } + } + + throw std::logic_error("No such column in the nestedrefidadapter"); + + return NULL; +} + +void CSMWorld::NestedRefIdAdapter::setAssocColumns(const std::vector >& assocColumns) +{ + mAssociatedColumns = assocColumns; +} diff --git a/apps/opencs/model/world/refidadapter.hpp b/apps/opencs/model/world/refidadapter.hpp index f7064ab66e..dd2248e925 100644 --- a/apps/opencs/model/world/refidadapter.hpp +++ b/apps/opencs/model/world/refidadapter.hpp @@ -2,6 +2,9 @@ #define CSM_WOLRD_REFIDADAPTER_H #include +#include + +#include "nestedadaptors.hpp" class QVariant; @@ -11,6 +14,7 @@ namespace CSMWorld class RefIdData; class RecordBase; class NestedTableWrapperBase; + class HelperBase; class RefIdAdapter { @@ -36,12 +40,12 @@ namespace CSMWorld virtual void setId(RecordBase& record, const std::string& id) = 0; }; - class NestedRefIdAdapter + class NestedRefIdAdapterBase { public: - NestedRefIdAdapter(); + NestedRefIdAdapterBase(); - virtual ~NestedRefIdAdapter(); + virtual ~NestedRefIdAdapterBase(); virtual void setNestedData (const RefIdColumn *column, RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const = 0; @@ -61,6 +65,41 @@ namespace CSMWorld virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, const RefIdData& data, int index) const = 0; }; + + class NestedRefIdAdapter : public NestedRefIdAdapterBase + { + std::vector > mAssociatedColumns; //basicly, i wanted map, but with pointer key + + public: + NestedRefIdAdapter(); + + virtual ~NestedRefIdAdapter(); + + virtual void setNestedData (const RefIdColumn *column, RefIdData& data, int row, + const QVariant& value, int subRowIndex, int subColIndex) const; + + virtual QVariant getNestedData (const RefIdColumn *column, const RefIdData& data, + int index, int subRowIndex, int subColIndex) const; + + virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const; + + virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const; + + virtual void removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, int rowToRemove) const; + + virtual void addNestedRow (const RefIdColumn *column, RefIdData& data, int index, int position) const; + + virtual void setNestedTable (const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable); + + virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, const RefIdData& data, int index) const; + + protected: + void setAssocColumns(const std::vector >& assocColumns); + + private: + + HelperBase* getHelper(const RefIdColumn *column) const; + }; } #endif diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 5681b8bae8..18287d596e 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include "nestedtablewrapper.hpp" @@ -180,28 +181,18 @@ void CSMWorld::ClothingRefIdAdapter::setData (const RefIdColumn *column, RefIdDa CSMWorld::ContainerRefIdAdapter::ContainerRefIdAdapter (const NameColumns& columns, const RefIdColumn *weight, const RefIdColumn *organic, const RefIdColumn *respawn, const RefIdColumn *content) : NameRefIdAdapter (UniversalId::Type_Container, columns), mWeight (weight), - mOrganic (organic), mRespawn (respawn), mContent(content), mHelper(InventoryHelper(UniversalId::Type_Container)) -{} - -int CSMWorld::ContainerRefIdAdapter::getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const + mOrganic (organic), mRespawn (respawn), mContent(content) { - assert(column==mContent); + std::vector > assoCol; - return 2; + assoCol.push_back(std::make_pair(content, new InventoryHelper(UniversalId::Type_Container))); + + setAssocColumns(assoCol); } -int CSMWorld::ContainerRefIdAdapter::getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const -{ - assert(column==mContent); - - const Record& record = static_cast&> ( - data.getRecord(RefIdData::LocalIndex (index, UniversalId::Type_Container))); - - return record.get().mInventory.mList.size(); -} - -QVariant CSMWorld::ContainerRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, - int index) const +QVariant CSMWorld::ContainerRefIdAdapter::getData (const RefIdColumn *column, + const RefIdData& data, + int index) const { const Record& record = static_cast&> ( data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))); @@ -221,24 +212,6 @@ QVariant CSMWorld::ContainerRefIdAdapter::getData (const RefIdColumn *column, co return NameRefIdAdapter::getData (column, data, index); } -void CSMWorld::ContainerRefIdAdapter::removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, int rowToRemove) const -{ - if(column!=mContent) - { - throw std::logic_error("This column does not hold multiple values."); - } - mHelper.removeNestedRow(column, data, index, rowToRemove); -} - -void CSMWorld::ContainerRefIdAdapter::addNestedRow (const RefIdColumn *column, RefIdData& data, int index, int position) const -{ - if(column!=mContent) - { - throw std::logic_error("This column does not hold multiple values."); - } - - mHelper.addNestedRow(column, data, index, position); -} void CSMWorld::ContainerRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, const QVariant& value) const @@ -266,54 +239,6 @@ void CSMWorld::ContainerRefIdAdapter::setData (const RefIdColumn *column, RefIdD NameRefIdAdapter::setData (column, data, index, value); } -void CSMWorld::ContainerRefIdAdapter::setNestedData(const RefIdColumn *column, - RefIdData& data, - int index, - const QVariant& value, - int subRowIndex, - int subColIndex) const -{ - - if (column==mContent) - { - mHelper.setNestedData(column, data, index, value, subRowIndex, subColIndex); - } else - { - throw std::logic_error("This column do not nest other columns"); - } -} - -void CSMWorld::ContainerRefIdAdapter::setNestedTable(const RefIdColumn* column, - RefIdData& data, - int index, - const NestedTableWrapperBase& nestedTable) -{ - mHelper.setNestedTable(column, data, index, nestedTable); -} - -CSMWorld::NestedTableWrapperBase* CSMWorld::ContainerRefIdAdapter::nestedTable (const RefIdColumn* column, - const RefIdData& data, - int index) const -{ - return mHelper.nestedTable(column, data, index); -} - -QVariant CSMWorld::ContainerRefIdAdapter::getNestedData (const CSMWorld::RefIdColumn* column, - const CSMWorld::RefIdData& data, - int index, - int subRowIndex, - int subColIndex) const -{ - if (column==mContent) - { - return mHelper.getNestedData(column, data, index, subRowIndex, subColIndex); - } else - { - throw std::logic_error("This column do not nest other columns"); - } -} - - CSMWorld::CreatureColumns::CreatureColumns (const ActorColumns& actorColumns) : ActorColumns (actorColumns) {} diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index aac2ba8073..ee069dd380 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -616,36 +616,16 @@ namespace CSMWorld const RefIdColumn *mRespawn; const RefIdColumn *mContent; - InventoryHelper mHelper; - public: ContainerRefIdAdapter (const NameColumns& columns, const RefIdColumn *weight, const RefIdColumn *organic, const RefIdColumn *respawn, const RefIdColumn *content); - virtual QVariant getNestedData (const RefIdColumn *column, const RefIdData& data, int index, - int subRowIndex, int subColIndex) const; - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) const; - virtual void setNestedData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value, int subRowIndex, int subColIndex) const; - virtual void setData (const RefIdColumn *column, RefIdData& data, int index, const QVariant& value) const; ///< If the data type does not match an exception is thrown. - - virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const; - - virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const; - - virtual void removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, int rowToRemove) const; - - virtual void addNestedRow (const RefIdColumn *column, RefIdData& data, int index, int position) const; - - virtual NestedTableWrapperBase* nestedTable (const RefIdColumn * column, const RefIdData& data, int index) const; - - virtual void setNestedTable (const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable); }; struct CreatureColumns : public ActorColumns From 9defb188ea83a9de4edba735f688a15dc1329e65 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 22 Jul 2014 13:08:32 +0200 Subject: [PATCH 066/185] handle inventory in the actors --- apps/opencs/model/world/columns.hpp | 1 + apps/opencs/model/world/refidadapterimp.hpp | 14 ++++++++++++-- apps/opencs/model/world/refidcollection.cpp | 4 ++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 283e15db76..6812bbae97 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -179,6 +179,7 @@ namespace CSMWorld ColumnId_Vampire = 164, ColumnId_BodyPartType = 165, ColumnId_MeshType = 166, + ColumnId_ActorInventory = 167, // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index ee069dd380..6fe479150b 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -445,6 +445,7 @@ namespace CSMWorld const RefIdColumn *mFlee; const RefIdColumn *mFight; const RefIdColumn *mAlarm; + const RefIdColumn *mInventory; std::map mServices; ActorColumns (const NameColumns& base) : NameColumns (base) {} @@ -452,7 +453,7 @@ namespace CSMWorld /// \brief Adapter for actor IDs (handles common AI functionality) template - class ActorRefIdAdapter : public NameRefIdAdapter + class ActorRefIdAdapter : public NameRefIdAdapter, public NestedRefIdAdapter { ActorColumns mActors; @@ -472,7 +473,13 @@ namespace CSMWorld ActorRefIdAdapter::ActorRefIdAdapter (UniversalId::Type type, const ActorColumns& columns) : NameRefIdAdapter (type, columns), mActors (columns) - {} + { + std::vector > assoCol; + + assoCol.push_back(std::make_pair(mActors.mInventory, new InventoryHelper(type))); + + setAssocColumns(assoCol); + } template QVariant ActorRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, @@ -496,6 +503,9 @@ namespace CSMWorld if (column==mActors.mAlarm) return record.get().mAiData.mAlarm; + if (column==mActors.mInventory) + return true; + std::map::const_iterator iter = mActors.mServices.find (column); diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 80ac1cc3b1..493b716eb3 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -99,6 +99,10 @@ CSMWorld::RefIdCollection::RefIdCollection() actorsColumns.mFight = &mColumns.back(); mColumns.push_back (RefIdColumn (Columns::ColumnId_AiAlarm, ColumnBase::Display_Integer)); actorsColumns.mAlarm = &mColumns.back(); + mColumns.push_back(RefIdColumn (Columns::ColumnId_ActorInventory, ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue, true, true, true)); + actorsColumns.mInventory = &mColumns.back(); + mColumns.back().addNestedColumn(Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String); + mColumns.back().addNestedColumn(Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer); static const struct { From 72b129b90e662c10df1d756ea0875197bb517523 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 22 Jul 2014 17:44:56 +0200 Subject: [PATCH 067/185] Code shuffling. Created CastableHelper to store actually usefull function. --- apps/opencs/model/world/nestedadaptors.hpp | 55 +++++++++++++--------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/apps/opencs/model/world/nestedadaptors.hpp b/apps/opencs/model/world/nestedadaptors.hpp index 806dc587de..3807f02191 100644 --- a/apps/opencs/model/world/nestedadaptors.hpp +++ b/apps/opencs/model/world/nestedadaptors.hpp @@ -60,25 +60,47 @@ namespace CSMWorld }; template - class InventoryHelper : public HelperBase + class CastableHelper : public HelperBase + { + + public: + CastableHelper(CSMWorld::UniversalId::Type type) + : HelperBase(type) {} + + protected: + const Record& getRecord(const RefIdData& data, int index) const + { + return dynamic_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, mType))); + } + + Record& getRecord(RefIdData& data, int index) const + { + return dynamic_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, mType))); + } + }; + + template + class InventoryHelper : public CastableHelper { public: InventoryHelper(CSMWorld::UniversalId::Type type) - : HelperBase(type) {} + : CastableHelper(type) {} virtual void setNestedTable(RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) { - getRecord(data, index).get().mInventory.mList = + CastableHelper::getRecord(data, index).get().mInventory.mList = (static_cast >&>(nestedTable)).mNestedTable; } virtual NestedTableWrapperBase* nestedTable(const RefIdData& data, int index) const { - return new NestedTableWrapper >(getRecord(data, index).get().mInventory.mList); + return new NestedTableWrapper >(CastableHelper::getRecord(data, index).get().mInventory.mList); } virtual QVariant getNestedData(const CSMWorld::RefIdData& data, @@ -86,7 +108,7 @@ namespace CSMWorld int subRowIndex, int subColIndex) const { - const ESM::ContItem& content = getRecord(data, index).get().mInventory.mList.at(subRowIndex); + const ESM::ContItem& content = CastableHelper::getRecord(data, index).get().mInventory.mList.at(subRowIndex); switch (subColIndex) { @@ -103,7 +125,7 @@ namespace CSMWorld virtual void removeNestedRow (RefIdData& data, int index, int rowToRemove) const { - std::vector& list = getRecord(data, index).get().mInventory.mList; + std::vector& list = CastableHelper::getRecord(data, index).get().mInventory.mList; list.erase (list.begin () + rowToRemove); } @@ -117,11 +139,11 @@ namespace CSMWorld switch(subColIndex) { case 0: - getRecord(data, index).get().mInventory.mList.at(subRowIndex).mItem.assign(std::string(value.toString().toUtf8().constData())); + CastableHelper::getRecord(data, index).get().mInventory.mList.at(subRowIndex).mItem.assign(std::string(value.toString().toUtf8().constData())); break; case 1: - getRecord(data, index).get().mInventory.mList.at(subRowIndex).mCount = value.toInt(); + CastableHelper::getRecord(data, index).get().mInventory.mList.at(subRowIndex).mCount = value.toInt(); break; default: @@ -131,7 +153,7 @@ namespace CSMWorld virtual void addNestedRow (RefIdData& data, int index, int position) const { - std::vector& list = getRecord(data, index).get().mInventory.mList; + std::vector& list = CastableHelper::getRecord(data, index).get().mInventory.mList; ESM::ContItem newRow = {0, ""}; if (position >= (int)list.size()) @@ -152,22 +174,9 @@ namespace CSMWorld virtual int getNestedRowsCount(const RefIdData& data, int index) const { - return getRecord(data, index).get().mInventory.mList.size(); + return CastableHelper::getRecord(data, index).get().mInventory.mList.size(); } - private: - - const Record& getRecord(const RefIdData& data, int index) const - { - return dynamic_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, mType))); - } - - Record& getRecord(RefIdData& data, int index) const - { - return dynamic_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, mType))); - } }; } From a676f6bc2cad308e924e2a32b3f51e679d99c4f6 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 23 Jul 2014 20:33:52 +0200 Subject: [PATCH 068/185] comments added --- apps/opencs/model/world/nestedadaptors.hpp | 4 ++++ apps/opencs/model/world/refidadapter.hpp | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/apps/opencs/model/world/nestedadaptors.hpp b/apps/opencs/model/world/nestedadaptors.hpp index 3807f02191..0bb998316f 100644 --- a/apps/opencs/model/world/nestedadaptors.hpp +++ b/apps/opencs/model/world/nestedadaptors.hpp @@ -13,6 +13,10 @@ #include +/*! \brief + * Nested adapter redirects responsibility to the helper class. Helper classes are polymorhpic (vide HelperBase and CastableHelper) and most likely templates. + */ + namespace CSMWorld { class RefIdColumn; diff --git a/apps/opencs/model/world/refidadapter.hpp b/apps/opencs/model/world/refidadapter.hpp index dd2248e925..22941fd9f5 100644 --- a/apps/opencs/model/world/refidadapter.hpp +++ b/apps/opencs/model/world/refidadapter.hpp @@ -6,6 +6,12 @@ #include "nestedadaptors.hpp" +/*! \brief + * Adaptors acts as indirection layer, abstracting details of the record types (in the wrappers) from the higher levels of model. + * Please notice that nested adaptor uses helper classes for actually performing any actions. Different record types require different helpers (needs to be created in the subclass and then fetched via member function). + * Important point: don't forget to make sure that getData on the nestedColumn returns true (otherwise code will not treat the index pointing to the column as having childs! + */ + class QVariant; namespace CSMWorld @@ -30,6 +36,7 @@ namespace CSMWorld virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int idnex) const = 0; + ///< If called on the nest column, should return QVariant(true). virtual void setData (const RefIdColumn *column, RefIdData& data, int index, const QVariant& value) const = 0; @@ -95,6 +102,9 @@ namespace CSMWorld protected: void setAssocColumns(const std::vector >& assocColumns); + ///The ownership of the Helper pointers is transfered. + ///The ownership of the column pointers it not transfered (it is not surprising, since columns are created by collection). + ///You MUST call this method to setup the nested adaptor! private: From 864b93e745fd9072b9810c82c866e7fb3e1210b4 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 25 Jul 2014 11:25:36 +0200 Subject: [PATCH 069/185] added enums for spells --- apps/opencs/model/world/columns.cpp | 1 + apps/opencs/model/world/columns.hpp | 2 ++ apps/opencs/model/world/refidadapterimp.hpp | 1 + apps/opencs/model/world/refidcollection.cpp | 4 ++++ 4 files changed, 8 insertions(+) diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 83d0ccc79f..1f13645da1 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -175,6 +175,7 @@ namespace CSMWorld { ColumnId_Scope, "Scope" }, { ColumnId_ReferenceableId, "Referenceable ID" }, { ColumnId_InventoryItemId, "ID"}, + { ColumnId_SpellId, "ID"}, { ColumnId_ItemCount, "Count"}, { ColumnId_CombatState, "Combat" }, { ColumnId_MagicState, "Magic" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 6812bbae97..908165e9d9 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -180,6 +180,8 @@ namespace CSMWorld ColumnId_BodyPartType = 165, ColumnId_MeshType = 166, ColumnId_ActorInventory = 167, + ColumnId_ActorSpells = 168, + ColumnId_SpellId = 169, // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 6fe479150b..ee2a586243 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -446,6 +446,7 @@ namespace CSMWorld const RefIdColumn *mFight; const RefIdColumn *mAlarm; const RefIdColumn *mInventory; + const RefIdColumn *mSpells; std::map mServices; ActorColumns (const NameColumns& base) : NameColumns (base) {} diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 493b716eb3..89469feac3 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -104,6 +104,10 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.back().addNestedColumn(Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String); mColumns.back().addNestedColumn(Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer); + mColumns.push_back(RefIdColumn (Columns::ColumnId_ActorSpells, ColumnBase::Display_NestedSpellList, ColumnBase::Flag_Dialogue, true, true, true)); + actorsColumns.mSpells = &mColumns.back(); + mColumns.back().addNestedColumn(Columns::ColumnId_SpellId, CSMWorld::ColumnBase::Display_String); + static const struct { int mName; From 39545670a887fb29266964e6c4506dd2a1cc2c02 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 25 Jul 2014 12:09:25 +0200 Subject: [PATCH 070/185] Added spells table (and it works!) --- apps/opencs/model/world/columnbase.hpp | 1 + apps/opencs/model/world/nestedadaptors.hpp | 87 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 4 + apps/opencs/model/world/refidcollection.cpp | 4 +- 4 files changed, 94 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 096491f1ec..5e4dac3ce0 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -94,6 +94,7 @@ namespace CSMWorld //Those are top level columns that nest other columns Display_NestedItemList, + Display_NestedSpellList, Display_EnchantmentType, Display_BodyPartType, diff --git a/apps/opencs/model/world/nestedadaptors.hpp b/apps/opencs/model/world/nestedadaptors.hpp index 0bb998316f..095bcdf951 100644 --- a/apps/opencs/model/world/nestedadaptors.hpp +++ b/apps/opencs/model/world/nestedadaptors.hpp @@ -2,6 +2,7 @@ #define CSM_WORLD_NESTEDADAPTORS_H #include +#include #include #include "universalid.hpp" @@ -85,6 +86,92 @@ namespace CSMWorld } }; + template + class SpellsHelper : public CastableHelper + { + public: + + SpellsHelper(CSMWorld::UniversalId::Type type) + : CastableHelper(type) {} + + virtual void setNestedTable(RefIdData& data, + int index, + const NestedTableWrapperBase& nestedTable) + { + CastableHelper::getRecord(data, index).get().mSpells.mList = + (static_cast >&>(nestedTable)).mNestedTable; + } + + virtual NestedTableWrapperBase* nestedTable(const RefIdData& data, + int index) const + { + return new NestedTableWrapper >(CastableHelper::getRecord(data, index).get().mSpells.mList); + } + + virtual QVariant getNestedData(const CSMWorld::RefIdData& data, + int index, + int subRowIndex, + int subColIndex) const + { + const std::string& content = CastableHelper::getRecord(data, index).get().mSpells.mList.at(subRowIndex); + + if (subColIndex == 0) + { + return QString::fromUtf8(content.c_str()); + } + + throw std::logic_error("Trying to access non-existing column in the nested table!"); + } + + virtual void removeNestedRow (RefIdData& data, int index, int rowToRemove) const + { + std::vector& list = CastableHelper::getRecord(data, index).get().mSpells.mList; + + list.erase (list.begin () + rowToRemove); + } + + void setNestedData (RefIdData& data, + int index, + const QVariant& value, + int subRowIndex, + int subColIndex) const + { + if (subColIndex == 0) + { + CastableHelper::getRecord(data, index).get().mSpells.mList.at(subRowIndex) = std::string(value.toString().toUtf8()); + } + + throw std::logic_error("Trying to access non-existing column in the nested table!"); + } + + virtual void addNestedRow (RefIdData& data, int index, int position) const + { + std::vector& list = CastableHelper::getRecord(data, index).get().mSpells.mList; + + std::string newString; + if (position >= (int)list.size()) + { + list.push_back(newString); + return; + } + + list.insert(list.begin()+position, newString); + } + + virtual int getNestedColumnsCount(const RefIdData& data) const + { + return 1; + } + + + virtual int getNestedRowsCount(const RefIdData& data, + int index) const + { + return CastableHelper::getRecord(data, index).get().mSpells.mList.size(); + } + + }; + template class InventoryHelper : public CastableHelper { diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index ee2a586243..4c65da85c4 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -478,6 +478,7 @@ namespace CSMWorld std::vector > assoCol; assoCol.push_back(std::make_pair(mActors.mInventory, new InventoryHelper(type))); + assoCol.push_back(std::make_pair(mActors.mSpells, new SpellsHelper(type))); setAssocColumns(assoCol); } @@ -507,6 +508,9 @@ namespace CSMWorld if (column==mActors.mInventory) return true; + if (column==mActors.mSpells) + return true; + std::map::const_iterator iter = mActors.mServices.find (column); diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 89469feac3..eb25b277e9 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -1,4 +1,3 @@ - #include "refidcollection.hpp" #include @@ -99,6 +98,7 @@ CSMWorld::RefIdCollection::RefIdCollection() actorsColumns.mFight = &mColumns.back(); mColumns.push_back (RefIdColumn (Columns::ColumnId_AiAlarm, ColumnBase::Display_Integer)); actorsColumns.mAlarm = &mColumns.back(); + mColumns.push_back(RefIdColumn (Columns::ColumnId_ActorInventory, ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue, true, true, true)); actorsColumns.mInventory = &mColumns.back(); mColumns.back().addNestedColumn(Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String); @@ -665,6 +665,6 @@ CSMWorld::NestedTableWrapperBase* CSMWorld::RefIdCollection::nestedTable(int row RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdaptor (localIndex.second)); - + return adaptor.nestedTable(&mColumns.at(column), mData, localIndex.first); } From ade27293be7cd76163c917602c8d092925623367 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 25 Jul 2014 17:11:18 +0200 Subject: [PATCH 071/185] handling destination for guides --- apps/opencs/model/world/columnbase.hpp | 1 + apps/opencs/model/world/columns.cpp | 9 ++ apps/opencs/model/world/columns.hpp | 8 ++ apps/opencs/model/world/nestedadaptors.hpp | 145 ++++++++++++++++++++ apps/opencs/model/world/refidadapter.cpp | 5 + apps/opencs/model/world/refidadapter.hpp | 3 + apps/opencs/model/world/refidadapterimp.cpp | 9 +- apps/opencs/model/world/refidadapterimp.hpp | 1 + apps/opencs/model/world/refidcollection.cpp | 10 ++ 9 files changed, 189 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 5e4dac3ce0..05fecaec0d 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -95,6 +95,7 @@ namespace CSMWorld //Those are top level columns that nest other columns Display_NestedItemList, Display_NestedSpellList, + Display_NestedDestinationsList, Display_EnchantmentType, Display_BodyPartType, diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 1f13645da1..2127724502 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -174,6 +174,7 @@ namespace CSMWorld { ColumnId_PcRank, "PC Rank" }, { ColumnId_Scope, "Scope" }, { ColumnId_ReferenceableId, "Referenceable ID" }, + { ColumnId_NpcDestinations, "Destinations" }, { ColumnId_InventoryItemId, "ID"}, { ColumnId_SpellId, "ID"}, { ColumnId_ItemCount, "Count"}, @@ -184,6 +185,14 @@ namespace CSMWorld { ColumnId_Vampire, "Vampire" }, { ColumnId_BodyPartType, "Bodypart Type" }, { ColumnId_MeshType, "Mesh Type" }, + + { ColumnId_NpcDestinations, "Cell"}, + { ColumnId_PosX, "X"}, + { ColumnId_PosY, "Y"}, + { ColumnId_PosZ, "Z"}, + { ColumnId_RotX, "Rotation X"}, + { ColumnId_RotY, "Rotation Y"}, + { ColumnId_RotZ, "Rotation Z"}, { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 908165e9d9..7efaf2bd0a 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -182,6 +182,14 @@ namespace CSMWorld ColumnId_ActorInventory = 167, ColumnId_ActorSpells = 168, ColumnId_SpellId = 169, + ColumnId_NpcDestinations = 170, + ColumnId_PosX = 171, + ColumnId_PosY = 172, + ColumnId_PosZ = 173, + ColumnId_RotX = 174, + ColumnId_RotY = 175, + ColumnId_RotZ = 176, + ColumnId_DestinationCell = 177, // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. diff --git a/apps/opencs/model/world/nestedadaptors.hpp b/apps/opencs/model/world/nestedadaptors.hpp index 095bcdf951..319fe1569e 100644 --- a/apps/opencs/model/world/nestedadaptors.hpp +++ b/apps/opencs/model/world/nestedadaptors.hpp @@ -11,6 +11,8 @@ #include "refiddata.hpp" #include "refidadapter.hpp" #include +#include +#include #include @@ -172,6 +174,149 @@ namespace CSMWorld }; + template + class DestinationsHelper : public CastableHelper + { + public: + + DestinationsHelper(CSMWorld::UniversalId::Type type) + : CastableHelper(type) {} + + virtual void setNestedTable(RefIdData& data, + int index, + const NestedTableWrapperBase& nestedTable) + { + CastableHelper::getRecord(data, index).get().mTransport = + (static_cast >&>(nestedTable)).mNestedTable; + } + + virtual NestedTableWrapperBase* nestedTable(const RefIdData& data, + int index) const + { + return new NestedTableWrapper >(CastableHelper::getRecord(data, index).get().mTransport); + } + + virtual QVariant getNestedData(const CSMWorld::RefIdData& data, + int index, + int subRowIndex, + int subColIndex) const + { + const ESM::NPC::Dest& content = CastableHelper::getRecord(data, index).get().mTransport.at(subRowIndex); + + switch (subColIndex) + { + case 0: + return QString::fromUtf8(content.mCellName.c_str()); + + case 1: + return content.mPos.pos[0]; + + case 2: + return content.mPos.pos[1]; + + case 3: + return content.mPos.pos[2]; + + case 4: + return content.mPos.rot[0]; + + case 5: + return content.mPos.rot[1]; + + case 6: + return content.mPos.rot[2]; + + default: + throw std::logic_error("Trying to access non-existing column in the nested table!"); + } + } + + virtual void removeNestedRow (RefIdData& data, int index, int rowToRemove) const + { + std::vector& list = CastableHelper::getRecord(data, index).get().mTransport; + + list.erase (list.begin () + rowToRemove); + } + + void setNestedData (RefIdData& data, + int index, + const QVariant& value, + int subRowIndex, + int subColIndex) const + { + switch(subColIndex) + { + case 0: + CastableHelper::getRecord(data, index).get().mTransport.at(subRowIndex).mCellName = std::string(value.toString().toUtf8().constData()); + break; + + case 1: + CastableHelper::getRecord(data, index).get().mTransport.at(subRowIndex).mPos.pos[0] = value.toFloat(); + break; + + case 2: + CastableHelper::getRecord(data, index).get().mTransport.at(subRowIndex).mPos.pos[1] = value.toFloat(); + break; + + case 3: + CastableHelper::getRecord(data, index).get().mTransport.at(subRowIndex).mPos.pos[2] = value.toFloat(); + break; + + case 4: + CastableHelper::getRecord(data, index).get().mTransport.at(subRowIndex).mPos.rot[0] = value.toFloat(); + break; + + case 5: + CastableHelper::getRecord(data, index).get().mTransport.at(subRowIndex).mPos.rot[1] = value.toFloat(); + break; + + case 6: + CastableHelper::getRecord(data, index).get().mTransport.at(subRowIndex).mPos.rot[2] = value.toFloat(); + break; + + default: + throw std::logic_error("Trying to access non-existing column in the nested table!"); + } + } + + virtual void addNestedRow (RefIdData& data, int index, int position) const + { + std::vector& list = CastableHelper::getRecord(data, index).get().mTransport; + + ESM::Position newPos; + for (unsigned i = 0; i < 3; ++i) + { + newPos.pos[i] = 0; + newPos.rot[i] = 0; + } + + ESM::NPC::Dest newRow; + newRow.mPos = newPos; + newRow.mCellName = ""; + + if (position >= (int)list.size()) + { + list.push_back(newRow); + return; + } + + list.insert(list.begin()+position, newRow); + } + + virtual int getNestedColumnsCount(const RefIdData& data) const + { + return 7; + } + + + virtual int getNestedRowsCount(const RefIdData& data, + int index) const + { + return CastableHelper::getRecord(data, index).get().mTransport.size(); + } + + }; + template class InventoryHelper : public CastableHelper { diff --git a/apps/opencs/model/world/refidadapter.cpp b/apps/opencs/model/world/refidadapter.cpp index 631c192fd0..58b775f47f 100644 --- a/apps/opencs/model/world/refidadapter.cpp +++ b/apps/opencs/model/world/refidadapter.cpp @@ -87,3 +87,8 @@ void CSMWorld::NestedRefIdAdapter::setAssocColumns(const std::vector& assocColumn) +{ + mAssociatedColumns.push_back(assocColumn); +} diff --git a/apps/opencs/model/world/refidadapter.hpp b/apps/opencs/model/world/refidadapter.hpp index 22941fd9f5..d18e7f02e7 100644 --- a/apps/opencs/model/world/refidadapter.hpp +++ b/apps/opencs/model/world/refidadapter.hpp @@ -106,6 +106,9 @@ namespace CSMWorld ///The ownership of the column pointers it not transfered (it is not surprising, since columns are created by collection). ///You MUST call this method to setup the nested adaptor! + void addAssocColumn(const std::pair & assocColumn); + ///Like setAssocColumn, when it is impossible to set all columns at once + private: HelperBase* getHelper(const RefIdColumn *column) const; diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 18287d596e..ac546db510 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -452,7 +452,9 @@ CSMWorld::NpcColumns::NpcColumns (const ActorColumns& actorColumns) : ActorColum CSMWorld::NpcRefIdAdapter::NpcRefIdAdapter (const NpcColumns& columns) : ActorRefIdAdapter (UniversalId::Type_Npc, columns), mColumns (columns) -{} +{ + NestedRefIdAdapter::addAssocColumn(std::make_pair(columns.mDestinations, new DestinationsHelper(UniversalId::Type_Npc))); +} QVariant CSMWorld::NpcRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, int index) const @@ -474,13 +476,16 @@ QVariant CSMWorld::NpcRefIdAdapter::getData (const RefIdColumn *column, const Re if (column==mColumns.mHead) return QString::fromUtf8 (record.get().mHead.c_str()); + + if (column==mColumns.mDestinations) + return true; std::map::const_iterator iter = mColumns.mFlags.find (column); if (iter!=mColumns.mFlags.end()) return (record.get().mFlags & iter->second)!=0; - + return ActorRefIdAdapter::getData (column, data, index); } diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 4c65da85c4..6fd42b00ec 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -742,6 +742,7 @@ namespace CSMWorld const RefIdColumn *mFaction; const RefIdColumn *mHair; const RefIdColumn *mHead; + const RefIdColumn *mDestinations; NpcColumns (const ActorColumns& actorColumns); }; diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index eb25b277e9..d776931f8f 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -315,6 +315,16 @@ CSMWorld::RefIdCollection::RefIdCollection() npcColumns.mFlags.insert (std::make_pair (metalBlood, ESM::NPC::Metal)); + mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcDestinations, ColumnBase::Display_NestedDestinationsList, ColumnBase::Flag_Dialogue, true, true, true)); + npcColumns.mDestinations = &mColumns.back(); + mColumns.back().addNestedColumn(Columns::ColumnId_DestinationCell, CSMWorld::ColumnBase::Display_String); + mColumns.back().addNestedColumn(Columns::ColumnId_PosX, CSMWorld::ColumnBase::Display_Float); + mColumns.back().addNestedColumn(Columns::ColumnId_PosY, CSMWorld::ColumnBase::Display_Float); + mColumns.back().addNestedColumn(Columns::ColumnId_PosZ, CSMWorld::ColumnBase::Display_Float); + mColumns.back().addNestedColumn(Columns::ColumnId_RotX, CSMWorld::ColumnBase::Display_Float); + mColumns.back().addNestedColumn(Columns::ColumnId_RotY, CSMWorld::ColumnBase::Display_Float); + mColumns.back().addNestedColumn(Columns::ColumnId_RotZ, CSMWorld::ColumnBase::Display_Float); + WeaponColumns weaponColumns (enchantableColumns); mColumns.push_back (RefIdColumn (Columns::ColumnId_WeaponType, ColumnBase::Display_WeaponType)); From 6a9c7c9f8699e852c0fc712cab5dec4f4ce49fb5 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 28 Jul 2014 17:33:21 +0200 Subject: [PATCH 072/185] fix for bug 1672 --- apps/opencs/model/doc/document.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 23a47b3130..644d32e846 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -1,6 +1,7 @@ #include "document.hpp" #include +#include #include @@ -2217,16 +2218,18 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, if (!boost::filesystem::exists (mProjectPath)) { - boost::filesystem::path locCustomFiltersPath (configuration.getUserDataPath()); - locCustomFiltersPath /= "defaultfilters"; + boost::filesystem::path customFiltersPath (configuration.getUserDataPath()); + customFiltersPath /= "defaultfilters"; + + std::string destinationPath = mProjectPath.string() + "/defaultfilters"; + std::ofstream dst(destinationPath.c_str(), std::ios::binary); - if (boost::filesystem::exists (locCustomFiltersPath)) + if (boost::filesystem::exists (customFiltersPath)) { - boost::filesystem::copy_file (locCustomFiltersPath, mProjectPath); - } - else + dst< Date: Wed, 30 Jul 2014 17:07:11 +0200 Subject: [PATCH 073/185] saving progress --- apps/opencs/model/doc/document.cpp | 4 +- apps/opencs/model/world/columns.cpp | 7 ++ apps/opencs/model/world/columns.hpp | 1 + apps/opencs/model/world/commands.cpp | 18 +-- apps/opencs/model/world/nestedadaptors.hpp | 128 ++++++++++++++++++++- apps/opencs/view/world/enumdelegate.cpp | 1 - 6 files changed, 148 insertions(+), 11 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 644d32e846..eb03be085b 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2,6 +2,7 @@ #include #include +#include #include @@ -2221,8 +2222,7 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, boost::filesystem::path customFiltersPath (configuration.getUserDataPath()); customFiltersPath /= "defaultfilters"; - std::string destinationPath = mProjectPath.string() + "/defaultfilters"; - std::ofstream dst(destinationPath.c_str(), std::ios::binary); + std::ofstream dst(mProjectPath.c_str(), std::ios::binary); if (boost::filesystem::exists (customFiltersPath)) { diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 2127724502..0c44c2dcbc 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -24,6 +24,7 @@ namespace CSMWorld { ColumnId_ValueType, "Value Type" }, { ColumnId_Description, "Description" }, { ColumnId_Specialisation, "Specialisation" }, + { ColumnId_Skill, "Skill" }, { ColumnId_Attribute, "Attribute" }, { ColumnId_Name, "Name" }, { ColumnId_Playable, "Playable" }, @@ -248,6 +249,11 @@ int CSMWorld::Columns::getId (const std::string& name) namespace { + static const char *sSkills[] = + { + "Long Blade" + }; + static const char *sSpecialisations[] = { "Combat", "Magic", "Stealth", 0 @@ -339,6 +345,7 @@ namespace switch (column) { case CSMWorld::Columns::ColumnId_Specialisation: return sSpecialisations; + case CSMWorld::Columns::ColumnId_Skill: return sSkills; case CSMWorld::Columns::ColumnId_Attribute: return sAttributes; case CSMWorld::Columns::ColumnId_SpellType: return sSpellTypes; case CSMWorld::Columns::ColumnId_ApparatusType: return sApparatusTypes; diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 7efaf2bd0a..b06018dd42 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -190,6 +190,7 @@ namespace CSMWorld ColumnId_RotY = 175, ColumnId_RotZ = 176, ColumnId_DestinationCell = 177, + ColumnId_Skill = 178, // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. diff --git a/apps/opencs/model/world/commands.cpp b/apps/opencs/model/world/commands.cpp index 0d9f6c7732..30c4bb892b 100644 --- a/apps/opencs/model/world/commands.cpp +++ b/apps/opencs/model/world/commands.cpp @@ -173,13 +173,17 @@ void CSMWorld::CloneCommand::undo() mModel.removeRow (mModel.getModelIndex (mIdDestination, 0).row()); } -CSMWorld::DeleteNestedCommand::DeleteNestedCommand (IdTable& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent) - : mId(id), - mModel(model), - mParentColumn(parentColumn), - QUndoCommand(parent), - mNestedRow(nestedRow), - NestedTableStoring(model, id, parentColumn) +CSMWorld::DeleteNestedCommand::DeleteNestedCommand (IdTable& model, + const std::string& id, + int nestedRow, + int parentColumn, + QUndoCommand* parent) : + mId(id), + mModel(model), + mParentColumn(parentColumn), + QUndoCommand(parent), + mNestedRow(nestedRow), + NestedTableStoring(model, id, parentColumn) { setText (("Delete nested row in " + mId).c_str()); } diff --git a/apps/opencs/model/world/nestedadaptors.hpp b/apps/opencs/model/world/nestedadaptors.hpp index 319fe1569e..6e3d447b29 100644 --- a/apps/opencs/model/world/nestedadaptors.hpp +++ b/apps/opencs/model/world/nestedadaptors.hpp @@ -13,6 +13,9 @@ #include #include #include +#include +#include +#include #include @@ -174,6 +177,129 @@ namespace CSMWorld }; + /* + template + class MagicEffectsHelper : public CastableHelper + { + public: + + MagicEffectsHelper(CSMWorld::UniversalId::Type type) + : CastableHelper(type) {} + + virtual void setNestedTable(RefIdData& data, + int index, + const NestedTableWrapperBase& nestedTable) + { + CastableHelper::getRecord(data, index).get().mEffects = + (static_cast&>(nestedTable)).mNestedTable; + } + + virtual NestedTableWrapperBase* nestedTable(const RefIdData& data, + int index) const + { + return new NestedTableWrapper(CastableHelper::getRecord(data, index).get().mEffects); + } + + virtual QVariant getNestedData(const CSMWorld::RefIdData& data, + int index, + int subRowIndex, + int subColIndex) const + { + const ESM::EffectList& content = CastableHelper::getRecord(data, index).get().mEffects; + + switch (subColIndex) + { + case 0: + return content.at(subRowIndex).mEffectID; + + case 1: + return content.at(subRowIndex).mRange; + + case 2: + return content.at(subRowIndex).mDuration; + + case 3: + return content.at(subRowIndex).mArea; + + case 4: + return content.at(subRowIndex).mMagMin; + + case 5: + return content.at(subRowIndex).mMagMax; + + case 6: + return (int)content.at(rubRowIndex).mSkill; + + case 7: + return (int)content.at(subRowIndex).mAttribute; + + default: + throw std::logic_error("Trying to access non-existing column in the nested table!"); + } + } + + virtual void removeNestedRow (RefIdData& data, int index, int rowToRemove) const + { + ESM::EffectList& list = CastableHelper::getRecord(data, index).get().mEffects; + + list.erase (list.begin () + rowToRemove); + } + + void setNestedData (RefIdData& data, + int index, + const QVariant& value, + int subRowIndex, + int subColIndex) const + { + switch(subColIndex) + { + case 0: + CastableHelper::getRecord(data, index).get().mEffects.at(subRowIndex).mEffectID = value.toInt(); + break; + + default: + throw std::logic_error("Trying to access non-existing column in the nested table!"); + } + } + + virtual void addNestedRow (RefIdData& data, int index, int position) const + { + std::vector& list = CastableHelper::getRecord(data, index).get().mTransport; + + ESM::Position newPos; + for (unsigned i = 0; i < 3; ++i) + { + newPos.pos[i] = 0; + newPos.rot[i] = 0; + } + + ESM::NPC::Dest newRow; + newRow.mPos = newPos; + newRow.mCellName = ""; + + if (position >= (int)list.size()) + { + list.push_back(newRow); + return; + } + + list.insert(list.begin()+position, newRow); + } + + virtual int getNestedColumnsCount(const RefIdData& data) const + { + return 7; + } + + + virtual int getNestedRowsCount(const RefIdData& data, + int index) const + { + return CastableHelper::getRecord(data, index).get().mTransport.size(); + } + + }; + */ template class DestinationsHelper : public CastableHelper { @@ -316,7 +442,7 @@ namespace CSMWorld } }; - + template class InventoryHelper : public CastableHelper { diff --git a/apps/opencs/view/world/enumdelegate.cpp b/apps/opencs/view/world/enumdelegate.cpp index 377f479bff..16f38938d4 100644 --- a/apps/opencs/view/world/enumdelegate.cpp +++ b/apps/opencs/view/world/enumdelegate.cpp @@ -46,7 +46,6 @@ QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent, const QModelIndex& index) const { return createEditor(parent, option, index, CSMWorld::ColumnBase::Display_None); - //overloading virtual functions is HARD } QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem& option, From c6194e7ea3352918e41d2bd7118294909651d7e8 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 30 Jul 2014 22:08:55 +0200 Subject: [PATCH 074/185] inserted additional class for nested collections --- apps/opencs/model/world/collection.hpp | 43 --------------------- apps/opencs/model/world/collectionbase.cpp | 27 ------------- apps/opencs/model/world/collectionbase.hpp | 40 +++++++++++-------- apps/opencs/model/world/idtable.cpp | 30 +++++++------- apps/opencs/model/world/refidcollection.hpp | 2 +- 5 files changed, 40 insertions(+), 102 deletions(-) diff --git a/apps/opencs/model/world/collection.hpp b/apps/opencs/model/world/collection.hpp index 591074372d..252e84c382 100644 --- a/apps/opencs/model/world/collection.hpp +++ b/apps/opencs/model/world/collection.hpp @@ -17,8 +17,6 @@ #include "collectionbase.hpp" -#include "nestedtablewrapper.hpp" - namespace CSMWorld { /// \brief Access to ID field in records @@ -77,10 +75,6 @@ namespace CSMWorld virtual int getSize() const; - virtual int getNestedColumnsCount(int column) const; - - virtual int getNestedRowsCount(int row, int column) const; - virtual std::string getId (int index) const; virtual int getIndex (const std::string& id) const; @@ -89,14 +83,8 @@ namespace CSMWorld virtual QVariant getData (int index, int column) const; - virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const; - virtual void setData (int index, int column, const QVariant& data); - virtual NestedTableWrapperBase* nestedTable(int row, int column) const; - - virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable); - virtual const ColumnBase& getColumn (int column) const; virtual void merge(); @@ -261,18 +249,6 @@ namespace CSMWorld return mRecords.size(); } - template - int Collection::getNestedRowsCount(int row, int column) const - { - return 0; - } - - template - int Collection::getNestedColumnsCount(int column) const - { - return 0; - } - template std::string Collection::getId (int index) const { @@ -302,25 +278,6 @@ namespace CSMWorld return mColumns.at (column)->get (mRecords.at (index)); } - template - QVariant Collection::getNestedData(int row, int column, int subRow, int subColumn) const - { - return QVariant(); - } - - template - NestedTableWrapperBase* Collection::nestedTable(int row, int column) const - { - assert(false); - return new NestedTableWrapperBase(); - } - - template - void Collection::setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable) - { - throw std::logic_error("setNestedTable was not overriden"); - } - template void Collection::setData (int index, int column, const QVariant& data) { diff --git a/apps/opencs/model/world/collectionbase.cpp b/apps/opencs/model/world/collectionbase.cpp index a1f4f4a70d..5b0c359c91 100644 --- a/apps/opencs/model/world/collectionbase.cpp +++ b/apps/opencs/model/world/collectionbase.cpp @@ -30,30 +30,3 @@ int CSMWorld::CollectionBase::findColumnIndex (Columns::ColumnId id) const return index; } - -void CSMWorld::CollectionBase::setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn) -{ - assert(false); //TODO remove and make pure abstract -} - -int CSMWorld::CollectionBase::getNestedColumnsCount(int row, int column) const -{ - assert(false); //TODO remove and make pure abstract - return 0; -} - -int CSMWorld::CollectionBase::getNestedRowsCount(int row, int column) const -{ - assert(false); //TODO, make pure abstract - return 0; -} - -void CSMWorld::CollectionBase::removeNestedRows(int row, int column, int subRow) -{ - assert(false); //todo, make pure abstract -} - -void CSMWorld::CollectionBase::addNestedRow(int row, int col, int position) -{ - assert(false); -} diff --git a/apps/opencs/model/world/collectionbase.hpp b/apps/opencs/model/world/collectionbase.hpp index a6ee34e56e..29ac33bc82 100644 --- a/apps/opencs/model/world/collectionbase.hpp +++ b/apps/opencs/model/world/collectionbase.hpp @@ -13,7 +13,7 @@ namespace CSMWorld { struct ColumnBase; struct RecordBase; - class NestedTableWrapperBase; + class NestedTableWrapperBase; /// \brief Base class for record collections /// @@ -35,10 +35,6 @@ namespace CSMWorld virtual int getSize() const = 0; - virtual int getNestedRowsCount(int row, int column) const; - - virtual int getNestedColumnsCount(int row, int column) const; - virtual std::string getId (int index) const = 0; virtual int getIndex (const std::string& id) const = 0; @@ -49,16 +45,8 @@ namespace CSMWorld virtual QVariant getData (int index, int column) const = 0; - virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const = 0; - - virtual NestedTableWrapperBase* nestedTable(int row, int column) const = 0; - - virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable) = 0; - virtual void setData (int index, int column, const QVariant& data) = 0; - virtual void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn); - // Not in use. Temporarily removed so that the implementation of RefIdCollection can continue without // these functions for now. // virtual void merge() = 0; @@ -69,10 +57,6 @@ namespace CSMWorld virtual void removeRows (int index, int count) = 0; - virtual void removeNestedRows(int row, int column, int subRow); - - virtual void addNestedRow(int row, int col, int position); - virtual void appendBlankRecord (const std::string& id, UniversalId::Type type = UniversalId::Type_None) = 0; ///< \param type Will be ignored, unless the collection supports multiple record types @@ -121,6 +105,28 @@ namespace CSMWorld ///< Return index of column with the given \a id. If no such column exists, an exception is /// thrown. }; + + class NestedCollection : public CollectionBase + { + public: + virtual void addNestedRow(int row, int col, int position) = 0; + + virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const = 0; + + virtual NestedTableWrapperBase* nestedTable(int row, int column) const = 0; + + virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable) = 0; + + virtual void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn) = 0; + + virtual int getNestedRowsCount(int row, int column) const = 0; + + virtual int getNestedColumnsCount(int row, int column) const = 0; + + virtual void removeNestedRows(int row, int column, int subRow) = 0; + + + }; } #endif diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index be31d05030..4e4ccb1c1b 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -18,7 +18,7 @@ int CSMWorld::IdTable::rowCount (const QModelIndex & parent) const { if (hasChildren(parent)) { - return mIdCollection->getNestedRowsCount(parent.row(), parent.column()); + return dynamic_cast(mIdCollection)->getNestedRowsCount(parent.row(), parent.column()); } return mIdCollection->getSize(); @@ -26,10 +26,9 @@ int CSMWorld::IdTable::rowCount (const QModelIndex & parent) const int CSMWorld::IdTable::columnCount (const QModelIndex & parent) const { - if (parent.isValid() && - parent.data().isValid()) + if (hasChildren(parent)) { - return mIdCollection->getNestedColumnsCount(parent.row(), parent.column()); + return dynamic_cast(mIdCollection)->getNestedColumnsCount(parent.row(), parent.column()); } return mIdCollection->getColumns(); @@ -46,10 +45,10 @@ QVariant CSMWorld::IdTable::data (const QModelIndex & index, int role) const if (index.internalId() != 0) { std::pair parentAdress(unfoldIndexAdress(index.internalId())); - return mIdCollection->getNestedData(parentAdress.first, - parentAdress.second, - index.row(), - index.column()); + return dynamic_cast(mIdCollection)->getNestedData(parentAdress.first, + parentAdress.second, + index.row(), + index.column()); } else { return mIdCollection->getData (index.row(), index.column()); } @@ -101,7 +100,7 @@ bool CSMWorld::IdTable::setData (const QModelIndex &index, const QVariant &value { const std::pair& parentAdress(unfoldIndexAdress(index.internalId())); - mIdCollection->setNestedData(parentAdress.first, parentAdress.second, value, index.row(), index.column()); + dynamic_cast(mIdCollection)->setNestedData(parentAdress.first, parentAdress.second, value, index.row(), index.column()); emit dataChanged (CSMWorld::IdTable::index (parentAdress.first, 0), CSMWorld::IdTable::index (parentAdress.second, mIdCollection->getColumns()-1)); @@ -144,7 +143,7 @@ bool CSMWorld::IdTable::removeRows (int row, int count, const QModelIndex& paren { for (int i = 0; i < count; ++i) { - mIdCollection->removeNestedRows(parent.row(), parent.column(), row+i); + dynamic_cast(mIdCollection)->removeNestedRows(parent.row(), parent.column(), row+i); } } else { @@ -164,12 +163,15 @@ bool CSMWorld::IdTable::removeRows (int row, int count, const QModelIndex& paren void CSMWorld::IdTable::addNestedRow(const QModelIndex& parent, int position) { - assert(parent.isValid()); + if (!hasChildren(parent)) + { + throw std::logic_error("Tried to set nested table, but index has no children"); + } int row = parent.row(); beginInsertRows(parent, position, position); - mIdCollection->addNestedRow(row, parent.column(), position); + dynamic_cast(mIdCollection)->addNestedRow(row, parent.column(), position); endInsertRows(); @@ -373,7 +375,7 @@ void CSMWorld::IdTable::setNestedTable(const QModelIndex& index, const CSMWorld: removeRowsMode = true; } - mIdCollection->setNestedTable(index.row(), index.column(), nestedTable); + dynamic_cast(mIdCollection)->setNestedTable(index.row(), index.column(), nestedTable); emit dataChanged (CSMWorld::IdTable::index (index.row(), 0), CSMWorld::IdTable::index (index.row(), mIdCollection->getColumns()-1)); @@ -391,5 +393,5 @@ CSMWorld::NestedTableWrapperBase* CSMWorld::IdTable::nestedTable(const QModelInd throw std::logic_error("Tried to retrive nested table, but index has no children"); } - return mIdCollection->nestedTable(index.row(), index.column()); + return dynamic_cast(mIdCollection)->nestedTable(index.row(), index.column()); } diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index cc7609a587..62616d3697 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -35,7 +35,7 @@ namespace CSMWorld virtual bool isUserEditable() const; }; - class RefIdCollection : public CollectionBase + class RefIdCollection : public NestedCollection { private: From 40edf15ab095f11c5485ff9a36912ac9e6cb7ce2 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 31 Jul 2014 12:18:24 +0200 Subject: [PATCH 075/185] cleaning up the code --- apps/opencs/model/world/collection.hpp | 1 + apps/opencs/model/world/columnimp.hpp | 1 + apps/opencs/model/world/idtable.cpp | 13 ++++++++----- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/apps/opencs/model/world/collection.hpp b/apps/opencs/model/world/collection.hpp index 252e84c382..5c32e7716d 100644 --- a/apps/opencs/model/world/collection.hpp +++ b/apps/opencs/model/world/collection.hpp @@ -2,6 +2,7 @@ #define CSM_WOLRD_COLLECTION_H #include +#include #include #include #include diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index 3fad05f651..e416c332b9 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -4,6 +4,7 @@ #include #include +#include #include diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index 4e4ccb1c1b..410e0d3f02 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -2,6 +2,7 @@ #include #include +#include #include "nestedtablewrapper.hpp" #include "collectionbase.hpp" @@ -30,7 +31,7 @@ int CSMWorld::IdTable::columnCount (const QModelIndex & parent) const { return dynamic_cast(mIdCollection)->getNestedColumnsCount(parent.row(), parent.column()); } - + return mIdCollection->getColumns(); } @@ -46,9 +47,9 @@ QVariant CSMWorld::IdTable::data (const QModelIndex & index, int role) const { std::pair parentAdress(unfoldIndexAdress(index.internalId())); return dynamic_cast(mIdCollection)->getNestedData(parentAdress.first, - parentAdress.second, - index.row(), - index.column()); + parentAdress.second, + index.row(), + index.column()); } else { return mIdCollection->getData (index.row(), index.column()); } @@ -68,8 +69,10 @@ QVariant CSMWorld::IdTable::headerData (int section, return mIdCollection->getColumn (section).mFlags; if (role==ColumnBase::Role_Display) + { return mIdCollection->getColumn (section).mDisplayType; - + } + return QVariant(); } From 3b534326ff0c01de98deb9a3220e74c2049073ad Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 5 Jan 2015 15:04:11 +0100 Subject: [PATCH 076/185] forbid manual editing of the cell field in reference records --- apps/opencs/model/world/columnimp.hpp | 10 ++++++++-- apps/opencs/model/world/data.cpp | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index eba73cf0b0..95023f49d6 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -870,7 +870,13 @@ namespace CSMWorld template struct CellColumn : public Column { - CellColumn() : Column (Columns::ColumnId_Cell, ColumnBase::Display_Cell) {} + bool mBlocked; + + /// \param blocked Do not allow user-modification + CellColumn (bool blocked = false) + : Column (Columns::ColumnId_Cell, ColumnBase::Display_Cell), + mBlocked (blocked) + {} virtual QVariant get (const Record& record) const { @@ -893,7 +899,7 @@ namespace CSMWorld virtual bool isUserEditable() const { - return true; + return !mBlocked; } }; diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 67f6822c7c..b925a66b3a 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -257,7 +257,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mRefs.addColumn (new StringIdColumn (true)); mRefs.addColumn (new RecordStateColumn); mRefs.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Reference)); - mRefs.addColumn (new CellColumn); + mRefs.addColumn (new CellColumn (true)); mRefs.addColumn (new IdColumn); mRefs.addColumn (new PosColumn (&CellRef::mPos, 0, false)); mRefs.addColumn (new PosColumn (&CellRef::mPos, 1, false)); From ba7b74217b9b821f2d354f5ee131b90bc333fd50 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 5 Jan 2015 15:20:47 +0100 Subject: [PATCH 077/185] added original cell column to reference table --- apps/opencs/model/world/columnimp.hpp | 32 +++++++++++++++++++++++ apps/opencs/model/world/columns.cpp | 1 + apps/opencs/model/world/columns.hpp | 1 + apps/opencs/model/world/data.cpp | 1 + apps/opencs/model/world/ref.hpp | 1 + apps/opencs/model/world/refcollection.cpp | 1 + 6 files changed, 37 insertions(+) diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index 95023f49d6..ed2cfc310a 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -903,6 +903,38 @@ namespace CSMWorld } }; + template + struct OriginalCellColumn : public Column + { + OriginalCellColumn() + : Column (Columns::ColumnId_OriginalCell, ColumnBase::Display_Cell) + {} + + virtual QVariant get (const Record& record) const + { + return QString::fromUtf8 (record.get().mOriginalCell.c_str()); + } + + virtual void set (Record& record, const QVariant& data) + { + ESXRecordT record2 = record.get(); + + record2.mOriginalCell = data.toString().toUtf8().constData(); + + record.setModified (record2); + } + + virtual bool isEditable() const + { + return true; + } + + virtual bool isUserEditable() const + { + return false; + } + }; + template struct IdColumn : public Column { diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 8349eb515b..d85125bd58 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -201,6 +201,7 @@ namespace CSMWorld { ColumnId_HitSound, "Hit Sound" }, { ColumnId_AreaSound, "Area Sound" }, { ColumnId_BoltSound, "Bolt Sound" }, + { ColumnId_OriginalCell, "Original Cell" }, { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index ca03266557..d3476f7b21 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -194,6 +194,7 @@ namespace CSMWorld ColumnId_HitSound = 178, ColumnId_AreaSound = 179, ColumnId_BoltSound = 180, + ColumnId_OriginalCell = 181, // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. ColumnId_UseValue1 = 0x10000, diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index b925a66b3a..e8905b9252 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -258,6 +258,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mRefs.addColumn (new RecordStateColumn); mRefs.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Reference)); mRefs.addColumn (new CellColumn (true)); + mRefs.addColumn (new OriginalCellColumn); mRefs.addColumn (new IdColumn); mRefs.addColumn (new PosColumn (&CellRef::mPos, 0, false)); mRefs.addColumn (new PosColumn (&CellRef::mPos, 1, false)); diff --git a/apps/opencs/model/world/ref.hpp b/apps/opencs/model/world/ref.hpp index eb62434cf2..4110246918 100644 --- a/apps/opencs/model/world/ref.hpp +++ b/apps/opencs/model/world/ref.hpp @@ -12,6 +12,7 @@ namespace CSMWorld { std::string mId; std::string mCell; + std::string mOriginalCell; CellRef(); }; diff --git a/apps/opencs/model/world/refcollection.cpp b/apps/opencs/model/world/refcollection.cpp index 47f0276c6c..1a0dd1e5bf 100644 --- a/apps/opencs/model/world/refcollection.cpp +++ b/apps/opencs/model/world/refcollection.cpp @@ -23,6 +23,7 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool while (ESM::Cell::getNextRef (reader, ref, deleted)) { + ref.mOriginalCell = cell2.mId; ref.mCell = cell2.mId; /// \todo handle moved references From e32402a0402be2bb36754fe2b718aa384df54726 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 9 Jan 2015 12:05:16 +0100 Subject: [PATCH 078/185] handle moved references on load --- apps/opencs/model/world/ref.cpp | 10 ++++++++++ apps/opencs/model/world/ref.hpp | 5 +++++ apps/opencs/model/world/refcollection.cpp | 14 ++++++++++++-- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/ref.cpp b/apps/opencs/model/world/ref.cpp index f3c1b0b73f..63594acc8f 100644 --- a/apps/opencs/model/world/ref.cpp +++ b/apps/opencs/model/world/ref.cpp @@ -1,8 +1,18 @@ #include "ref.hpp" +#include + CSMWorld::CellRef::CellRef() { mRefNum.mIndex = 0; mRefNum.mContentFile = 0; +} + +std::pair CSMWorld::CellRef::getCellIndex() const +{ + const int cellSize = 8192; + + return std::make_pair ( + std::floor (mPos.pos[0]/cellSize), std::floor (mPos.pos[1]/cellSize)); } \ No newline at end of file diff --git a/apps/opencs/model/world/ref.hpp b/apps/opencs/model/world/ref.hpp index 4110246918..dae9488f05 100644 --- a/apps/opencs/model/world/ref.hpp +++ b/apps/opencs/model/world/ref.hpp @@ -1,6 +1,8 @@ #ifndef CSM_WOLRD_REF_H #define CSM_WOLRD_REF_H +#include + #include namespace CSMWorld @@ -15,6 +17,9 @@ namespace CSMWorld std::string mOriginalCell; CellRef(); + + /// Calculate cell index based on coordinates (x and y) + std::pair getCellIndex() const; }; } diff --git a/apps/opencs/model/world/refcollection.cpp b/apps/opencs/model/world/refcollection.cpp index 1a0dd1e5bf..19dfae57dd 100644 --- a/apps/opencs/model/world/refcollection.cpp +++ b/apps/opencs/model/world/refcollection.cpp @@ -24,9 +24,19 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool while (ESM::Cell::getNextRef (reader, ref, deleted)) { ref.mOriginalCell = cell2.mId; - ref.mCell = cell2.mId; - /// \todo handle moved references + if (cell.get().isExterior()) + { + // ignoring moved references sub-record; instead calculate cell from coordinates + std::pair index = ref.getCellIndex(); + + std::ostringstream stream; + stream << "#" << index.first << " " << index.second; + + ref.mCell = stream.str(); + } + else + ref.mCell = cell2.mId; std::map::iterator iter = cache.find (ref.mRefNum); From 320b994aef7ed7f0df3987c4ffc909aa287e9059 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 10 Jan 2015 12:35:59 +0100 Subject: [PATCH 079/185] keep original cell field empty, if reference is in modified --- apps/opencs/model/world/refcollection.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/world/refcollection.cpp b/apps/opencs/model/world/refcollection.cpp index 19dfae57dd..dcb295626a 100644 --- a/apps/opencs/model/world/refcollection.cpp +++ b/apps/opencs/model/world/refcollection.cpp @@ -23,10 +23,13 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool while (ESM::Cell::getNextRef (reader, ref, deleted)) { - ref.mOriginalCell = cell2.mId; + // Keep mOriginalCell empty when in modified (as an indicator that the + // original cell will always be equal the current cell). + ref.mOriginalCell = base ? cell2.mId : ""; if (cell.get().isExterior()) { + // ignoring moved references sub-record; instead calculate cell from coordinates std::pair index = ref.getCellIndex(); From 7615cbafcee43007b60da8de8f7e1a5795b1471b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 15 Jan 2015 14:24:33 +0100 Subject: [PATCH 080/185] create modify commands through command dispatcher --- apps/opencs/model/world/commanddispatcher.cpp | 8 ++++++++ apps/opencs/model/world/commanddispatcher.hpp | 9 +++++++++ apps/opencs/view/tools/reporttable.cpp | 4 ++-- apps/opencs/view/world/datadisplaydelegate.cpp | 7 ++++--- apps/opencs/view/world/datadisplaydelegate.hpp | 11 ++++------- apps/opencs/view/world/dialoguesubview.cpp | 14 +++++++------- apps/opencs/view/world/dialoguesubview.hpp | 10 ++++++---- apps/opencs/view/world/enumdelegate.cpp | 8 ++++---- apps/opencs/view/world/enumdelegate.hpp | 4 ++-- apps/opencs/view/world/idtypedelegate.cpp | 8 ++++---- apps/opencs/view/world/idtypedelegate.hpp | 4 ++-- .../opencs/view/world/recordstatusdelegate.cpp | 8 ++++---- .../opencs/view/world/recordstatusdelegate.hpp | 8 ++++---- apps/opencs/view/world/table.cpp | 2 +- apps/opencs/view/world/util.cpp | 18 ++++++++++++------ apps/opencs/view/world/util.hpp | 14 ++++++++++---- apps/opencs/view/world/vartypedelegate.cpp | 8 ++++---- apps/opencs/view/world/vartypedelegate.hpp | 5 +++-- 18 files changed, 90 insertions(+), 60 deletions(-) diff --git a/apps/opencs/model/world/commanddispatcher.cpp b/apps/opencs/model/world/commanddispatcher.cpp index 4e146d87c0..a0b7a9fa06 100644 --- a/apps/opencs/model/world/commanddispatcher.cpp +++ b/apps/opencs/model/world/commanddispatcher.cpp @@ -131,6 +131,14 @@ std::vector CSMWorld::CommandDispatcher::getExtendedTypes return tables; } +void CSMWorld::CommandDispatcher::executeModify (QAbstractItemModel *model, const QModelIndex& index, const QVariant& new_) +{ + if (mLocked) + return; + + mDocument.getUndoStack().push (new CSMWorld::ModifyCommand (*model, index, new_)); +} + void CSMWorld::CommandDispatcher::executeDelete() { if (mLocked) diff --git a/apps/opencs/model/world/commanddispatcher.hpp b/apps/opencs/model/world/commanddispatcher.hpp index 50085b1a1e..1d29e48c19 100644 --- a/apps/opencs/model/world/commanddispatcher.hpp +++ b/apps/opencs/model/world/commanddispatcher.hpp @@ -7,6 +7,9 @@ #include "universalid.hpp" +class QModelIndex; +class QAbstractItemModel; + namespace CSMDoc { class Document; @@ -53,6 +56,12 @@ namespace CSMWorld /// the extended mode, the returned vector will be empty instead. std::vector getExtendedTypes() const; + /// Add a modify command to the undo stack. + /// + /// \attention model must either be a model for the table operated on by this + /// dispatcher or a proxy of it. + void executeModify (QAbstractItemModel *model, const QModelIndex& index, const QVariant& new_); + public slots: void executeDelete(); diff --git a/apps/opencs/view/tools/reporttable.cpp b/apps/opencs/view/tools/reporttable.cpp index 4cd11925e0..6ab470a02c 100644 --- a/apps/opencs/view/tools/reporttable.cpp +++ b/apps/opencs/view/tools/reporttable.cpp @@ -79,8 +79,8 @@ CSVTools::ReportTable::ReportTable (CSMDoc::Document& document, setModel (mModel); setColumnHidden (2, true); - mIdTypeDelegate = CSVWorld::IdTypeDelegateFactory().makeDelegate ( - document, this); + mIdTypeDelegate = CSVWorld::IdTypeDelegateFactory().makeDelegate (0, + mDocument, this); setItemDelegateForColumn (0, mIdTypeDelegate); diff --git a/apps/opencs/view/world/datadisplaydelegate.cpp b/apps/opencs/view/world/datadisplaydelegate.cpp index 46ca17a292..b9df52bf7e 100644 --- a/apps/opencs/view/world/datadisplaydelegate.cpp +++ b/apps/opencs/view/world/datadisplaydelegate.cpp @@ -6,11 +6,12 @@ CSVWorld::DataDisplayDelegate::DataDisplayDelegate(const ValueList &values, const IconList &icons, + CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, const QString &pageName, const QString &settingName, QObject *parent) - : EnumDelegate (values, document, parent), mDisplayMode (Mode_TextOnly), + : EnumDelegate (values, dispatcher, document, parent), mDisplayMode (Mode_TextOnly), mIcons (icons), mIconSize (QSize(16, 16)), mIconLeftOffset(3), mTextLeftOffset(8), mSettingKey (pageName + '/' + settingName) { @@ -136,9 +137,9 @@ void CSVWorld::DataDisplayDelegateFactory::add (int enumValue, QString enumName, } CSVWorld::CommandDelegate *CSVWorld::DataDisplayDelegateFactory::makeDelegate ( - CSMDoc::Document& document, QObject *parent) const + CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const { - return new DataDisplayDelegate (mValues, mIcons, document, "", "", parent); + return new DataDisplayDelegate (mValues, mIcons, dispatcher, document, "", "", parent); } diff --git a/apps/opencs/view/world/datadisplaydelegate.hpp b/apps/opencs/view/world/datadisplaydelegate.hpp index 73790e3c65..f6e4c26887 100755 --- a/apps/opencs/view/world/datadisplaydelegate.hpp +++ b/apps/opencs/view/world/datadisplaydelegate.hpp @@ -38,12 +38,9 @@ namespace CSVWorld QString mSettingKey; public: - explicit DataDisplayDelegate (const ValueList & values, - const IconList & icons, - CSMDoc::Document& document, - const QString &pageName, - const QString &settingName, - QObject *parent); + DataDisplayDelegate (const ValueList & values, const IconList & icons, + CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, + const QString &pageName, const QString &settingName, QObject *parent); ~DataDisplayDelegate(); @@ -82,7 +79,7 @@ namespace CSVWorld public: - virtual CommandDelegate *makeDelegate (CSMDoc::Document& document, QObject *parent) const; + virtual CommandDelegate *makeDelegate (CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const; ///< The ownership of the returned CommandDelegate is transferred to the caller. protected: diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 8790601ea3..497ce7acdc 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -167,10 +167,10 @@ void CSVWorld::DialogueDelegateDispatcherProxy::tableMimeDataDropped(const std:: ==============================DialogueDelegateDispatcher========================================== */ -CSVWorld::DialogueDelegateDispatcher::DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, CSMDoc::Document& document) : +CSVWorld::DialogueDelegateDispatcher::DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, CSMWorld::CommandDispatcher& commandDispatcher, CSMDoc::Document& document) : mParent(parent), mTable(table), -mDocument (document), +mCommandDispatcher (commandDispatcher), mDocument (document), mNotEditableDelegate(table, parent) { } @@ -182,7 +182,7 @@ CSVWorld::CommandDelegate* CSVWorld::DialogueDelegateDispatcher::makeDelegate(CS if (delegateIt == mDelegates.end()) { delegate = CommandDelegateFactoryCollection::get().makeDelegate ( - display, mDocument, mParent); + display, &mCommandDispatcher, mDocument, mParent); mDelegates.insert(std::make_pair(display, delegate)); } else { @@ -309,12 +309,12 @@ CSVWorld::DialogueDelegateDispatcher::~DialogueDelegateDispatcher() =============================================================EditWidget===================================================== */ -CSVWorld::EditWidget::EditWidget(QWidget *parent, int row, CSMWorld::IdTable* table, CSMDoc::Document& document, bool createAndDelete) : -mDispatcher(this, table, document), +CSVWorld::EditWidget::EditWidget(QWidget *parent, int row, CSMWorld::IdTable* table, CSMWorld::CommandDispatcher& commandDispatcher, CSMDoc::Document& document, bool createAndDelete) : +mDispatcher(this, table, commandDispatcher, document), QScrollArea(parent), mWidgetMapper(NULL), mMainWidget(NULL), -mDocument (document), +mCommandDispatcher (commandDispatcher), mTable(table) { remake (row); @@ -471,7 +471,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM mMainLayout = new QVBoxLayout(mainWidget); - mEditWidget = new EditWidget(mainWidget, mRow, mTable, document, false); + mEditWidget = new EditWidget(mainWidget, mRow, mTable, mCommandDispatcher, document, false); connect(mEditWidget, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)), this, SLOT(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*))); diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index 4c260170f3..f45ed40c44 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -101,14 +101,16 @@ namespace CSVWorld CSMWorld::IdTable* mTable; - CSMDoc::Document& mDocument; + CSMWorld::CommandDispatcher& mCommandDispatcher; + CSMDoc::Document& mDocument; NotEditableSubDelegate mNotEditableDelegate; std::vector mProxys; //once we move to the C++11 we should use unique_ptr public: - DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, CSMDoc::Document& document); + DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, + CSMWorld::CommandDispatcher& commandDispatcher, CSMDoc::Document& document); ~DialogueDelegateDispatcher(); @@ -145,11 +147,11 @@ namespace CSVWorld DialogueDelegateDispatcher mDispatcher; QWidget* mMainWidget; CSMWorld::IdTable* mTable; - CSMDoc::Document& mDocument; + CSMWorld::CommandDispatcher& mCommandDispatcher; public: - EditWidget (QWidget *parent, int row, CSMWorld::IdTable* table, CSMDoc::Document& document, bool createAndDelete = false); + EditWidget (QWidget *parent, int row, CSMWorld::IdTable* table, CSMWorld::CommandDispatcher& commandDispatcher, CSMDoc::Document& document, bool createAndDelete = false); void remake(int row); diff --git a/apps/opencs/view/world/enumdelegate.cpp b/apps/opencs/view/world/enumdelegate.cpp index 168e5cb0a3..95b120e9af 100644 --- a/apps/opencs/view/world/enumdelegate.cpp +++ b/apps/opencs/view/world/enumdelegate.cpp @@ -35,8 +35,8 @@ void CSVWorld::EnumDelegate::addCommands (QAbstractItemModel *model, CSVWorld::EnumDelegate::EnumDelegate (const std::vector >& values, - CSMDoc::Document& document, QObject *parent) -: CommandDelegate (document, parent), mValues (values) + CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) +: CommandDelegate (dispatcher, document, parent), mValues (values) { } @@ -141,9 +141,9 @@ CSVWorld::EnumDelegateFactory::EnumDelegateFactory (const std::vector >& values, - CSMDoc::Document& document, QObject *parent); + CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent); virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem& option, @@ -64,7 +64,7 @@ namespace CSVWorld EnumDelegateFactory (const std::vector& names, bool allowNone = false); /// \param allowNone Use value of -1 for "none selected" (empty string) - virtual CommandDelegate *makeDelegate (CSMDoc::Document& document, QObject *parent) const; + virtual CommandDelegate *makeDelegate (CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const; ///< The ownership of the returned CommandDelegate is transferred to the caller. void add (int value, const QString& name); diff --git a/apps/opencs/view/world/idtypedelegate.cpp b/apps/opencs/view/world/idtypedelegate.cpp index 3b440ff714..34c8d12cd7 100755 --- a/apps/opencs/view/world/idtypedelegate.cpp +++ b/apps/opencs/view/world/idtypedelegate.cpp @@ -3,8 +3,8 @@ #include "../../model/world/universalid.hpp" CSVWorld::IdTypeDelegate::IdTypeDelegate - (const ValueList &values, const IconList &icons, CSMDoc::Document& document, QObject *parent) - : DataDisplayDelegate (values, icons, document, + (const ValueList &values, const IconList &icons, CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) + : DataDisplayDelegate (values, icons, dispatcher, document, "records", "type-format", parent) {} @@ -21,7 +21,7 @@ CSVWorld::IdTypeDelegateFactory::IdTypeDelegateFactory() } CSVWorld::CommandDelegate *CSVWorld::IdTypeDelegateFactory::makeDelegate ( - CSMDoc::Document& document, QObject *parent) const + CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const { - return new IdTypeDelegate (mValues, mIcons, document, parent); + return new IdTypeDelegate (mValues, mIcons, dispatcher, document, parent); } diff --git a/apps/opencs/view/world/idtypedelegate.hpp b/apps/opencs/view/world/idtypedelegate.hpp index e9a0af68c5..d0ed6997b4 100755 --- a/apps/opencs/view/world/idtypedelegate.hpp +++ b/apps/opencs/view/world/idtypedelegate.hpp @@ -11,7 +11,7 @@ namespace CSVWorld class IdTypeDelegate : public DataDisplayDelegate { public: - IdTypeDelegate (const ValueList &mValues, const IconList &icons, CSMDoc::Document& document, QObject *parent); + IdTypeDelegate (const ValueList &mValues, const IconList &icons, CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent); }; class IdTypeDelegateFactory : public DataDisplayDelegateFactory @@ -20,7 +20,7 @@ namespace CSVWorld IdTypeDelegateFactory(); - virtual CommandDelegate *makeDelegate (CSMDoc::Document& document, QObject *parent) const; + virtual CommandDelegate *makeDelegate (CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const; ///< The ownership of the returned CommandDelegate is transferred to the caller. }; } diff --git a/apps/opencs/view/world/recordstatusdelegate.cpp b/apps/opencs/view/world/recordstatusdelegate.cpp index 708a780155..58a5c01774 100644 --- a/apps/opencs/view/world/recordstatusdelegate.cpp +++ b/apps/opencs/view/world/recordstatusdelegate.cpp @@ -9,16 +9,16 @@ CSVWorld::RecordStatusDelegate::RecordStatusDelegate(const ValueList& values, const IconList & icons, - CSMDoc::Document& document, QObject *parent) - : DataDisplayDelegate (values, icons, document, + CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) + : DataDisplayDelegate (values, icons, dispatcher, document, "records", "status-format", parent) {} CSVWorld::CommandDelegate *CSVWorld::RecordStatusDelegateFactory::makeDelegate ( - CSMDoc::Document& document, QObject *parent) const + CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const { - return new RecordStatusDelegate (mValues, mIcons, document, parent); + return new RecordStatusDelegate (mValues, mIcons, dispatcher, document, parent); } CSVWorld::RecordStatusDelegateFactory::RecordStatusDelegateFactory() diff --git a/apps/opencs/view/world/recordstatusdelegate.hpp b/apps/opencs/view/world/recordstatusdelegate.hpp index fbdaed538b..acaf872a63 100644 --- a/apps/opencs/view/world/recordstatusdelegate.hpp +++ b/apps/opencs/view/world/recordstatusdelegate.hpp @@ -17,9 +17,9 @@ namespace CSVWorld { public: - explicit RecordStatusDelegate(const ValueList& values, - const IconList& icons, - CSMDoc::Document& document, QObject *parent = 0); + RecordStatusDelegate (const ValueList& values, const IconList& icons, + CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, + QObject *parent = 0); }; class RecordStatusDelegateFactory : public DataDisplayDelegateFactory @@ -28,7 +28,7 @@ namespace CSVWorld RecordStatusDelegateFactory(); - virtual CommandDelegate *makeDelegate (CSMDoc::Document& document, QObject *parent) const; + virtual CommandDelegate *makeDelegate (CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const; ///< The ownership of the returned CommandDelegate is transferred to the caller. }; diff --git a/apps/opencs/view/world/table.cpp b/apps/opencs/view/world/table.cpp index e864e4ed26..794510f42f 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -281,7 +281,7 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id, mModel->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); CommandDelegate *delegate = CommandDelegateFactoryCollection::get().makeDelegate (display, - mDocument, this); + mDispatcher, document, this); mDelegates.push_back (delegate); setItemDelegateForColumn (i, delegate); diff --git a/apps/opencs/view/world/util.cpp b/apps/opencs/view/world/util.cpp index c65e12c609..8039034a21 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -18,6 +18,7 @@ #include "../../model/world/commands.hpp" #include "../../model/world/tablemimedata.hpp" +#include "../../model/world/commanddispatcher.hpp" #include "scriptedit.hpp" @@ -82,15 +83,15 @@ void CSVWorld::CommandDelegateFactoryCollection::add (CSMWorld::ColumnBase::Disp } CSVWorld::CommandDelegate *CSVWorld::CommandDelegateFactoryCollection::makeDelegate ( - CSMWorld::ColumnBase::Display display, CSMDoc::Document& document, QObject *parent) const + CSMWorld::ColumnBase::Display display, CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const { std::map::const_iterator iter = mFactories.find (display); if (iter!=mFactories.end()) - return iter->second->makeDelegate (document, parent); + return iter->second->makeDelegate (dispatcher, document, parent); - return new CommandDelegate (document, parent); + return new CommandDelegate (dispatcher, document, parent); } const CSVWorld::CommandDelegateFactoryCollection& CSVWorld::CommandDelegateFactoryCollection::get() @@ -115,17 +116,22 @@ CSMDoc::Document& CSVWorld::CommandDelegate::getDocument() const void CSVWorld::CommandDelegate::setModelDataImp (QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const { + if (!mCommandDispatcher) + return; + NastyTableModelHack hack (*model); QStyledItemDelegate::setModelData (editor, &hack, index); QVariant new_ = hack.getData(); if (model->data (index)!=new_) - getUndoStack().push (new CSMWorld::ModifyCommand (*model, index, new_)); + mCommandDispatcher->executeModify (model, index, new_); } -CSVWorld::CommandDelegate::CommandDelegate (CSMDoc::Document& document, QObject *parent) -: QStyledItemDelegate (parent), mDocument (document), mEditLock (false) +CSVWorld::CommandDelegate::CommandDelegate (CSMWorld::CommandDispatcher *commandDispatcher, + CSMDoc::Document& document, QObject *parent) +: QStyledItemDelegate (parent), mEditLock (false), + mCommandDispatcher (commandDispatcher), mDocument (document) {} void CSVWorld::CommandDelegate::setModelData (QWidget *editor, QAbstractItemModel *model, diff --git a/apps/opencs/view/world/util.hpp b/apps/opencs/view/world/util.hpp index b4d972bf3f..df9d61dadd 100644 --- a/apps/opencs/view/world/util.hpp +++ b/apps/opencs/view/world/util.hpp @@ -16,6 +16,7 @@ namespace CSMWorld { class TableMimeData; class UniversalId; + class CommandDispatcher; } namespace CSVWorld @@ -51,7 +52,8 @@ namespace CSVWorld virtual ~CommandDelegateFactory(); - virtual CommandDelegate *makeDelegate (CSMDoc::Document& document, QObject *parent) + virtual CommandDelegate *makeDelegate (CSMWorld::CommandDispatcher *dispatcher, + CSMDoc::Document& document, QObject *parent) const = 0; ///< The ownership of the returned CommandDelegate is transferred to the caller. }; @@ -78,7 +80,8 @@ namespace CSVWorld /// /// This function must not be called more than once per value of \a display. - CommandDelegate *makeDelegate (CSMWorld::ColumnBase::Display display, CSMDoc::Document& document, + CommandDelegate *makeDelegate (CSMWorld::ColumnBase::Display display, + CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const; ///< The ownership of the returned CommandDelegate is transferred to the caller. /// @@ -111,8 +114,9 @@ namespace CSVWorld { Q_OBJECT - CSMDoc::Document& mDocument; bool mEditLock; + CSMWorld::CommandDispatcher *mCommandDispatcher; + CSMDoc::Document& mDocument; protected: @@ -125,7 +129,9 @@ namespace CSVWorld public: - CommandDelegate (CSMDoc::Document& document, QObject *parent); + /// \param commandDispatcher If CommandDelegate will be only be used on read-only + /// cells, a 0-pointer can be passed here. + CommandDelegate (CSMWorld::CommandDispatcher *commandDispatcher, CSMDoc::Document& document, QObject *parent); virtual void setModelData (QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const; diff --git a/apps/opencs/view/world/vartypedelegate.cpp b/apps/opencs/view/world/vartypedelegate.cpp index c3c98b800c..90a686a67e 100644 --- a/apps/opencs/view/world/vartypedelegate.cpp +++ b/apps/opencs/view/world/vartypedelegate.cpp @@ -47,8 +47,8 @@ void CSVWorld::VarTypeDelegate::addCommands (QAbstractItemModel *model, const QM } CSVWorld::VarTypeDelegate::VarTypeDelegate (const std::vector >& values, - CSMDoc::Document& document, QObject *parent) -: EnumDelegate (values, document, parent) + CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) +: EnumDelegate (values, dispatcher, document, parent) {} @@ -69,9 +69,9 @@ CSVWorld::VarTypeDelegateFactory::VarTypeDelegateFactory (ESM::VarType type0, } CSVWorld::CommandDelegate *CSVWorld::VarTypeDelegateFactory::makeDelegate ( - CSMDoc::Document& document, QObject *parent) const + CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const { - return new VarTypeDelegate (mValues, document, parent); + return new VarTypeDelegate (mValues, dispatcher, document, parent); } void CSVWorld::VarTypeDelegateFactory::add (ESM::VarType type) diff --git a/apps/opencs/view/world/vartypedelegate.hpp b/apps/opencs/view/world/vartypedelegate.hpp index c86b936f63..a8f39c318d 100644 --- a/apps/opencs/view/world/vartypedelegate.hpp +++ b/apps/opencs/view/world/vartypedelegate.hpp @@ -17,7 +17,7 @@ namespace CSVWorld public: VarTypeDelegate (const std::vector >& values, - CSMDoc::Document& document, QObject *parent); + CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent); }; class VarTypeDelegateFactory : public CommandDelegateFactory @@ -30,7 +30,8 @@ namespace CSVWorld ESM::VarType type1 = ESM::VT_Unknown, ESM::VarType type2 = ESM::VT_Unknown, ESM::VarType type3 = ESM::VT_Unknown); - virtual CommandDelegate *makeDelegate (CSMDoc::Document& document, QObject *parent) const; + virtual CommandDelegate *makeDelegate (CSMWorld::CommandDispatcher *dispatcher, + CSMDoc::Document& document, QObject *parent) const; ///< The ownership of the returned CommandDelegate is transferred to the caller. void add (ESM::VarType type); From 561ddfa0c59bdea8cb717658b56f6b4701c4cef7 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 16 Jan 2015 11:27:17 +0100 Subject: [PATCH 081/185] make column type accessable via the regular table model --- apps/opencs/model/world/columnbase.hpp | 3 ++- apps/opencs/model/world/idtable.cpp | 13 +++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index db9b8b3c64..03e3739043 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -15,7 +15,8 @@ namespace CSMWorld enum Roles { Role_Flags = Qt::UserRole, - Role_Display = Qt::UserRole+1 + Role_Display = Qt::UserRole+1, + Role_ColumnId = Qt::UserRole+1 }; enum Flags diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index c68b717896..7733264904 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -27,9 +27,15 @@ int CSMWorld::IdTable::columnCount (const QModelIndex & parent) const return mIdCollection->getColumns(); } -QVariant CSMWorld::IdTable::data (const QModelIndex & index, int role) const +QVariant CSMWorld::IdTable::data (const QModelIndex & index, int role) const { - if ((role!=Qt::DisplayRole && role!=Qt::EditRole) || index.row() < 0 || index.column() < 0) + if (index.row() < 0 || index.column() < 0) + return QVariant(); + + if (role==ColumnBase::Role_ColumnId) + return QVariant (getColumnId (index.column())); + + if ((role!=Qt::DisplayRole && role!=Qt::EditRole)) return QVariant(); if (role==Qt::EditRole && !mIdCollection->getColumn (index.column()).isEditable()) @@ -52,6 +58,9 @@ QVariant CSMWorld::IdTable::headerData (int section, Qt::Orientation orientation if (role==ColumnBase::Role_Display) return mIdCollection->getColumn (section).mDisplayType; + if (role==ColumnBase::Role_ColumnId) + return getColumnId (section); + return QVariant(); } From 9670e0881dd74c83e2ce40d7b5495d99bc525603 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 16 Jan 2015 15:17:52 +0100 Subject: [PATCH 082/185] update reference's current cell when x/y-coordinates are modified --- apps/opencs/model/world/commanddispatcher.cpp | 44 ++++++++++++++++- apps/opencs/model/world/commands.cpp | 47 ++++++++++++++++++- apps/opencs/model/world/commands.hpp | 23 ++++++++- 3 files changed, 111 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/world/commanddispatcher.cpp b/apps/opencs/model/world/commanddispatcher.cpp index a0b7a9fa06..cda4f3a748 100644 --- a/apps/opencs/model/world/commanddispatcher.cpp +++ b/apps/opencs/model/world/commanddispatcher.cpp @@ -2,6 +2,7 @@ #include "commanddispatcher.hpp" #include +#include #include @@ -10,6 +11,7 @@ #include "idtable.hpp" #include "record.hpp" #include "commands.hpp" +#include "idtableproxymodel.hpp" std::vector CSMWorld::CommandDispatcher::getDeletableRecords() const { @@ -136,7 +138,47 @@ void CSMWorld::CommandDispatcher::executeModify (QAbstractItemModel *model, cons if (mLocked) return; - mDocument.getUndoStack().push (new CSMWorld::ModifyCommand (*model, index, new_)); + std::auto_ptr modifyCell; + + int columnId = model->data (index, ColumnBase::Role_ColumnId).toInt(); + + if (columnId==Columns::ColumnId_PositionXPos || columnId==Columns::ColumnId_PositionYPos) + { + IdTableProxyModel *proxy = dynamic_cast (model); + + int row = proxy ? proxy->mapToSource (index).row() : index.row(); + + // This is not guaranteed to be the same as \a model, since a proxy could be used. + IdTable& model2 = dynamic_cast (*mDocument.getData().getTableModel (mId)); + + int cellColumn = model2.searchColumnIndex (Columns::ColumnId_Cell); + + if (cellColumn!=-1) + { + QModelIndex cellIndex = model2.index (row, cellColumn); + + std::string cellId = model2.data (cellIndex).toString().toUtf8().data(); + + if (cellId.find ('#')!=std::string::npos) + { + // Need to recalculate the cell + modifyCell.reset (new UpdateCellCommand (model2, row)); + } + } + } + + std::auto_ptr modifyData ( + new CSMWorld::ModifyCommand (*model, index, new_)); + + if (modifyCell.get()) + { + mDocument.getUndoStack().beginMacro (modifyData->text()); + mDocument.getUndoStack().push (modifyData.release()); + mDocument.getUndoStack().push (modifyCell.release()); + mDocument.getUndoStack().endMacro(); + } + else + mDocument.getUndoStack().push (modifyData.release()); } void CSMWorld::CommandDispatcher::executeDelete() diff --git a/apps/opencs/model/world/commands.cpp b/apps/opencs/model/world/commands.cpp index de0e9a4e53..bd667e40b9 100644 --- a/apps/opencs/model/world/commands.cpp +++ b/apps/opencs/model/world/commands.cpp @@ -1,11 +1,16 @@ #include "commands.hpp" +#include + +#include + #include -#include "idtable.hpp" #include +#include "idtable.hpp" + CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelIndex& index, const QVariant& new_, QUndoCommand* parent) : QUndoCommand (parent), mModel (model), mIndex (index), mNew (new_) @@ -170,4 +175,44 @@ void CSMWorld::CloneCommand::redo() void CSMWorld::CloneCommand::undo() { mModel.removeRow (mModel.getModelIndex (mId, 0).row()); +} + + +CSMWorld::UpdateCellCommand::UpdateCellCommand (IdTable& model, int row, QUndoCommand *parent) +: QUndoCommand (parent), mModel (model), mRow (row) +{ + setText ("Update cell ID"); +} + +void CSMWorld::UpdateCellCommand::redo() +{ + if (!mNew.isValid()) + { + int cellColumn = mModel.searchColumnIndex (Columns::ColumnId_Cell); + mIndex = mModel.index (mRow, cellColumn); + + const int cellSize = 8192; + + QModelIndex xIndex = mModel.index ( + mRow, mModel.findColumnIndex (Columns::ColumnId_PositionXPos)); + + QModelIndex yIndex = mModel.index ( + mRow, mModel.findColumnIndex (Columns::ColumnId_PositionYPos)); + + int x = std::floor (mModel.data (xIndex).toFloat() / cellSize); + int y = std::floor (mModel.data (yIndex).toFloat() / cellSize); + + std::ostringstream stream; + + stream << "#" << x << " " << y; + + mNew = QString::fromUtf8 (stream.str().c_str()); + } + + mModel.setData (mIndex, mNew); +} + +void CSMWorld::UpdateCellCommand::undo() +{ + mModel.setData (mIndex, mOld); } \ No newline at end of file diff --git a/apps/opencs/model/world/commands.hpp b/apps/opencs/model/world/commands.hpp index a15c071a8b..26e1da828f 100644 --- a/apps/opencs/model/world/commands.hpp +++ b/apps/opencs/model/world/commands.hpp @@ -18,7 +18,6 @@ class QAbstractItemModel; namespace CSMWorld { - class IdTable; class IdTable; class RecordBase; @@ -139,6 +138,28 @@ namespace CSMWorld virtual void undo(); }; + + /// \brief Update cell ID according to x/y-coordinates + /// + /// \note The new value will be calculated in the first call to redo instead of the + /// constructor to accommodate multiple coordinate-affecting commands being executed + /// in a macro. + class UpdateCellCommand : public QUndoCommand + { + IdTable& mModel; + int mRow; + QModelIndex mIndex; + QVariant mNew; // invalid, if new cell ID has not been calculated yet + QVariant mOld; + + public: + + UpdateCellCommand (IdTable& model, int row, QUndoCommand *parent = 0); + + virtual void redo(); + + virtual void undo(); + }; } #endif \ No newline at end of file From 764c155cece395e7e05de885dd26a0ad62b5c6f4 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 22 Jan 2015 13:33:23 +0100 Subject: [PATCH 083/185] moved code for writing/reading ref nums into RefNum struct --- components/esm/cellref.cpp | 27 +++++++++++++++++++-------- components/esm/cellref.hpp | 4 ++++ 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/components/esm/cellref.cpp b/components/esm/cellref.cpp index 29d26d013f..a14f977d64 100644 --- a/components/esm/cellref.cpp +++ b/components/esm/cellref.cpp @@ -4,6 +4,23 @@ #include "esmreader.hpp" #include "esmwriter.hpp" +void ESM::RefNum::load (ESMReader& esm, bool wide) +{ + if (wide) + esm.getHNT (*this, "FRMR", 8); + else + esm.getHNT (mIndex, "FRMR"); +} + +void ESM::RefNum::save (ESMWriter &esm, bool wide) const +{ + if (wide) + esm.writeHNT ("FRMR", *this, 8); + else + esm.writeHNT ("FRMR", mIndex, 4); +} + + void ESM::CellRef::load (ESMReader& esm, bool wideRefNum) { // According to Hrnchamd, this does not belong to the actual ref. Instead, it is a marker indicating that @@ -13,10 +30,7 @@ void ESM::CellRef::load (ESMReader& esm, bool wideRefNum) if (esm.isNextSub ("NAM0")) esm.skipHSub(); - if (wideRefNum) - esm.getHNT (mRefNum, "FRMR", 8); - else - esm.getHNT (mRefNum.mIndex, "FRMR"); + mRefNum.load (esm, wideRefNum); mRefID = esm.getHNString ("NAME"); @@ -74,10 +88,7 @@ void ESM::CellRef::load (ESMReader& esm, bool wideRefNum) void ESM::CellRef::save (ESMWriter &esm, bool wideRefNum, bool inInventory) const { - if (wideRefNum) - esm.writeHNT ("FRMR", mRefNum, 8); - else - esm.writeHNT ("FRMR", mRefNum.mIndex, 4); + mRefNum.save (esm, wideRefNum); esm.writeHNCString("NAME", mRefID); diff --git a/components/esm/cellref.hpp b/components/esm/cellref.hpp index 9c57061b00..505f676b18 100644 --- a/components/esm/cellref.hpp +++ b/components/esm/cellref.hpp @@ -15,6 +15,10 @@ namespace ESM { int mIndex; int mContentFile; // -1 no content file + + void load (ESMReader& esm, bool wide = false); + + void save (ESMWriter &esm, bool wide = false) const; }; /* Cell reference. This represents ONE object (of many) inside the From a97f599e6529ebdf87188c110839baa40f0c6f7c Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 22 Jan 2015 13:41:09 +0100 Subject: [PATCH 084/185] fixed ref num saving in non-wide format --- apps/opencs/model/doc/savingstages.cpp | 36 +++++++++++++++++++++++--- apps/opencs/model/doc/savingstate.cpp | 2 +- apps/opencs/model/doc/savingstate.hpp | 5 ++-- components/esm/cellref.cpp | 6 ++++- 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index 08f8c9eaa8..6b8750b446 100644 --- a/apps/opencs/model/doc/savingstages.cpp +++ b/apps/opencs/model/doc/savingstages.cpp @@ -231,8 +231,18 @@ void CSMDoc::CollectionReferencesStage::perform (int stage, Messages& messages) record.mState==CSMWorld::RecordBase::State_Modified || record.mState==CSMWorld::RecordBase::State_ModifiedOnly) { - mState.getSubRecords()[Misc::StringUtils::lowerCase (record.get().mCell)] - .push_back (i); + std::string cellId = record.get().mOriginalCell.empty() ? + record.get().mCell : record.get().mOriginalCell; + + std::deque& indices = + mState.getSubRecords()[Misc::StringUtils::lowerCase (cellId)]; + + // collect moved references at the end of the container + if (!record.get().mOriginalCell.empty() && + record.get().mOriginalCell!=record.get().mCell) + indices.push_back (i); + else + indices.push_front (i); } } } @@ -253,7 +263,7 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages) const CSMWorld::Record& cell = mDocument.getData().getCells().getRecord (stage); - std::map >::const_iterator references = + std::map >::const_iterator references = mState.getSubRecords().find (Misc::StringUtils::lowerCase (cell.get().mId)); if (cell.mState==CSMWorld::RecordBase::State_Modified || @@ -284,7 +294,7 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages) // write references if (references!=mState.getSubRecords().end()) { - for (std::vector::const_iterator iter (references->second.begin()); + for (std::deque::const_iterator iter (references->second.begin()); iter!=references->second.end(); ++iter) { const CSMWorld::Record& ref = @@ -293,6 +303,24 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages) if (ref.mState==CSMWorld::RecordBase::State_Modified || ref.mState==CSMWorld::RecordBase::State_ModifiedOnly) { + if (!ref.get().mOriginalCell.empty() && + ref.get().mOriginalCell!=ref.get().mCell) + { + ESM::MovedCellRef moved; + moved.mRefNum = ref.get().mRefNum; + + std::istringstream stream (ref.get().mCell.c_str()); + + char ignore; + stream >> ignore >> moved.mTarget[0] >> moved.mTarget[1]; + + mState.getWriter().startSubRecord ("MVRF"); + + mState.getWriter().endRecord ("MVRF"); + mState.getWriter().writeHNT ("FRMR", moved.mRefNum.mIndex, 4); + mState.getWriter().writeHNT ("CNDT", moved.mTarget, 8); + } + ref.get().save (mState.getWriter()); } else if (ref.mState==CSMWorld::RecordBase::State_Deleted) diff --git a/apps/opencs/model/doc/savingstate.cpp b/apps/opencs/model/doc/savingstate.cpp index 84bca1e95c..e7ad551b27 100644 --- a/apps/opencs/model/doc/savingstate.cpp +++ b/apps/opencs/model/doc/savingstate.cpp @@ -64,7 +64,7 @@ bool CSMDoc::SavingState::isProjectFile() const return mProjectFile; } -std::map >& CSMDoc::SavingState::getSubRecords() +std::map >& CSMDoc::SavingState::getSubRecords() { return mSubRecords; } diff --git a/apps/opencs/model/doc/savingstate.hpp b/apps/opencs/model/doc/savingstate.hpp index 577fc734d6..e6c8c545a7 100644 --- a/apps/opencs/model/doc/savingstate.hpp +++ b/apps/opencs/model/doc/savingstate.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -26,7 +27,7 @@ namespace CSMDoc ESM::ESMWriter mWriter; boost::filesystem::path mProjectPath; bool mProjectFile; - std::map > mSubRecords; // record ID, list of subrecords + std::map > mSubRecords; // record ID, list of subrecords public: @@ -49,7 +50,7 @@ namespace CSMDoc bool isProjectFile() const; ///< Currently saving project file? (instead of content file) - std::map >& getSubRecords(); + std::map >& getSubRecords(); }; diff --git a/components/esm/cellref.cpp b/components/esm/cellref.cpp index a14f977d64..0e258571f6 100644 --- a/components/esm/cellref.cpp +++ b/components/esm/cellref.cpp @@ -17,7 +17,11 @@ void ESM::RefNum::save (ESMWriter &esm, bool wide) const if (wide) esm.writeHNT ("FRMR", *this, 8); else - esm.writeHNT ("FRMR", mIndex, 4); + { + int refNum = (mIndex & 0xffffff) | ((mContentFile==-1 ? 0xff : mContentFile)<<24); + + esm.writeHNT ("FRMR", refNum, 4); + } } From 89998a6a036fa22cbb81b9113f534571eb3c7a1e Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 24 Jan 2015 14:22:29 +0100 Subject: [PATCH 085/185] save MVRF subrecords --- apps/opencs/model/doc/savingstages.cpp | 5 +---- components/esm/cellref.cpp | 6 +++--- components/esm/cellref.hpp | 2 +- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index 6b8750b446..4354a03130 100644 --- a/apps/opencs/model/doc/savingstages.cpp +++ b/apps/opencs/model/doc/savingstages.cpp @@ -314,10 +314,7 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages) char ignore; stream >> ignore >> moved.mTarget[0] >> moved.mTarget[1]; - mState.getWriter().startSubRecord ("MVRF"); - - mState.getWriter().endRecord ("MVRF"); - mState.getWriter().writeHNT ("FRMR", moved.mRefNum.mIndex, 4); + ref.get().mRefNum.save (mState.getWriter(), false, "MVRF"); mState.getWriter().writeHNT ("CNDT", moved.mTarget, 8); } diff --git a/components/esm/cellref.cpp b/components/esm/cellref.cpp index 0e258571f6..546151e276 100644 --- a/components/esm/cellref.cpp +++ b/components/esm/cellref.cpp @@ -12,15 +12,15 @@ void ESM::RefNum::load (ESMReader& esm, bool wide) esm.getHNT (mIndex, "FRMR"); } -void ESM::RefNum::save (ESMWriter &esm, bool wide) const +void ESM::RefNum::save (ESMWriter &esm, bool wide, const std::string& tag) const { if (wide) - esm.writeHNT ("FRMR", *this, 8); + esm.writeHNT (tag, *this, 8); else { int refNum = (mIndex & 0xffffff) | ((mContentFile==-1 ? 0xff : mContentFile)<<24); - esm.writeHNT ("FRMR", refNum, 4); + esm.writeHNT (tag, refNum, 4); } } diff --git a/components/esm/cellref.hpp b/components/esm/cellref.hpp index 505f676b18..d4e63d6e89 100644 --- a/components/esm/cellref.hpp +++ b/components/esm/cellref.hpp @@ -18,7 +18,7 @@ namespace ESM void load (ESMReader& esm, bool wide = false); - void save (ESMWriter &esm, bool wide = false) const; + void save (ESMWriter &esm, bool wide = false, const std::string& tag = "FRMR") const; }; /* Cell reference. This represents ONE object (of many) inside the From 7f905470fae10ac8d5665b19adbc995a92cb720d Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 24 Jan 2015 15:01:38 +0100 Subject: [PATCH 086/185] fixed moved reference loading --- apps/opencs/model/world/refcollection.cpp | 3 +-- components/esm/cellref.cpp | 5 +++-- components/esm/loadcell.cpp | 20 +++++++++++++++----- components/esm/loadcell.hpp | 3 ++- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/apps/opencs/model/world/refcollection.cpp b/apps/opencs/model/world/refcollection.cpp index dcb295626a..39f85da708 100644 --- a/apps/opencs/model/world/refcollection.cpp +++ b/apps/opencs/model/world/refcollection.cpp @@ -21,7 +21,7 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool bool deleted = false; - while (ESM::Cell::getNextRef (reader, ref, deleted)) + while (ESM::Cell::getNextRef (reader, ref, deleted, true)) { // Keep mOriginalCell empty when in modified (as an indicator that the // original cell will always be equal the current cell). @@ -29,7 +29,6 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool if (cell.get().isExterior()) { - // ignoring moved references sub-record; instead calculate cell from coordinates std::pair index = ref.getCellIndex(); diff --git a/components/esm/cellref.cpp b/components/esm/cellref.cpp index 546151e276..8579d891f0 100644 --- a/components/esm/cellref.cpp +++ b/components/esm/cellref.cpp @@ -25,7 +25,7 @@ void ESM::RefNum::save (ESMWriter &esm, bool wide, const std::string& tag) const } -void ESM::CellRef::load (ESMReader& esm, bool wideRefNum) +void ESM::CellRef::load (ESMReader& esm, bool wideRefNum, bool ignoreRefNum) { // According to Hrnchamd, this does not belong to the actual ref. Instead, it is a marker indicating that // the following refs are part of a "temp refs" section. A temp ref is not being tracked by the moved references system. @@ -34,7 +34,8 @@ void ESM::CellRef::load (ESMReader& esm, bool wideRefNum) if (esm.isNextSub ("NAM0")) esm.skipHSub(); - mRefNum.load (esm, wideRefNum); + if (!ignoreRefNum) + mRefNum.load (esm, wideRefNum); mRefID = esm.getHNString ("NAME"); diff --git a/components/esm/loadcell.cpp b/components/esm/loadcell.cpp index e4f847dec2..d836ec9cfd 100644 --- a/components/esm/loadcell.cpp +++ b/components/esm/loadcell.cpp @@ -168,7 +168,7 @@ std::string Cell::getDescription() const } } -bool Cell::getNextRef(ESMReader &esm, CellRef &ref, bool& deleted) +bool Cell::getNextRef(ESMReader &esm, CellRef &ref, bool& deleted, bool ignoreMoves) { // TODO: Try and document reference numbering, I don't think this has been done anywhere else. if (!esm.hasMoreSubs()) @@ -176,10 +176,20 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref, bool& deleted) // NOTE: We should not need this check. It is a safety check until we have checked // more plugins, and how they treat these moved references. - if (esm.isNextSub("MVRF")) { - // skip rest of cell record (moved references), they are handled elsewhere - esm.skipRecord(); // skip MVRF, CNDT - return false; + if (esm.isNextSub("MVRF")) + { + if (ignoreMoves) + { + MovedCellRef mref; + esm.getHT (mref.mRefNum.mIndex); + esm.getHNOT (mref.mTarget, "CNDT"); + } + else + { + // skip rest of cell record (moved references), they are handled elsewhere + esm.skipRecord(); // skip MVRF, CNDT + return false; + } } ref.load (esm); diff --git a/components/esm/loadcell.hpp b/components/esm/loadcell.hpp index e1a6eee1ab..8eeecd8931 100644 --- a/components/esm/loadcell.hpp +++ b/components/esm/loadcell.hpp @@ -156,7 +156,8 @@ struct Cell All fields of the CellRef struct are overwritten. You can safely reuse one memory location without blanking it between calls. */ - static bool getNextRef(ESMReader &esm, CellRef &ref, bool& deleted); + /// \param ignoreMoves ignore MVRF record and read reference like a regular CellRef. + static bool getNextRef(ESMReader &esm, CellRef &ref, bool& deleted, bool ignoreMoves = false); /* This fetches an MVRF record, which is used to track moved references. * Since they are comparably rare, we use a separate method for this. From 6d6ff8c6a47e102679b40c388b7dbf099c07cbba Mon Sep 17 00:00:00 2001 From: cc9cii Date: Fri, 6 Mar 2015 14:36:13 +1100 Subject: [PATCH 087/185] Resolved compile issues, but not fully working. --- apps/opencs/model/world/idtable.cpp | 26 ++++++------ apps/opencs/view/world/dialoguesubview.cpp | 46 +++++++++++----------- apps/opencs/view/world/dialoguesubview.hpp | 8 ++-- apps/opencs/view/world/nestedtable.cpp | 8 ++-- apps/opencs/view/world/nestedtable.hpp | 14 +++---- 5 files changed, 51 insertions(+), 51 deletions(-) diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index 2852cb581d..fc8ac66b74 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -31,7 +31,7 @@ int CSMWorld::IdTable::columnCount (const QModelIndex & parent) const { return dynamic_cast(mIdCollection)->getNestedColumnsCount(parent.row(), parent.column()); } - + return mIdCollection->getColumns(); } @@ -72,7 +72,7 @@ QVariant CSMWorld::IdTable::headerData (int section, { return mIdCollection->getColumn (section).mDisplayType; } - + return QVariant(); } @@ -104,7 +104,7 @@ bool CSMWorld::IdTable::setData (const QModelIndex &index, const QVariant &value const std::pair& parentAdress(unfoldIndexAdress(index.internalId())); dynamic_cast(mIdCollection)->setNestedData(parentAdress.first, parentAdress.second, value, index.row(), index.column()); - + emit dataChanged (CSMWorld::IdTable::index (parentAdress.first, 0), CSMWorld::IdTable::index (parentAdress.second, mIdCollection->getColumns()-1)); @@ -114,17 +114,17 @@ bool CSMWorld::IdTable::setData (const QModelIndex &index, const QVariant &value return false; } } - + if (mIdCollection->getColumn (index.column()).isEditable() && role==Qt::EditRole) { mIdCollection->setData (index.row(), index.column(), value); - + emit dataChanged (CSMWorld::IdTable::index (index.row(), 0), CSMWorld::IdTable::index (index.row(), mIdCollection->getColumns()-1)); - + return true; - } - + } + return false; } @@ -177,7 +177,7 @@ void CSMWorld::IdTable::addNestedRow(const QModelIndex& parent, int position) dynamic_cast(mIdCollection)->addNestedRow(row, parent.column(), position); endInsertRows(); - + emit dataChanged (CSMWorld::IdTable::index (row, 0), CSMWorld::IdTable::index (row, mIdCollection->getColumns()-1)); } @@ -353,7 +353,7 @@ std::pair< int, int > CSMWorld::IdTable::unfoldIndexAdress (unsigned int id) con --id; int row = id / this->columnCount(); int column = id - row * this->columnCount(); - return std::make_pair(row, column); + return std::make_pair (row, column); } bool CSMWorld::IdTable::hasChildren(const QModelIndex& index) const @@ -370,14 +370,14 @@ void CSMWorld::IdTable::setNestedTable(const QModelIndex& index, const CSMWorld: { throw std::logic_error("Tried to set nested table, but index has no children"); } - + bool removeRowsMode = false; if (nestedTable.size() != this->nestedTable(index)->size()) { emit resetStart(this->index(index.row(), 0).data().toString()); removeRowsMode = true; } - + dynamic_cast(mIdCollection)->setNestedTable(index.row(), index.column(), nestedTable); emit dataChanged (CSMWorld::IdTable::index (index.row(), 0), @@ -395,6 +395,6 @@ CSMWorld::NestedTableWrapperBase* CSMWorld::IdTable::nestedTable(const QModelInd { throw std::logic_error("Tried to retrive nested table, but index has no children"); } - + return dynamic_cast(mIdCollection)->nestedTable(index.row(), index.column()); } diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index f6ad79a6a9..a2b6f45f10 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -281,7 +281,7 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase:: connect(proxy, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)), this, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*))); - skip = true; + //skip = true; } else if (qobject_cast(editor)) { @@ -298,7 +298,7 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase:: else if (qobject_cast(editor)) { connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited())); - } //lisp cond pairs would be nice in the C++ + } connect(proxy, SIGNAL(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display)), this, SLOT(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display))); @@ -328,8 +328,8 @@ CSVWorld::EditWidget::~EditWidget() } } -CSVWorld::EditWidget::EditWidget(QWidget *parent, int row, CSMWorld::IdTable* table, QUndoStack& undoStack, bool createAndDelete) : -mDispatcher(this, table, undoStack), +CSVWorld::EditWidget::EditWidget(QWidget *parent, int row, CSMWorld::IdTable* table, CSMDoc::Document& document, bool createAndDelete) : +mDispatcher(this, table, document), QScrollArea(parent), mWidgetMapper(NULL), mMainWidget(NULL), @@ -338,7 +338,7 @@ mTable(table) { remake (row); - connect(&mDispatcher, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)), + connect(&mDispatcher, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)), this, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*))); } @@ -349,7 +349,7 @@ void CSVWorld::EditWidget::remake(int row) delete mNestedModels[i]; } mNestedModels.clear(); - + if (mMainWidget) { delete mMainWidget; @@ -401,8 +401,8 @@ void CSVWorld::EditWidget::remake(int row) if (mTable->hasChildren(mTable->index(row, i))) { mNestedModels.push_back(new CSMWorld::NestedTableModel (mTable->index(row, i), display, mTable)); - - NestedTable* table = new NestedTable(mUndoStack, *(mNestedModels.rbegin()), this); + + NestedTable* table = new NestedTable(mDocument, *(mNestedModels.rbegin()), this); tablesLayout->addWidget(table); } else @@ -517,7 +517,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM mMainLayout = new QVBoxLayout(mainWidget); - mEditWidget = new EditWidget(mainWidget, mTable->getModelIndex(mCurrentId, 0).row(), mTable, mUndoStack, false); + mEditWidget = new EditWidget(mainWidget, mTable->getModelIndex(mCurrentId, 0).row(), mTable, document, false); connect(mEditWidget, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)), this, SLOT(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*))); @@ -570,7 +570,7 @@ void CSVWorld::DialogueSubView::prevId () setUniversalId(CSMWorld::UniversalId (static_cast (mTable->data (mTable->index (newRow, 2)).toInt()), mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData())); - changeCurrentId(std::string(mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData())); + changeCurrentId(std::string(mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData())); mEditWidget->setDisabled(mLocked); @@ -604,9 +604,9 @@ void CSVWorld::DialogueSubView::nextId () mEditWidget->remake(newRow); setUniversalId(CSMWorld::UniversalId (static_cast (mTable->data (mTable->index (newRow, 2)).toInt()), - mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData())); + mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData())); - changeCurrentId(std::string(mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData())); + changeCurrentId(std::string(mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData())); mEditWidget->setDisabled(mLocked); @@ -623,11 +623,11 @@ void CSVWorld::DialogueSubView::setEditLock (bool locked) if (currentIndex.isValid()) { - CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (currentIndex.row(), 1)).toInt()); + CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (currentIndex.row(), 1)).toInt()); - mEditWidget->setDisabled (state==CSMWorld::RecordBase::State_Deleted || locked); + mEditWidget->setDisabled (state==CSMWorld::RecordBase::State_Deleted || locked); - mCommandDispatcher.setEditLock (locked); + mCommandDispatcher.setEditLock (locked); } } @@ -640,14 +640,14 @@ void CSVWorld::DialogueSubView::dataChanged (const QModelIndex & index) { CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (currentIndex.row(), 1)).toInt()); - mEditWidget->setDisabled (state==CSMWorld::RecordBase::State_Deleted || mLocked); + mEditWidget->setDisabled (state==CSMWorld::RecordBase::State_Deleted || mLocked); } } void CSVWorld::DialogueSubView::tableMimeDataDropped (QWidget* editor, - const QModelIndex& index, - const CSMWorld::UniversalId& id, - const CSMDoc::Document* document) + const QModelIndex& index, + const CSMWorld::UniversalId& id, + const CSMDoc::Document* document) { if (document == &mDocument) { @@ -672,10 +672,10 @@ void CSVWorld::DialogueSubView::showPreview () QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0)); if (currentIndex.isValid() && - mTable->getFeatures() & CSMWorld::IdTable::Feature_Preview && - currentIndex.row() < mTable->rowCount()) + mTable->getFeatures() & CSMWorld::IdTable::Feature_Preview && + currentIndex.row() < mTable->rowCount()) { - emit focusId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Preview, mCurrentId), ""); + emit focusId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Preview, mCurrentId), ""); } } @@ -684,7 +684,7 @@ void CSVWorld::DialogueSubView::viewRecord () QModelIndex currentIndex(mTable->getModelIndex (mCurrentId, 0)); if (currentIndex.isValid() && - currentIndex.row() < mTable->rowCount()) + currentIndex.row() < mTable->rowCount()) { std::pair params = mTable->view (currentIndex.row()); diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index 3f48aef428..45581bc3f1 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -118,12 +118,12 @@ namespace CSVWorld NotEditableSubDelegate mNotEditableDelegate; std::vector mProxys; -//once we move to the C++11 we should use unique_ptr + //once we move to the C++11 we should use unique_ptr public: DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, - QUndoStack& undoStack); + CSMDoc::Document& document); ~DialogueDelegateDispatcher(); @@ -175,10 +175,10 @@ namespace CSVWorld public: EditWidget (QWidget *parent, int row, CSMWorld::IdTable* table, - QUndoStack& undoStack, bool createAndDelete = false); + CSMDoc::Document& document, bool createAndDelete = false); virtual ~EditWidget(); - + void remake(int row); signals: diff --git a/apps/opencs/view/world/nestedtable.cpp b/apps/opencs/view/world/nestedtable.cpp index 21bef504bc..14e079c983 100644 --- a/apps/opencs/view/world/nestedtable.cpp +++ b/apps/opencs/view/world/nestedtable.cpp @@ -9,11 +9,11 @@ #include #include -CSVWorld::NestedTable::NestedTable(QUndoStack& undoStack, +CSVWorld::NestedTable::NestedTable(CSMDoc::Document& document, CSMWorld::NestedTableModel* model, QWidget* parent) : QTableView(parent), - mUndoStack(undoStack), + mUndoStack(document.getUndoStack()), mModel(model) { @@ -31,9 +31,9 @@ CSVWorld::NestedTable::NestedTable(QUndoStack& undoStack, model->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); CommandDelegate *delegate = CommandDelegateFactoryCollection::get().makeDelegate(display, - undoStack, + document, this); - + setItemDelegateForColumn(i, delegate); } diff --git a/apps/opencs/view/world/nestedtable.hpp b/apps/opencs/view/world/nestedtable.hpp index 35fa224949..6b6b6aabab 100644 --- a/apps/opencs/view/world/nestedtable.hpp +++ b/apps/opencs/view/world/nestedtable.hpp @@ -29,23 +29,23 @@ namespace CSVWorld QAction *mRemoveRowAction; QUndoStack& mUndoStack; CSMWorld::NestedTableModel* mModel; - + public: - NestedTable(QUndoStack& undoStack, + NestedTable(CSMDoc::Document& document, CSMWorld::NestedTableModel* model, QWidget* parent = NULL); - + protected: void dragEnterEvent(QDragEnterEvent *event); - + void dragMoveEvent(QDragMoveEvent *event); - + private: void contextMenuEvent (QContextMenuEvent *event); - + private slots: void removeRowActionTriggered(); - + void addNewRowActionTriggered(); }; } From 727b68dd15472a2a647966db85bd2d1d6b931b90 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Fri, 6 Mar 2015 19:20:50 +1100 Subject: [PATCH 088/185] Reduce difference with the master branch where possible. --- apps/opencs/CMakeLists.txt | 5 +-- apps/opencs/model/doc/document.cpp | 5 ++- apps/opencs/model/tools/startscriptcheck.cpp | 31 +++++++++++++++++++ apps/opencs/model/tools/startscriptcheck.hpp | 28 +++++++++++++++++ apps/opencs/model/tools/tools.cpp | 3 ++ apps/opencs/model/world/collection.hpp | 4 +-- apps/opencs/model/world/collectionbase.cpp | 3 +- apps/opencs/model/world/columnimp.hpp | 1 - apps/opencs/view/world/enumdelegate.cpp | 1 + apps/opencs/view/world/util.cpp | 2 +- apps/openmw/mwmechanics/activespells.cpp | 2 +- .../mwscript/transformationextensions.cpp | 2 ++ .../contentselector/view/contentselector.cpp | 1 + 13 files changed, 75 insertions(+), 13 deletions(-) create mode 100644 apps/opencs/model/tools/startscriptcheck.cpp create mode 100644 apps/opencs/model/tools/startscriptcheck.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index ab3765bb6f..2125deeff5 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -19,7 +19,7 @@ opencs_hdrs_noqt (model/doc opencs_units (model/world idtable idtableproxymodel regionmap data commanddispatcher - idtablebase resourcetable nestedtablemodel + idtablebase resourcetable nestedtablemodel ) @@ -41,6 +41,7 @@ opencs_units (model/tools opencs_units_noqt (model/tools mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck birthsigncheck spellcheck referencecheck referenceablecheck scriptcheck bodypartcheck + startscriptcheck ) @@ -64,7 +65,7 @@ opencs_units (view/world cellcreator referenceablecreator referencecreator scenesubview infocreator scriptedit dialoguesubview previewsubview regionmap dragrecordtable nestedtable ) - + opencs_units_noqt (view/world subviews enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate scripthighlighter idvalidator dialoguecreator physicssystem diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 61fe4b3221..e688a9474a 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2,7 +2,6 @@ #include #include -#include #include @@ -2243,7 +2242,7 @@ void CSMDoc::Document::createBase() record.blank(); getData().getMagicEffects().add (record); -} + } } CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, @@ -2265,7 +2264,7 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, { boost::filesystem::path customFiltersPath (configuration.getUserDataPath()); customFiltersPath /= "defaultfilters"; - + std::ofstream destination (mProjectPath.string().c_str(), std::ios::binary); if (boost::filesystem::exists (customFiltersPath)) diff --git a/apps/opencs/model/tools/startscriptcheck.cpp b/apps/opencs/model/tools/startscriptcheck.cpp new file mode 100644 index 0000000000..e3c01368bd --- /dev/null +++ b/apps/opencs/model/tools/startscriptcheck.cpp @@ -0,0 +1,31 @@ + +#include "startscriptcheck.hpp" + +#include + +CSMTools::StartScriptCheckStage::StartScriptCheckStage ( + const CSMWorld::IdCollection& startScripts, + const CSMWorld::IdCollection& scripts) +: mStartScripts (startScripts), mScripts (scripts) +{} + +void CSMTools::StartScriptCheckStage::perform(int stage, CSMDoc::Messages& messages) +{ + const CSMWorld::Record& record = mStartScripts.getRecord (stage); + + if (record.isDeleted()) + return; + + std::string scriptId = record.get().mId; + + CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_StartScript, scriptId); + + if (mScripts.searchId (Misc::StringUtils::lowerCase (scriptId))==-1) + messages.push_back ( + std::make_pair (id, "Start script " + scriptId + " does not exist")); +} + +int CSMTools::StartScriptCheckStage::setup() +{ + return mStartScripts.getSize(); +} diff --git a/apps/opencs/model/tools/startscriptcheck.hpp b/apps/opencs/model/tools/startscriptcheck.hpp new file mode 100644 index 0000000000..cb82cbae7d --- /dev/null +++ b/apps/opencs/model/tools/startscriptcheck.hpp @@ -0,0 +1,28 @@ +#ifndef CSM_TOOLS_STARTSCRIPTCHECK_H +#define CSM_TOOLS_STARTSCRIPTCHECK_H + +#include +#include + +#include "../doc/stage.hpp" + +#include "../world/idcollection.hpp" + +namespace CSMTools +{ + class StartScriptCheckStage : public CSMDoc::Stage + { + const CSMWorld::IdCollection& mStartScripts; + const CSMWorld::IdCollection& mScripts; + + public: + + StartScriptCheckStage (const CSMWorld::IdCollection& startScripts, + const CSMWorld::IdCollection& scripts); + + virtual void perform(int stage, CSMDoc::Messages& messages); + virtual int setup(); + }; +} + +#endif diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index e78758bb67..2139f890f8 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -24,6 +24,7 @@ #include "scriptcheck.hpp" #include "bodypartcheck.hpp" #include "referencecheck.hpp" +#include "startscriptcheck.hpp" CSMDoc::Operation *CSMTools::Tools::get (int type) { @@ -84,6 +85,8 @@ CSMDoc::Operation *CSMTools::Tools::getVerifier() mVerifier->appendStage (new ScriptCheckStage (mDocument)); + mVerifier->appendStage (new StartScriptCheckStage (mData.getStartScripts(), mData.getScripts())); + mVerifier->appendStage( new BodyPartCheckStage( mData.getBodyParts(), diff --git a/apps/opencs/model/world/collection.hpp b/apps/opencs/model/world/collection.hpp index 5c32e7716d..1fb3e1f1db 100644 --- a/apps/opencs/model/world/collection.hpp +++ b/apps/opencs/model/world/collection.hpp @@ -2,13 +2,11 @@ #define CSM_WOLRD_COLLECTION_H #include -#include #include #include #include #include #include -#include #include @@ -94,7 +92,7 @@ namespace CSMWorld virtual void purge(); ///< Remove records that are flagged as erased. - virtual void removeRows (int index, int count); + virtual void removeRows (int index, int count) ; virtual void appendBlankRecord (const std::string& id, UniversalId::Type type = UniversalId::Type_None); diff --git a/apps/opencs/model/world/collectionbase.cpp b/apps/opencs/model/world/collectionbase.cpp index 5b0c359c91..241f198cb2 100644 --- a/apps/opencs/model/world/collectionbase.cpp +++ b/apps/opencs/model/world/collectionbase.cpp @@ -2,7 +2,6 @@ #include "collectionbase.hpp" #include -#include #include "columnbase.hpp" @@ -29,4 +28,4 @@ int CSMWorld::CollectionBase::findColumnIndex (Columns::ColumnId id) const throw std::logic_error ("invalid column index"); return index; -} +} \ No newline at end of file diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index dc8edbc519..da14bb4955 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -6,7 +6,6 @@ #include #include -#include #include diff --git a/apps/opencs/view/world/enumdelegate.cpp b/apps/opencs/view/world/enumdelegate.cpp index 7c305b1b6b..168e5cb0a3 100644 --- a/apps/opencs/view/world/enumdelegate.cpp +++ b/apps/opencs/view/world/enumdelegate.cpp @@ -46,6 +46,7 @@ QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent, const QModelIndex& index) const { return createEditor(parent, option, index, CSMWorld::ColumnBase::Display_None); + //overloading virtual functions is HARD } QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem& option, diff --git a/apps/opencs/view/world/util.cpp b/apps/opencs/view/world/util.cpp index 11521bb67d..c65e12c609 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -186,7 +186,7 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO } case CSMWorld::ColumnBase::Display_Boolean: - + return new QCheckBox(parent); case CSMWorld::ColumnBase::Display_String: diff --git a/apps/openmw/mwmechanics/activespells.cpp b/apps/openmw/mwmechanics/activespells.cpp index eec4f2bd37..b4701126b3 100644 --- a/apps/openmw/mwmechanics/activespells.cpp +++ b/apps/openmw/mwmechanics/activespells.cpp @@ -185,7 +185,7 @@ namespace MWMechanics bool missing = true; for (std::vector::const_iterator iter(addTo.begin()); iter != addTo.end(); ++iter) { - if (effect->mEffectId == iter->mEffectId) + if ((effect->mEffectId == iter->mEffectId) && (effect->mArg == iter->mArg)) { missing = false; break; diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index 9166bf9099..734df7d74e 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -316,6 +316,7 @@ namespace MWScript store = MWBase::Environment::get().getWorld()->getExterior(cx,cy); if(!cell) { + runtime.getContext().report ("unknown cell (" + cellID + ")"); std::cerr << "unknown cell (" << cellID << ")\n"; } } @@ -428,6 +429,7 @@ namespace MWScript store = MWBase::Environment::get().getWorld()->getExterior(cx,cy); if(!cell) { + runtime.getContext().report ("unknown cell (" + cellID + ")"); std::cerr << "unknown cell (" << cellID << ")\n"; } } diff --git a/components/contentselector/view/contentselector.cpp b/components/contentselector/view/contentselector.cpp index 2363ae477a..e3093d5685 100644 --- a/components/contentselector/view/contentselector.cpp +++ b/components/contentselector/view/contentselector.cpp @@ -183,6 +183,7 @@ void ContentSelectorView::ContentSelector::setGameFileSelected(int index, bool s void ContentSelectorView::ContentSelector::slotAddonTableItemActivated(const QModelIndex &index) { + // toggles check state when an AddOn file is double clicked or activated by keyboard QModelIndex sourceIndex = mAddonProxyModel->mapToSource (index); if (!mContentModel->isEnabled (sourceIndex)) From ca21181483d203de200c3ee963a3abe07f5ede14 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 7 Mar 2015 11:42:50 +1100 Subject: [PATCH 089/185] Fix typo to get table display working. --- apps/opencs/model/world/columnbase.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 5926df2694..607f585b76 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -145,9 +145,9 @@ namespace CSMWorld void addNestedColumn(int columnId, Display displayType); bool canHaveNestedColumns() const; - + const ColumnBase& nestedColumn(int subColumn) const; - + int nestedColumnCount() const; }; @@ -157,15 +157,15 @@ namespace CSMWorld public: NestedColumn(int columnId, Display displayType, int flag, const NestColumn* parent); - + virtual bool isEditable() const; }; - + template struct Column : public NestColumn { Column (int columnId, Display displayType, int flags = Flag_Table | Flag_Dialogue, bool canNest = false) - : NestColumn (columnId, displayType, canNest, flags) {} + : NestColumn (columnId, displayType, flags, canNest) {} virtual QVariant get (const Record& record) const = 0; From 76adb64e20f90d58d53e43aa2d2587ea89992924 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 16 Mar 2015 13:21:02 +1100 Subject: [PATCH 090/185] Compilation fix after merging commt e30f24 --- apps/opencs/model/world/nestedadaptors.hpp | 134 ++++++++++----------- 1 file changed, 66 insertions(+), 68 deletions(-) diff --git a/apps/opencs/model/world/nestedadaptors.hpp b/apps/opencs/model/world/nestedadaptors.hpp index 6e3d447b29..cc062e827a 100644 --- a/apps/opencs/model/world/nestedadaptors.hpp +++ b/apps/opencs/model/world/nestedadaptors.hpp @@ -34,16 +34,16 @@ namespace CSMWorld public: HelperBase(CSMWorld::UniversalId::Type type); - + virtual ~HelperBase(); - + virtual void setNestedTable(RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) = 0; - + virtual NestedTableWrapperBase* nestedTable(const RefIdData& data, int index) const = 0; - + virtual QVariant getNestedData(const CSMWorld::RefIdData& data, int index, int subRowIndex, @@ -58,7 +58,7 @@ namespace CSMWorld const QVariant& value, int subRowIndex, int subColIndex) const = 0; - + virtual void addNestedRow (RefIdData& data, int index, int position) const = 0; @@ -72,7 +72,7 @@ namespace CSMWorld template class CastableHelper : public HelperBase { - + public: CastableHelper(CSMWorld::UniversalId::Type type) : HelperBase(type) {} @@ -96,23 +96,23 @@ namespace CSMWorld { public: - SpellsHelper(CSMWorld::UniversalId::Type type) + SpellsHelper(CSMWorld::UniversalId::Type type) : CastableHelper(type) {} virtual void setNestedTable(RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) { - CastableHelper::getRecord(data, index).get().mSpells.mList = + CastableHelper::getRecord(data, index).get().mSpells.mList = (static_cast >&>(nestedTable)).mNestedTable; } - + virtual NestedTableWrapperBase* nestedTable(const RefIdData& data, int index) const { return new NestedTableWrapper >(CastableHelper::getRecord(data, index).get().mSpells.mList); } - + virtual QVariant getNestedData(const CSMWorld::RefIdData& data, int index, int subRowIndex, @@ -124,7 +124,7 @@ namespace CSMWorld { return QString::fromUtf8(content.c_str()); } - + throw std::logic_error("Trying to access non-existing column in the nested table!"); } @@ -144,11 +144,11 @@ namespace CSMWorld if (subColIndex == 0) { CastableHelper::getRecord(data, index).get().mSpells.mList.at(subRowIndex) = std::string(value.toString().toUtf8()); - } + } throw std::logic_error("Trying to access non-existing column in the nested table!"); } - + virtual void addNestedRow (RefIdData& data, int index, int position) const { std::vector& list = CastableHelper::getRecord(data, index).get().mSpells.mList; @@ -159,15 +159,15 @@ namespace CSMWorld list.push_back(newString); return; } - + list.insert(list.begin()+position, newString); } - + virtual int getNestedColumnsCount(const RefIdData& data) const { return 1; } - + virtual int getNestedRowsCount(const RefIdData& data, int index) const @@ -183,23 +183,23 @@ namespace CSMWorld { public: - MagicEffectsHelper(CSMWorld::UniversalId::Type type) + MagicEffectsHelper(CSMWorld::UniversalId::Type type) : CastableHelper(type) {} virtual void setNestedTable(RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) { - CastableHelper::getRecord(data, index).get().mEffects = + CastableHelper::getRecord(data, index).get().mEffects = (static_cast&>(nestedTable)).mNestedTable; } - + virtual NestedTableWrapperBase* nestedTable(const RefIdData& data, int index) const { return new NestedTableWrapper(CastableHelper::getRecord(data, index).get().mEffects); } - + virtual QVariant getNestedData(const CSMWorld::RefIdData& data, int index, int subRowIndex, @@ -211,7 +211,7 @@ namespace CSMWorld { case 0: return content.at(subRowIndex).mEffectID; - + case 1: return content.at(subRowIndex).mRange; @@ -226,13 +226,13 @@ namespace CSMWorld case 5: return content.at(subRowIndex).mMagMax; - + case 6: return (int)content.at(rubRowIndex).mSkill; case 7: return (int)content.at(subRowIndex).mAttribute; - + default: throw std::logic_error("Trying to access non-existing column in the nested table!"); } @@ -261,10 +261,10 @@ namespace CSMWorld throw std::logic_error("Trying to access non-existing column in the nested table!"); } } - + virtual void addNestedRow (RefIdData& data, int index, int position) const { - std::vector& list = CastableHelper::getRecord(data, index).get().mTransport; + std::vector& list = CastableHelper::getRecord(data, index).get().mTransport.mList; ESM::Position newPos; for (unsigned i = 0; i < 3; ++i) @@ -273,7 +273,7 @@ namespace CSMWorld newPos.rot[i] = 0; } - ESM::NPC::Dest newRow; + ESM::Transport::Dest newRow; newRow.mPos = newPos; newRow.mCellName = ""; @@ -282,20 +282,20 @@ namespace CSMWorld list.push_back(newRow); return; } - + list.insert(list.begin()+position, newRow); } - + virtual int getNestedColumnsCount(const RefIdData& data) const { return 7; } - + virtual int getNestedRowsCount(const RefIdData& data, int index) const { - return CastableHelper::getRecord(data, index).get().mTransport.size(); + return CastableHelper::getRecord(data, index).get().mTransport.mList.size(); } }; @@ -305,35 +305,35 @@ namespace CSMWorld { public: - DestinationsHelper(CSMWorld::UniversalId::Type type) + DestinationsHelper(CSMWorld::UniversalId::Type type) : CastableHelper(type) {} virtual void setNestedTable(RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) { - CastableHelper::getRecord(data, index).get().mTransport = - (static_cast >&>(nestedTable)).mNestedTable; + CastableHelper::getRecord(data, index).get().mTransport.mList = + (static_cast >&>(nestedTable)).mNestedTable; } - + virtual NestedTableWrapperBase* nestedTable(const RefIdData& data, int index) const { - return new NestedTableWrapper >(CastableHelper::getRecord(data, index).get().mTransport); + return new NestedTableWrapper >(CastableHelper::getRecord(data, index).get().mTransport.mList); } - + virtual QVariant getNestedData(const CSMWorld::RefIdData& data, int index, int subRowIndex, int subColIndex) const { - const ESM::NPC::Dest& content = CastableHelper::getRecord(data, index).get().mTransport.at(subRowIndex); + const ESM::Transport::Dest& content = CastableHelper::getRecord(data, index).get().mTransport.mList.at(subRowIndex); switch (subColIndex) { case 0: return QString::fromUtf8(content.mCellName.c_str()); - + case 1: return content.mPos.pos[0]; @@ -351,7 +351,7 @@ namespace CSMWorld case 6: return content.mPos.rot[2]; - + default: throw std::logic_error("Trying to access non-existing column in the nested table!"); } @@ -359,7 +359,7 @@ namespace CSMWorld virtual void removeNestedRow (RefIdData& data, int index, int rowToRemove) const { - std::vector& list = CastableHelper::getRecord(data, index).get().mTransport; + std::vector& list = CastableHelper::getRecord(data, index).get().mTransport.mList; list.erase (list.begin () + rowToRemove); } @@ -373,41 +373,41 @@ namespace CSMWorld switch(subColIndex) { case 0: - CastableHelper::getRecord(data, index).get().mTransport.at(subRowIndex).mCellName = std::string(value.toString().toUtf8().constData()); + CastableHelper::getRecord(data, index).get().mTransport.mList.at(subRowIndex).mCellName = std::string(value.toString().toUtf8().constData()); break; case 1: - CastableHelper::getRecord(data, index).get().mTransport.at(subRowIndex).mPos.pos[0] = value.toFloat(); + CastableHelper::getRecord(data, index).get().mTransport.mList.at(subRowIndex).mPos.pos[0] = value.toFloat(); break; - + case 2: - CastableHelper::getRecord(data, index).get().mTransport.at(subRowIndex).mPos.pos[1] = value.toFloat(); + CastableHelper::getRecord(data, index).get().mTransport.mList.at(subRowIndex).mPos.pos[1] = value.toFloat(); break; - + case 3: - CastableHelper::getRecord(data, index).get().mTransport.at(subRowIndex).mPos.pos[2] = value.toFloat(); + CastableHelper::getRecord(data, index).get().mTransport.mList.at(subRowIndex).mPos.pos[2] = value.toFloat(); break; - + case 4: - CastableHelper::getRecord(data, index).get().mTransport.at(subRowIndex).mPos.rot[0] = value.toFloat(); + CastableHelper::getRecord(data, index).get().mTransport.mList.at(subRowIndex).mPos.rot[0] = value.toFloat(); break; case 5: - CastableHelper::getRecord(data, index).get().mTransport.at(subRowIndex).mPos.rot[1] = value.toFloat(); + CastableHelper::getRecord(data, index).get().mTransport.mList.at(subRowIndex).mPos.rot[1] = value.toFloat(); break; case 6: - CastableHelper::getRecord(data, index).get().mTransport.at(subRowIndex).mPos.rot[2] = value.toFloat(); + CastableHelper::getRecord(data, index).get().mTransport.mList.at(subRowIndex).mPos.rot[2] = value.toFloat(); break; default: throw std::logic_error("Trying to access non-existing column in the nested table!"); } } - + virtual void addNestedRow (RefIdData& data, int index, int position) const { - std::vector& list = CastableHelper::getRecord(data, index).get().mTransport; + std::vector& list = CastableHelper::getRecord(data, index).get().mTransport.mList; ESM::Position newPos; for (unsigned i = 0; i < 3; ++i) @@ -416,7 +416,7 @@ namespace CSMWorld newPos.rot[i] = 0; } - ESM::NPC::Dest newRow; + ESM::Transport::Dest newRow; newRow.mPos = newPos; newRow.mCellName = ""; @@ -425,20 +425,19 @@ namespace CSMWorld list.push_back(newRow); return; } - + list.insert(list.begin()+position, newRow); } - + virtual int getNestedColumnsCount(const RefIdData& data) const { return 7; } - virtual int getNestedRowsCount(const RefIdData& data, int index) const { - return CastableHelper::getRecord(data, index).get().mTransport.size(); + return CastableHelper::getRecord(data, index).get().mTransport.mList.size(); } }; @@ -448,23 +447,23 @@ namespace CSMWorld { public: - InventoryHelper(CSMWorld::UniversalId::Type type) + InventoryHelper(CSMWorld::UniversalId::Type type) : CastableHelper(type) {} virtual void setNestedTable(RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) { - CastableHelper::getRecord(data, index).get().mInventory.mList = + CastableHelper::getRecord(data, index).get().mInventory.mList = (static_cast >&>(nestedTable)).mNestedTable; } - + virtual NestedTableWrapperBase* nestedTable(const RefIdData& data, int index) const { return new NestedTableWrapper >(CastableHelper::getRecord(data, index).get().mInventory.mList); } - + virtual QVariant getNestedData(const CSMWorld::RefIdData& data, int index, int subRowIndex, @@ -476,10 +475,10 @@ namespace CSMWorld { case 0: return QString::fromUtf8(content.mItem.toString().c_str()); - + case 1: return content.mCount; - + default: throw std::logic_error("Trying to access non-existing column in the nested table!"); } @@ -507,12 +506,12 @@ namespace CSMWorld case 1: CastableHelper::getRecord(data, index).get().mInventory.mList.at(subRowIndex).mCount = value.toInt(); break; - + default: throw std::logic_error("Trying to access non-existing column in the nested table!"); } } - + virtual void addNestedRow (RefIdData& data, int index, int position) const { std::vector& list = CastableHelper::getRecord(data, index).get().mInventory.mList; @@ -523,15 +522,14 @@ namespace CSMWorld list.push_back(newRow); return; } - + list.insert(list.begin()+position, newRow); } - + virtual int getNestedColumnsCount(const RefIdData& data) const { return 2; } - virtual int getNestedRowsCount(const RefIdData& data, int index) const From 7bc0d41bb060f59e5356244119ca2f32406dbf9d Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 19 Mar 2015 15:51:45 +0100 Subject: [PATCH 091/185] Marker collision fix (Fixes #2461) --- components/nifbullet/bulletnifloader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/nifbullet/bulletnifloader.cpp b/components/nifbullet/bulletnifloader.cpp index cdc06f985b..93c9797b25 100644 --- a/components/nifbullet/bulletnifloader.cpp +++ b/components/nifbullet/bulletnifloader.cpp @@ -274,9 +274,9 @@ void ManualBulletShapeLoader::handleNode(const Nif::Node *node, int flags, // No collision. Use an internal flag setting to mark this. flags |= 0x800; } - else if (sd->string == "MRK" && !mShowMarkers && raycasting) + else if (sd->string == "MRK" && !mShowMarkers && (raycasting || mShape->mAutogenerated)) { - // Marker objects should be invisible, but still have collision. + // Marker objects should be invisible, but can still have collision if the model explicitely specifies it via a RootCollisionNode. // Except in the editor, the marker objects are visible. return; } From 5cb61fa01cc8cbaacec8f348f473bff7d3781619 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 22 Mar 2015 17:25:23 +0100 Subject: [PATCH 092/185] Don't mark gold as stolen, adjust stolen tooltip (Fixes #2465) --- apps/openmw/mwgui/tooltips.cpp | 5 ++++- apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index 4e03b788a4..4e83c25db3 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -593,7 +593,10 @@ namespace MWGui for (std::vector >::const_iterator it = itemOwners.begin(); it != itemOwners.end(); ++it) { - ret += std::string("\nStolen from ") + it->first; + if (it->second == std::numeric_limits::max()) + ret += std::string("\nStolen from ") + it->first; // for legacy (ESS) savegames + else + ret += std::string("\nStolen ") + MyGUI::utility::toString(it->second) + " from " + it->first; } ret += getMiscString(cellref.getGlobalVariable(), "Global"); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 0d4518f875..617f38daf2 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -1030,7 +1030,9 @@ namespace MWMechanics owner.second = true; } Misc::StringUtils::toLower(owner.first); - mStolenItems[Misc::StringUtils::lowerCase(item.getClass().getId(item))][owner] += count; + + if (!Misc::StringUtils::ciEqual(item.getCellRef().getRefId(), MWWorld::ContainerStore::sGoldId)) + mStolenItems[Misc::StringUtils::lowerCase(item.getClass().getId(item))][owner] += count; commitCrime(ptr, victim, OT_Theft, item.getClass().getValue(item) * count); } From 3d280a6ba54c192ae6a3e9ebaef7621985dc0f3d Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 30 Mar 2015 11:19:37 +1100 Subject: [PATCH 093/185] Fixed the display issues of the nested tables in the dialogue subview. Needs further work but usable for now. --- apps/opencs/model/world/columns.cpp | 32 +++++---- apps/opencs/model/world/columns.hpp | 76 +++++++++++----------- apps/opencs/view/world/dialoguesubview.cpp | 75 ++++++++++++++------- 3 files changed, 109 insertions(+), 74 deletions(-) diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index c8bf8ad640..1d3bc7641e 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -24,7 +24,6 @@ namespace CSMWorld { ColumnId_ValueType, "Value Type" }, { ColumnId_Description, "Description" }, { ColumnId_Specialisation, "Specialisation" }, - { ColumnId_Skill, "Skill" }, { ColumnId_Attribute, "Attribute" }, { ColumnId_Name, "Name" }, { ColumnId_Playable, "Playable" }, @@ -174,10 +173,11 @@ namespace CSMWorld { ColumnId_Gender, "Gender" }, { ColumnId_PcRank, "PC Rank" }, { ColumnId_ReferenceableId, "Referenceable ID" }, - { ColumnId_NpcDestinations, "Destinations" }, + + { ColumnId_ContainerContent, "Content" }, + { ColumnId_ItemCount, "Count" }, { ColumnId_InventoryItemId, "ID"}, - { ColumnId_SpellId, "ID"}, - { ColumnId_ItemCount, "Count"}, + { ColumnId_CombatState, "Combat" }, { ColumnId_MagicState, "Magic" }, { ColumnId_StealthState, "Stealth" }, @@ -185,6 +185,22 @@ namespace CSMWorld { ColumnId_Vampire, "Vampire" }, { ColumnId_BodyPartType, "Bodypart Type" }, { ColumnId_MeshType, "Mesh Type" }, + + { ColumnId_ActorInventory, "Inventory" }, + { ColumnId_ActorSpells, "Spells" }, + { ColumnId_SpellId, "ID"}, + + { ColumnId_NpcDestinations, "Destinations" }, + { ColumnId_DestinationCell, "Cell"}, + { ColumnId_PosX, "X"}, + { ColumnId_PosY, "Y"}, + { ColumnId_PosZ, "Z"}, + { ColumnId_RotX, "Rotation X"}, + { ColumnId_RotY, "Rotation Y"}, + { ColumnId_RotZ, "Rotation Z"}, + + { ColumnId_Skill, "Skill" }, + { ColumnId_OwnerGlobal, "Owner Global" }, { ColumnId_DefaultProfile, "Default Profile" }, { ColumnId_BypassNewGame, "Bypass New Game" }, @@ -206,14 +222,6 @@ namespace CSMWorld { ColumnId_HitSound, "Hit Sound" }, { ColumnId_AreaSound, "Area Sound" }, { ColumnId_BoltSound, "Bolt Sound" }, - - { ColumnId_NpcDestinations, "Cell"}, - { ColumnId_PosX, "X"}, - { ColumnId_PosY, "Y"}, - { ColumnId_PosZ, "Z"}, - { ColumnId_RotX, "Rotation X"}, - { ColumnId_RotY, "Rotation Y"}, - { ColumnId_RotZ, "Rotation Z"}, { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 69bbfa39f0..1c0af217bc 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -167,50 +167,50 @@ namespace CSMWorld ColumnId_Rank = 152, ColumnId_Gender = 153, ColumnId_PcRank = 154, - ColumnId_ReferenceableId = 156, - ColumnId_ContainerContent = 157, - ColumnId_ItemCount = 158, - ColumnId_InventoryItemId = 159, - ColumnId_CombatState = 160, - ColumnId_MagicState = 161, - ColumnId_StealthState = 162, - ColumnId_EnchantmentType = 163, - ColumnId_Vampire = 164, - ColumnId_BodyPartType = 165, - ColumnId_MeshType = 166, - ColumnId_ActorInventory = 167, - ColumnId_ActorSpells = 168, - ColumnId_SpellId = 169, - ColumnId_NpcDestinations = 170, + ColumnId_ReferenceableId = 155, + ColumnId_ContainerContent = 156, + ColumnId_ItemCount = 157, + ColumnId_InventoryItemId = 158, + ColumnId_CombatState = 159, + ColumnId_MagicState = 160, + ColumnId_StealthState = 161, + ColumnId_EnchantmentType = 162, + ColumnId_Vampire = 163, + ColumnId_BodyPartType = 164, + ColumnId_MeshType = 165, + ColumnId_ActorInventory = 166, + ColumnId_ActorSpells = 167, + ColumnId_SpellId = 168, + ColumnId_NpcDestinations = 169, + ColumnId_DestinationCell = 170, ColumnId_PosX = 171, ColumnId_PosY = 172, ColumnId_PosZ = 173, ColumnId_RotX = 174, ColumnId_RotY = 175, ColumnId_RotZ = 176, - ColumnId_DestinationCell = 177, - ColumnId_Skill = 178, - ColumnId_OwnerGlobal = 164, - ColumnId_DefaultProfile = 165, - ColumnId_BypassNewGame = 166, - ColumnId_GlobalProfile = 167, - ColumnId_RefNumCounter = 168, - ColumnId_RefNum = 169, - ColumnId_Creature = 170, - ColumnId_SoundGeneratorType = 171, - ColumnId_AllowSpellmaking = 172, - ColumnId_AllowEnchanting = 173, - ColumnId_BaseCost = 174, - ColumnId_School = 175, - ColumnId_Particle = 176, - ColumnId_CastingObject = 177, - ColumnId_HitObject = 178, - ColumnId_AreaObject = 179, - ColumnId_BoltObject = 180, - ColumnId_CastingSound = 177, - ColumnId_HitSound = 178, - ColumnId_AreaSound = 179, - ColumnId_BoltSound = 180, + ColumnId_Skill = 177, + ColumnId_OwnerGlobal = 178, + ColumnId_DefaultProfile = 179, + ColumnId_BypassNewGame = 180, + ColumnId_GlobalProfile = 181, + ColumnId_RefNumCounter = 182, + ColumnId_RefNum = 183, + ColumnId_Creature = 184, + ColumnId_SoundGeneratorType = 185, + ColumnId_AllowSpellmaking = 186, + ColumnId_AllowEnchanting = 187, + ColumnId_BaseCost = 188, + ColumnId_School = 189, + ColumnId_Particle = 190, + ColumnId_CastingObject = 191, + ColumnId_HitObject = 192, + ColumnId_AreaObject = 193, + ColumnId_BoltObject = 194, + ColumnId_CastingSound = 195, + ColumnId_HitSound = 196, + ColumnId_AreaSound = 197, + ColumnId_BoltSound = 198, // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. ColumnId_UseValue1 = 0x10000, diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 8d51bbf7e2..421e12c132 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include "../../model/world/nestedtablemodel.hpp" @@ -139,26 +140,26 @@ void CSVWorld::DialogueDelegateDispatcherProxy::tableMimeDataDropped(const std:: CSMWorld::UniversalId::Type type = data[i].getType(); if (mDisplay == CSMWorld::ColumnBase::Display_Referenceable) { - if ( type == CSMWorld::UniversalId::Type_Activator - || type == CSMWorld::UniversalId::Type_Potion - || type == CSMWorld::UniversalId::Type_Apparatus - || type == CSMWorld::UniversalId::Type_Armor - || type == CSMWorld::UniversalId::Type_Book - || type == CSMWorld::UniversalId::Type_Clothing - || type == CSMWorld::UniversalId::Type_Container - || type == CSMWorld::UniversalId::Type_Creature - || type == CSMWorld::UniversalId::Type_Door - || type == CSMWorld::UniversalId::Type_Ingredient - || type == CSMWorld::UniversalId::Type_CreatureLevelledList - || type == CSMWorld::UniversalId::Type_ItemLevelledList - || type == CSMWorld::UniversalId::Type_Light - || type == CSMWorld::UniversalId::Type_Lockpick - || type == CSMWorld::UniversalId::Type_Miscellaneous - || type == CSMWorld::UniversalId::Type_Npc - || type == CSMWorld::UniversalId::Type_Probe - || type == CSMWorld::UniversalId::Type_Repair - || type == CSMWorld::UniversalId::Type_Static - || type == CSMWorld::UniversalId::Type_Weapon) + if (type == CSMWorld::UniversalId::Type_Activator + || type == CSMWorld::UniversalId::Type_Potion + || type == CSMWorld::UniversalId::Type_Apparatus + || type == CSMWorld::UniversalId::Type_Armor + || type == CSMWorld::UniversalId::Type_Book + || type == CSMWorld::UniversalId::Type_Clothing + || type == CSMWorld::UniversalId::Type_Container + || type == CSMWorld::UniversalId::Type_Creature + || type == CSMWorld::UniversalId::Type_Door + || type == CSMWorld::UniversalId::Type_Ingredient + || type == CSMWorld::UniversalId::Type_CreatureLevelledList + || type == CSMWorld::UniversalId::Type_ItemLevelledList + || type == CSMWorld::UniversalId::Type_Light + || type == CSMWorld::UniversalId::Type_Lockpick + || type == CSMWorld::UniversalId::Type_Miscellaneous + || type == CSMWorld::UniversalId::Type_Npc + || type == CSMWorld::UniversalId::Type_Probe + || type == CSMWorld::UniversalId::Type_Repair + || type == CSMWorld::UniversalId::Type_Static + || type == CSMWorld::UniversalId::Type_Weapon) { type = CSMWorld::UniversalId::Type_Referenceable; } @@ -388,6 +389,12 @@ void CSVWorld::EditWidget::remake(int row) line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); + QFrame* line2 = new QFrame(mMainWidget); + line2->setObjectName(QString::fromUtf8("line2")); + line2->setGeometry(QRect(320, 150, 118, 3)); + line2->setFrameShape(QFrame::HLine); + line2->setFrameShadow(QFrame::Sunken); + QVBoxLayout *mainLayout = new QVBoxLayout(mMainWidget); QGridLayout *unlockedLayout = new QGridLayout(); QGridLayout *lockedLayout = new QGridLayout(); @@ -396,7 +403,8 @@ void CSVWorld::EditWidget::remake(int row) mainLayout->addLayout(lockedLayout, 0); mainLayout->addWidget(line, 1); mainLayout->addLayout(unlockedLayout, 2); - mainLayout->addLayout(tablesLayout, 3); + mainLayout->addWidget(line2, 1); + mainLayout->addLayout(tablesLayout, 0); mainLayout->addStretch(1); int unlocked = 0; @@ -416,10 +424,28 @@ void CSVWorld::EditWidget::remake(int row) { mNestedModels.push_back(new CSMWorld::NestedTableModel (mTable->index(row, i), display, mTable)); - NestedTable* table = new NestedTable(mDocument, *(mNestedModels.rbegin()), this); + NestedTable* table = new NestedTable(mDocument, mNestedModels.back(), this); + int rows = mNestedModels.back()->rowCount(mTable->index(row, i)); + if (rows == 0) rows = 1; // FIXME: quick hack + int rowHeight = table->rowHeight(0); + int tableHeight = (rows * rowHeight) + + table->horizontalHeader()->height() + 2 * table->frameWidth(); + int tableMaxHeight = (5 * rowHeight) + + table->horizontalHeader()->height() + 2 * table->frameWidth(); + if (rows > 1 && rows < 5) + table->setMinimumHeight(tableHeight); + else if (rows > 1) + table->setMinimumHeight(tableMaxHeight); + + QLabel* label = new QLabel (mTable->headerData (i, Qt::Horizontal, Qt::DisplayRole).toString(), mMainWidget); + + label->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed); + + tablesLayout->addWidget(label); tablesLayout->addWidget(table); - } else + } + else { mDispatcher.makeDelegate (display); QWidget* editor = mDispatcher.makeEditor (display, (mTable->index (row, i))); @@ -438,7 +464,8 @@ void CSVWorld::EditWidget::remake(int row) lockedLayout->addWidget (label, locked, 0); lockedLayout->addWidget (editor, locked, 1); ++locked; - } else + } + else { unlockedLayout->addWidget (label, unlocked, 0); unlockedLayout->addWidget (editor, unlocked, 1); From 29ef08bb7545e62f15325ad79abce4ece3e5792c Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 30 Mar 2015 11:53:33 +1100 Subject: [PATCH 094/185] Spelling and other consistencies nit pick. --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/world/collectionbase.hpp | 23 ------------ apps/opencs/model/world/idtable.cpp | 1 + ...{nestedadaptors.cpp => nestedadapters.cpp} | 2 +- ...{nestedadaptors.hpp => nestedadapters.hpp} | 4 +-- apps/opencs/model/world/nestedcollection.hpp | 35 +++++++++++++++++++ apps/opencs/model/world/refidadapter.hpp | 30 ++++++++-------- apps/opencs/model/world/refidadapterimp.hpp | 8 ++--- apps/opencs/model/world/refidcollection.cpp | 24 ++++++------- apps/opencs/model/world/refidcollection.hpp | 5 +-- 10 files changed, 74 insertions(+), 60 deletions(-) rename apps/opencs/model/world/{nestedadaptors.cpp => nestedadapters.cpp} (81%) rename apps/opencs/model/world/{nestedadaptors.hpp => nestedadapters.hpp} (99%) create mode 100644 apps/opencs/model/world/nestedcollection.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 82d9f69774..c9ca60b339 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -26,7 +26,7 @@ opencs_units (model/world opencs_units_noqt (model/world universalid record commands columnbase scriptcontext cell refidcollection refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope - pathgrid landtexture land nestedtablewrapper nestedadaptors + pathgrid landtexture land nestedtablewrapper nestedadapters ) opencs_hdrs_noqt (model/world diff --git a/apps/opencs/model/world/collectionbase.hpp b/apps/opencs/model/world/collectionbase.hpp index 29ac33bc82..ef826e31c8 100644 --- a/apps/opencs/model/world/collectionbase.hpp +++ b/apps/opencs/model/world/collectionbase.hpp @@ -13,7 +13,6 @@ namespace CSMWorld { struct ColumnBase; struct RecordBase; - class NestedTableWrapperBase; /// \brief Base class for record collections /// @@ -105,28 +104,6 @@ namespace CSMWorld ///< Return index of column with the given \a id. If no such column exists, an exception is /// thrown. }; - - class NestedCollection : public CollectionBase - { - public: - virtual void addNestedRow(int row, int col, int position) = 0; - - virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const = 0; - - virtual NestedTableWrapperBase* nestedTable(int row, int column) const = 0; - - virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable) = 0; - - virtual void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn) = 0; - - virtual int getNestedRowsCount(int row, int column) const = 0; - - virtual int getNestedColumnsCount(int row, int column) const = 0; - - virtual void removeNestedRows(int row, int column, int subRow) = 0; - - - }; } #endif diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index fc8ac66b74..964b68cd1b 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -6,6 +6,7 @@ #include "nestedtablewrapper.hpp" #include "collectionbase.hpp" +#include "nestedcollection.hpp" #include "columnbase.hpp" CSMWorld::IdTable::IdTable (CollectionBase *idCollection, unsigned int features) diff --git a/apps/opencs/model/world/nestedadaptors.cpp b/apps/opencs/model/world/nestedadapters.cpp similarity index 81% rename from apps/opencs/model/world/nestedadaptors.cpp rename to apps/opencs/model/world/nestedadapters.cpp index 1e8425229a..1c8b1eff18 100644 --- a/apps/opencs/model/world/nestedadaptors.cpp +++ b/apps/opencs/model/world/nestedadapters.cpp @@ -1,4 +1,4 @@ -#include "nestedadaptors.hpp" +#include "nestedadapters.hpp" CSMWorld::HelperBase::HelperBase(CSMWorld::UniversalId::Type type) : mType(type) diff --git a/apps/opencs/model/world/nestedadaptors.hpp b/apps/opencs/model/world/nestedadapters.hpp similarity index 99% rename from apps/opencs/model/world/nestedadaptors.hpp rename to apps/opencs/model/world/nestedadapters.hpp index cc062e827a..ac2a650d47 100644 --- a/apps/opencs/model/world/nestedadaptors.hpp +++ b/apps/opencs/model/world/nestedadapters.hpp @@ -1,5 +1,5 @@ -#ifndef CSM_WORLD_NESTEDADAPTORS_H -#define CSM_WORLD_NESTEDADAPTORS_H +#ifndef CSM_WORLD_NESTEDADAPTERS_H +#define CSM_WORLD_NESTEDADAPTERS_H #include #include diff --git a/apps/opencs/model/world/nestedcollection.hpp b/apps/opencs/model/world/nestedcollection.hpp new file mode 100644 index 0000000000..dffa295733 --- /dev/null +++ b/apps/opencs/model/world/nestedcollection.hpp @@ -0,0 +1,35 @@ +#ifndef CSM_WOLRD_NESTEDCOLLECTION_H +#define CSM_WOLRD_NESTEDCOLLECTION_H + +#include "collectionbase.hpp" + +class QVariant; + +namespace CSMWorld +{ + class NestedTableWrapperBase; + + class NestedCollection : public CollectionBase + { + public: + virtual void addNestedRow(int row, int col, int position) = 0; + + virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const = 0; + + virtual NestedTableWrapperBase* nestedTable(int row, int column) const = 0; + + virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable) = 0; + + virtual void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn) = 0; + + virtual int getNestedRowsCount(int row, int column) const = 0; + + virtual int getNestedColumnsCount(int row, int column) const = 0; + + virtual void removeNestedRows(int row, int column, int subRow) = 0; + + + }; +} + +#endif diff --git a/apps/opencs/model/world/refidadapter.hpp b/apps/opencs/model/world/refidadapter.hpp index 387ee8606f..af74696372 100644 --- a/apps/opencs/model/world/refidadapter.hpp +++ b/apps/opencs/model/world/refidadapter.hpp @@ -4,10 +4,10 @@ #include #include -#include "nestedadaptors.hpp" +#include "nestedadapters.hpp" /*! \brief - * Adaptors acts as indirection layer, abstracting details of the record types (in the wrappers) from the higher levels of model. + * Adapters acts as indirection layer, abstracting details of the record types (in the wrappers) from the higher levels of model. * Please notice that nested adaptor uses helper classes for actually performing any actions. Different record types require different helpers (needs to be created in the subclass and then fetched via member function). * Important point: don't forget to make sure that getData on the nestedColumn returns true (otherwise code will not treat the index pointing to the column as having childs! */ @@ -79,25 +79,25 @@ namespace CSMWorld public: NestedRefIdAdapter(); - + virtual ~NestedRefIdAdapter(); - + virtual void setNestedData (const RefIdColumn *column, RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const; - + virtual QVariant getNestedData (const RefIdColumn *column, const RefIdData& data, int index, int subRowIndex, int subColIndex) const; - + virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const; - + virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const; - + virtual void removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, int rowToRemove) const; - + virtual void addNestedRow (const RefIdColumn *column, RefIdData& data, int index, int position) const; - + virtual void setNestedTable (const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable); - + virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, const RefIdData& data, int index) const; protected: @@ -105,12 +105,12 @@ namespace CSMWorld ///The ownership of the Helper pointers is transfered. ///The ownership of the column pointers it not transfered (it is not surprising, since columns are created by collection). ///You MUST call this method to setup the nested adaptor! - - void addAssocColumn(const std::pair & assocColumn); + + void addAssocColumn(const std::pair & assocColumn); ///Like setAssocColumn, when it is impossible to set all columns at once - + private: - + HelperBase* getHelper(const RefIdColumn *column) const; }; } diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 11befaeec8..acc6c40c1c 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -12,7 +12,7 @@ #include "refiddata.hpp" #include "universalid.hpp" #include "refidadapter.hpp" -#include "nestedadaptors.hpp" +#include "nestedadapters.hpp" namespace CSMWorld { @@ -509,7 +509,7 @@ namespace CSMWorld assoCol.push_back(std::make_pair(mActors.mInventory, new InventoryHelper(type))); assoCol.push_back(std::make_pair(mActors.mSpells, new SpellsHelper(type))); - + setAssocColumns(assoCol); } @@ -540,7 +540,7 @@ namespace CSMWorld if (column==mActors.mSpells) return true; - + std::map::const_iterator iter = mActors.mServices.find (column); @@ -666,7 +666,7 @@ namespace CSMWorld const RefIdColumn *mOrganic; const RefIdColumn *mRespawn; const RefIdColumn *mContent; - + public: ContainerRefIdAdapter (const NameColumns& columns, const RefIdColumn *weight, diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index ee09cafa10..c488964358 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -27,7 +27,7 @@ bool CSMWorld::RefIdColumn::isUserEditable() const } -CSMWorld::RefIdAdapter& CSMWorld::RefIdCollection::findAdaptor (UniversalId::Type type) const +CSMWorld::RefIdAdapter& CSMWorld::RefIdCollection::findAdapter (UniversalId::Type type) const { std::map::const_iterator iter = mAdapters.find (type); @@ -452,7 +452,7 @@ QVariant CSMWorld::RefIdCollection::getData (int index, int column) const { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (index); - const RefIdAdapter& adaptor = findAdaptor (localIndex.second); + const RefIdAdapter& adaptor = findAdapter (localIndex.second); return adaptor.getData (&mColumns.at (column), mData, localIndex.first); } @@ -461,7 +461,7 @@ QVariant CSMWorld::RefIdCollection::getNestedData (int row, int column, int subR { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(row); - const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdaptor (localIndex.second)); + const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdapter (localIndex.second)); return adaptor.getNestedData (&mColumns.at (column), mData, localIndex.first, subRow, subColumn); } @@ -470,7 +470,7 @@ void CSMWorld::RefIdCollection::setData (int index, int column, const QVariant& { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (index); - const RefIdAdapter& adaptor = findAdaptor (localIndex.second); + const RefIdAdapter& adaptor = findAdapter (localIndex.second); adaptor.setData (&mColumns.at (column), mData, localIndex.first, data); } @@ -479,7 +479,7 @@ void CSMWorld::RefIdCollection::setNestedData(int row, int column, const QVarian { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); - const RefIdAdapter& adaptor = findAdaptor (localIndex.second); + const RefIdAdapter& adaptor = findAdapter (localIndex.second); dynamic_cast(adaptor).setNestedData (&mColumns.at (column), mData, localIndex.first, data, subRow, subColumn); } @@ -493,7 +493,7 @@ void CSMWorld::RefIdCollection::removeNestedRows(int row, int column, int subRow { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); - const RefIdAdapter& adaptor = findAdaptor (localIndex.second); + const RefIdAdapter& adaptor = findAdapter (localIndex.second); dynamic_cast(adaptor).removeNestedRow(&mColumns.at (column), mData, localIndex.first, subRow); } @@ -530,7 +530,7 @@ void CSMWorld::RefIdCollection::cloneRecord(const std::string& origin, void CSMWorld::RefIdCollection::appendRecord (const RecordBase& record, UniversalId::Type type) { - std::string id = findAdaptor (type).getId (record); + std::string id = findAdapter (type).getId (record); int index = mData.getAppendIndex (type); @@ -637,7 +637,7 @@ int CSMWorld::RefIdCollection::getNestedRowsCount(int row, int column) const { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); - const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdaptor (localIndex.second)); + const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdapter (localIndex.second)); return adaptor.getNestedRowsCount(&mColumns.at(column), mData, localIndex.first); } @@ -646,7 +646,7 @@ int CSMWorld::RefIdCollection::getNestedColumnsCount(int row, int column) const { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); - const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdaptor (localIndex.second)); + const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdapter (localIndex.second)); return adaptor.getNestedColumnsCount(&mColumns.at(column), mData); } @@ -655,7 +655,7 @@ void CSMWorld::RefIdCollection::addNestedRow(int row, int col, int position) { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); - const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdaptor (localIndex.second)); + const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdapter (localIndex.second)); adaptor.addNestedRow(&mColumns.at(col), mData, localIndex.first, position); } @@ -664,7 +664,7 @@ void CSMWorld::RefIdCollection::setNestedTable(int row, int column, const CSMWor { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); - CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdaptor (localIndex.second)); + CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdapter (localIndex.second)); adaptor.setNestedTable(&mColumns.at(column), mData, localIndex.first, nestedTable); } @@ -673,7 +673,7 @@ CSMWorld::NestedTableWrapperBase* CSMWorld::RefIdCollection::nestedTable(int row { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); - const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdaptor (localIndex.second)); + const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdapter (localIndex.second)); return adaptor.nestedTable(&mColumns.at(column), mData, localIndex.first); } diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index 62616d3697..ab25c93fa3 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -7,6 +7,7 @@ #include "columnbase.hpp" #include "collectionbase.hpp" +#include "nestedcollection.hpp" #include "refiddata.hpp" namespace ESM @@ -45,7 +46,7 @@ namespace CSMWorld private: - RefIdAdapter& findAdaptor (UniversalId::Type) const; + RefIdAdapter& findAdapter (UniversalId::Type) const; ///< Throws an exception if no adaptor for \a Type can be found. public: @@ -71,7 +72,7 @@ namespace CSMWorld virtual QVariant getData (int index, int column) const; virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const; - + virtual NestedTableWrapperBase* nestedTable(int row, int column) const; virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable); From 619b5206cdedfb75a1ecadf5754de129c46211e2 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 30 Mar 2015 16:41:55 +1100 Subject: [PATCH 095/185] More consistency nit pick. --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/world/idtable.cpp | 10 ++-- ...blemodel.cpp => nestedtableproxymodel.cpp} | 49 +++++++++---------- ...blemodel.hpp => nestedtableproxymodel.hpp} | 26 +++++----- apps/opencs/view/world/dialoguesubview.cpp | 4 +- apps/opencs/view/world/dialoguesubview.hpp | 4 +- apps/opencs/view/world/nestedtable.cpp | 4 +- apps/opencs/view/world/nestedtable.hpp | 6 +-- 8 files changed, 54 insertions(+), 51 deletions(-) rename apps/opencs/model/world/{nestedtablemodel.cpp => nestedtableproxymodel.cpp} (66%) rename apps/opencs/model/world/{nestedtablemodel.hpp => nestedtableproxymodel.hpp} (89%) diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index c9ca60b339..5f95592578 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -19,7 +19,7 @@ opencs_hdrs_noqt (model/doc opencs_units (model/world idtable idtableproxymodel regionmap data commanddispatcher - idtablebase resourcetable nestedtablemodel + idtablebase resourcetable nestedtableproxymodel ) diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index 964b68cd1b..c5061b93de 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -51,7 +51,9 @@ QVariant CSMWorld::IdTable::data (const QModelIndex & index, int role) const parentAdress.second, index.row(), index.column()); - } else { + } + else + { return mIdCollection->getData (index.row(), index.column()); } } @@ -110,7 +112,8 @@ bool CSMWorld::IdTable::setData (const QModelIndex &index, const QVariant &value CSMWorld::IdTable::index (parentAdress.second, mIdCollection->getColumns()-1)); return true; - } else + } + else { return false; } @@ -149,7 +152,8 @@ bool CSMWorld::IdTable::removeRows (int row, int count, const QModelIndex& paren { dynamic_cast(mIdCollection)->removeNestedRows(parent.row(), parent.column(), row+i); } - } else + } + else { beginRemoveRows (parent, row, row+count-1); diff --git a/apps/opencs/model/world/nestedtablemodel.cpp b/apps/opencs/model/world/nestedtableproxymodel.cpp similarity index 66% rename from apps/opencs/model/world/nestedtablemodel.cpp rename to apps/opencs/model/world/nestedtableproxymodel.cpp index 734047b8dd..c098e03166 100644 --- a/apps/opencs/model/world/nestedtablemodel.cpp +++ b/apps/opencs/model/world/nestedtableproxymodel.cpp @@ -1,9 +1,9 @@ -#include "nestedtablemodel.hpp" +#include "nestedtableproxymodel.hpp" #include #include "idtable.hpp" -CSMWorld::NestedTableModel::NestedTableModel(const QModelIndex& parent, +CSMWorld::NestedTableProxyModel::NestedTableProxyModel(const QModelIndex& parent, ColumnBase::Display columnId, CSMWorld::IdTable* parentModel) : mParentColumn(parent.column()), @@ -14,10 +14,10 @@ CSMWorld::NestedTableModel::NestedTableModel(const QModelIndex& parent, mId = std::string(parentModel->index(parentRow, 0).data().toString().toUtf8()); QAbstractProxyModel::setSourceModel(parentModel); - + connect(mMainModel, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)), this, SLOT(forwardRowsAboutToInserted(const QModelIndex &, int, int))); - + connect(mMainModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(forwardRowsInserted(const QModelIndex &, int, int))); @@ -26,7 +26,7 @@ CSMWorld::NestedTableModel::NestedTableModel(const QModelIndex& parent, connect(mMainModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SLOT(forwardRowsRemoved(const QModelIndex &, int, int))); - + connect(mMainModel, SIGNAL(resetStart(const QString&)), this, SLOT(forwardResetStart(const QString&))); @@ -34,7 +34,7 @@ CSMWorld::NestedTableModel::NestedTableModel(const QModelIndex& parent, this, SLOT(forwardResetEnd(const QString&))); } -QModelIndex CSMWorld::NestedTableModel::mapFromSource(const QModelIndex& sourceIndex) const +QModelIndex CSMWorld::NestedTableProxyModel::mapFromSource(const QModelIndex& sourceIndex) const { const QModelIndex& testedParent = mMainModel->parent(sourceIndex); const QModelIndex& parent = mMainModel->getModelIndex (mId, mParentColumn); @@ -46,30 +46,29 @@ QModelIndex CSMWorld::NestedTableModel::mapFromSource(const QModelIndex& sourceI { return QModelIndex(); } - } -QModelIndex CSMWorld::NestedTableModel::mapToSource(const QModelIndex& proxyIndex) const +QModelIndex CSMWorld::NestedTableProxyModel::mapToSource(const QModelIndex& proxyIndex) const { const QModelIndex& parent = mMainModel->getModelIndex (mId, mParentColumn); return mMainModel->index(proxyIndex.row(), proxyIndex.column(), parent); } -int CSMWorld::NestedTableModel::rowCount(const QModelIndex& index) const +int CSMWorld::NestedTableProxyModel::rowCount(const QModelIndex& index) const { assert (!index.isValid()); return mMainModel->rowCount(mMainModel->getModelIndex(mId, mParentColumn)); } -int CSMWorld::NestedTableModel::columnCount(const QModelIndex& parent) const +int CSMWorld::NestedTableProxyModel::columnCount(const QModelIndex& parent) const { assert (!parent.isValid()); return mMainModel->columnCount(mMainModel->getModelIndex(mId, mParentColumn)); } -QModelIndex CSMWorld::NestedTableModel::index(int row, int column, const QModelIndex& parent) const +QModelIndex CSMWorld::NestedTableProxyModel::index(int row, int column, const QModelIndex& parent) const { assert (!parent.isValid()); @@ -87,12 +86,12 @@ QModelIndex CSMWorld::NestedTableModel::index(int row, int column, const QModelI return createIndex(row, column); } -QModelIndex CSMWorld::NestedTableModel::parent(const QModelIndex& index) const +QModelIndex CSMWorld::NestedTableProxyModel::parent(const QModelIndex& index) const { return QModelIndex(); } -QVariant CSMWorld::NestedTableModel::headerData(int section, +QVariant CSMWorld::NestedTableProxyModel::headerData(int section, Qt::Orientation orientation, int role) const { @@ -100,32 +99,32 @@ QVariant CSMWorld::NestedTableModel::headerData(int section, } -bool CSMWorld::NestedTableModel::setData ( const QModelIndex & index, const QVariant & value, int role) +bool CSMWorld::NestedTableProxyModel::setData ( const QModelIndex & index, const QVariant & value, int role) { return mMainModel->setData(mapToSource(index), value, role); } -Qt::ItemFlags CSMWorld::NestedTableModel::flags(const QModelIndex& index) const +Qt::ItemFlags CSMWorld::NestedTableProxyModel::flags(const QModelIndex& index) const { return mMainModel->flags(mMainModel->index(0, mParentColumn)); } -std::string CSMWorld::NestedTableModel::getParentId() const +std::string CSMWorld::NestedTableProxyModel::getParentId() const { return mId; } -int CSMWorld::NestedTableModel::getParentColumn() const +int CSMWorld::NestedTableProxyModel::getParentColumn() const { return mParentColumn; } -CSMWorld::IdTable* CSMWorld::NestedTableModel::model() const +CSMWorld::IdTable* CSMWorld::NestedTableProxyModel::model() const { return mMainModel; } -void CSMWorld::NestedTableModel::forwardRowsAboutToInserted(const QModelIndex& parent, int first, int last) +void CSMWorld::NestedTableProxyModel::forwardRowsAboutToInserted(const QModelIndex& parent, int first, int last) { if (indexIsParent(parent)) { @@ -133,7 +132,7 @@ void CSMWorld::NestedTableModel::forwardRowsAboutToInserted(const QModelIndex& p } } -void CSMWorld::NestedTableModel::forwardRowsInserted(const QModelIndex& parent, int first, int last) +void CSMWorld::NestedTableProxyModel::forwardRowsInserted(const QModelIndex& parent, int first, int last) { if (indexIsParent(parent)) { @@ -141,14 +140,14 @@ void CSMWorld::NestedTableModel::forwardRowsInserted(const QModelIndex& parent, } } -bool CSMWorld::NestedTableModel::indexIsParent(const QModelIndex& index) +bool CSMWorld::NestedTableProxyModel::indexIsParent(const QModelIndex& index) { return (index.isValid() && index.column() == mParentColumn && mMainModel->data(mMainModel->index(index.row(), 0)).toString().toUtf8().constData() == mId); } -void CSMWorld::NestedTableModel::forwardRowsAboutToRemoved(const QModelIndex& parent, int first, int last) +void CSMWorld::NestedTableProxyModel::forwardRowsAboutToRemoved(const QModelIndex& parent, int first, int last) { if (indexIsParent(parent)) { @@ -156,7 +155,7 @@ void CSMWorld::NestedTableModel::forwardRowsAboutToRemoved(const QModelIndex& pa } } -void CSMWorld::NestedTableModel::forwardRowsRemoved(const QModelIndex& parent, int first, int last) +void CSMWorld::NestedTableProxyModel::forwardRowsRemoved(const QModelIndex& parent, int first, int last) { if (indexIsParent(parent)) { @@ -164,13 +163,13 @@ void CSMWorld::NestedTableModel::forwardRowsRemoved(const QModelIndex& parent, i } } -void CSMWorld::NestedTableModel::forwardResetStart(const QString& id) +void CSMWorld::NestedTableProxyModel::forwardResetStart(const QString& id) { if (id.toUtf8() == mId.c_str()) beginResetModel(); } -void CSMWorld::NestedTableModel::forwardResetEnd(const QString& id) +void CSMWorld::NestedTableProxyModel::forwardResetEnd(const QString& id) { if (id.toUtf8() == mId.c_str()) endResetModel(); diff --git a/apps/opencs/model/world/nestedtablemodel.hpp b/apps/opencs/model/world/nestedtableproxymodel.hpp similarity index 89% rename from apps/opencs/model/world/nestedtablemodel.hpp rename to apps/opencs/model/world/nestedtableproxymodel.hpp index 5fea5c0061..7ad8fc0c23 100644 --- a/apps/opencs/model/world/nestedtablemodel.hpp +++ b/apps/opencs/model/world/nestedtableproxymodel.hpp @@ -1,5 +1,5 @@ -#ifndef CSM_WOLRD_NESTEDTABLEMODEL_H -#define CSM_WOLRD_NESTEDTABLEMODEL_H +#ifndef CSM_WOLRD_NESTEDTABLEPROXYMODEL_H +#define CSM_WOLRD_NESTEDTABLEPROXYMODEL_H #include @@ -19,7 +19,7 @@ namespace CSMWorld class RecordBase; class IdTable; - class NestedTableModel : public QAbstractProxyModel + class NestedTableProxyModel : public QAbstractProxyModel { Q_OBJECT @@ -28,15 +28,15 @@ namespace CSMWorld std::string mId; public: - NestedTableModel(const QModelIndex& parent, + NestedTableProxyModel(const QModelIndex& parent, ColumnBase::Display displayType, IdTable* parentModel); //parent is the parent of columns to work with. Columnid provides information about the column std::string getParentId() const; - + int getParentColumn() const; - + CSMWorld::IdTable* model() const; virtual QModelIndex mapFromSource(const QModelIndex& sourceIndex) const; @@ -52,27 +52,27 @@ namespace CSMWorld virtual QModelIndex parent(const QModelIndex& index) const; virtual QVariant headerData ( int section, Qt::Orientation orientation, int role ) const; - + virtual bool setData ( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole ); - + virtual Qt::ItemFlags flags(const QModelIndex& index) const; - + private: void setupHeaderVectors(ColumnBase::Display columnId); bool indexIsParent(const QModelIndex& index); - + private slots: void forwardRowsAboutToInserted(const QModelIndex & parent, int first, int last); - + void forwardRowsInserted(const QModelIndex & parent, int first, int last); void forwardRowsAboutToRemoved(const QModelIndex & parent, int first, int last); void forwardRowsRemoved(const QModelIndex & parent, int first, int last); - + void forwardResetStart(const QString& id); - + void forwardResetEnd(const QString& id); }; } diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 421e12c132..e26dcdc9ba 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -23,7 +23,7 @@ #include #include -#include "../../model/world/nestedtablemodel.hpp" +#include "../../model/world/nestedtableproxymodel.hpp" #include "../../model/world/columnbase.hpp" #include "../../model/world/idtable.hpp" #include "../../model/world/columns.hpp" @@ -422,7 +422,7 @@ void CSVWorld::EditWidget::remake(int row) if (mTable->hasChildren(mTable->index(row, i))) { - mNestedModels.push_back(new CSMWorld::NestedTableModel (mTable->index(row, i), display, mTable)); + mNestedModels.push_back(new CSMWorld::NestedTableProxyModel (mTable->index(row, i), display, mTable)); NestedTable* table = new NestedTable(mDocument, mNestedModels.back(), this); diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index 6ea79aa951..72acb19669 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -21,7 +21,7 @@ class QVBoxLayout; namespace CSMWorld { class IdTable; - class NestedTableModel; + class NestedTableProxyModel; } namespace CSMDoc @@ -165,7 +165,7 @@ namespace CSVWorld QWidget* mMainWidget; CSMWorld::IdTable* mTable; CSMDoc::Document& mDocument; - std::vector mNestedModels; //Plain, raw C pointers, deleted in the dtor + std::vector mNestedModels; //Plain, raw C pointers, deleted in the dtor public: diff --git a/apps/opencs/view/world/nestedtable.cpp b/apps/opencs/view/world/nestedtable.cpp index 14e079c983..1597c81a35 100644 --- a/apps/opencs/view/world/nestedtable.cpp +++ b/apps/opencs/view/world/nestedtable.cpp @@ -1,5 +1,5 @@ #include "nestedtable.hpp" -#include "../../model/world/nestedtablemodel.hpp" +#include "../../model/world/nestedtableproxymodel.hpp" #include "../../model/world/universalid.hpp" #include "../../model/world/commands.hpp" #include "util.hpp" @@ -10,7 +10,7 @@ #include CSVWorld::NestedTable::NestedTable(CSMDoc::Document& document, - CSMWorld::NestedTableModel* model, + CSMWorld::NestedTableProxyModel* model, QWidget* parent) : QTableView(parent), mUndoStack(document.getUndoStack()), diff --git a/apps/opencs/view/world/nestedtable.hpp b/apps/opencs/view/world/nestedtable.hpp index 6b6b6aabab..f41ba43452 100644 --- a/apps/opencs/view/world/nestedtable.hpp +++ b/apps/opencs/view/world/nestedtable.hpp @@ -10,7 +10,7 @@ class QContextMenuEvent; namespace CSMWorld { - class NestedTableModel; + class NestedTableProxyModel; class UniversalId; } @@ -28,11 +28,11 @@ namespace CSVWorld QAction *mAddNewRowAction; QAction *mRemoveRowAction; QUndoStack& mUndoStack; - CSMWorld::NestedTableModel* mModel; + CSMWorld::NestedTableProxyModel* mModel; public: NestedTable(CSMDoc::Document& document, - CSMWorld::NestedTableModel* model, + CSMWorld::NestedTableProxyModel* model, QWidget* parent = NULL); protected: From ece34a1baa2c963d7f5429126c75891c0addd1b4 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 30 Mar 2015 18:14:07 +1100 Subject: [PATCH 096/185] Workaround for crash while exiting the application. --- apps/opencs/model/world/idtable.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index c5061b93de..1c21e64c3d 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -14,7 +14,9 @@ CSMWorld::IdTable::IdTable (CollectionBase *idCollection, unsigned int features) {} CSMWorld::IdTable::~IdTable() -{} +{ + mIdCollection = 0; // FIXME: workaround only, should stop QHideEvent calling after destruction +} int CSMWorld::IdTable::rowCount (const QModelIndex & parent) const { @@ -81,6 +83,10 @@ QVariant CSMWorld::IdTable::headerData (int section, QVariant CSMWorld::IdTable::nestedHeaderData(int section, int subSection, Qt::Orientation orientation, int role) const { + // FIXME: workaround only, should stop QHideEvent calling after destruction + if (section < 0 || !mIdCollection || section >= mIdCollection->getColumns()) + return QVariant(); + const NestColumn& parentColumn = dynamic_cast(mIdCollection->getColumn(section)); if (orientation==Qt::Vertical) From 83bcc8d4512c4571421d9602fb0e367c440dc9f1 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Thu, 2 Apr 2015 20:19:15 +1100 Subject: [PATCH 097/185] Reorganised class inheritance structure of collections, columns and idtable model. --- apps/opencs/CMakeLists.txt | 5 +- apps/opencs/model/world/columnbase.cpp | 45 +-- apps/opencs/model/world/columnbase.hpp | 39 +-- apps/opencs/model/world/commands.cpp | 13 +- apps/opencs/model/world/commands.hpp | 21 +- apps/opencs/model/world/data.cpp | 3 +- apps/opencs/model/world/idtable.cpp | 208 +----------- apps/opencs/model/world/idtable.hpp | 27 -- apps/opencs/model/world/idtree.cpp | 296 ++++++++++++++++++ apps/opencs/model/world/idtree.hpp | 88 ++++++ apps/opencs/model/world/nestablecolumn.cpp | 44 +++ apps/opencs/model/world/nestablecolumn.hpp | 33 ++ apps/opencs/model/world/nestedcollection.hpp | 10 + .../model/world/nestedtableproxymodel.cpp | 6 +- .../model/world/nestedtableproxymodel.hpp | 8 +- apps/opencs/model/world/refidcollection.cpp | 62 ++-- apps/opencs/model/world/refidcollection.hpp | 45 +-- apps/opencs/model/world/refiddata.hpp | 6 +- apps/opencs/view/world/dialoguesubview.cpp | 3 +- 19 files changed, 590 insertions(+), 372 deletions(-) create mode 100644 apps/opencs/model/world/idtree.cpp create mode 100644 apps/opencs/model/world/idtree.hpp create mode 100644 apps/opencs/model/world/nestablecolumn.cpp create mode 100644 apps/opencs/model/world/nestablecolumn.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 5f95592578..39b4c486bc 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -18,15 +18,14 @@ opencs_hdrs_noqt (model/doc opencs_units (model/world - idtable idtableproxymodel regionmap data commanddispatcher - idtablebase resourcetable nestedtableproxymodel + idtable idtableproxymodel regionmap data commanddispatcher idtablebase resourcetable nestedtableproxymodel idtree ) opencs_units_noqt (model/world universalid record commands columnbase scriptcontext cell refidcollection refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope - pathgrid landtexture land nestedtablewrapper nestedadapters + pathgrid landtexture land nestedtablewrapper nestedadapters nestedcollection nestablecolumn ) opencs_hdrs_noqt (model/world diff --git a/apps/opencs/model/world/columnbase.cpp b/apps/opencs/model/world/columnbase.cpp index 60e201ba45..665ab93545 100644 --- a/apps/opencs/model/world/columnbase.cpp +++ b/apps/opencs/model/world/columnbase.cpp @@ -1,9 +1,10 @@ + #include "columnbase.hpp" #include "columns.hpp" -CSMWorld::ColumnBase::ColumnBase (int columnId, Display displayType, int flags, bool canNest) - : mColumnId (columnId), mDisplayType (displayType), mFlags (flags), mCanNest(canNest) +CSMWorld::ColumnBase::ColumnBase (int columnId, Display displayType, int flags) +: mColumnId (columnId), mDisplayType (displayType), mFlags (flags) {} CSMWorld::ColumnBase::~ColumnBase() {} @@ -22,43 +23,3 @@ int CSMWorld::ColumnBase::getId() const { return mColumnId; } - -bool CSMWorld::NestColumn::canHaveNestedColumns() const -{ - return mCanNest; -} - -void CSMWorld::NestColumn::addNestedColumn(int columnId, Display displayType) -{ - if (!mCanNest) - throw std::logic_error("Tried to nest inside of the non-nest column"); - - mNestedColumns.push_back(CSMWorld::NestedColumn(columnId, displayType, mFlags, this)); -} - -const CSMWorld::ColumnBase& CSMWorld::NestColumn::nestedColumn(int subColumn) const -{ - if (!mCanNest) - throw std::logic_error("Tried to access nested column of the non-nest column"); - - return mNestedColumns.at(subColumn); -} - -int CSMWorld::NestColumn::nestedColumnCount() const -{ - if (!mCanNest) - throw std::logic_error("Tried to access number of the subcolumns in the non-nest column"); - - return mNestedColumns.size(); -} - -CSMWorld::NestColumn::NestColumn(int columnId, Display displayType, int flags, bool canNest) - : CSMWorld::ColumnBase(columnId, displayType, flags, canNest) {} - -CSMWorld::NestedColumn::NestedColumn(int columnId, Display displayType, int flag, const CSMWorld::NestColumn* parent) - : mParent(parent), CSMWorld::ColumnBase(columnId, displayType, flag) {} - -bool CSMWorld::NestedColumn::isEditable() const -{ - return mParent->isEditable(); -} diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 607f585b76..b717f3a52b 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include @@ -117,9 +117,8 @@ namespace CSMWorld int mColumnId; int mFlags; Display mDisplayType; - bool mCanNest; - ColumnBase (int columnId, Display displayType, int flag, bool canNest = false); + ColumnBase (int columnId, Display displayType, int flag); virtual ~ColumnBase(); @@ -133,39 +132,11 @@ namespace CSMWorld virtual int getId() const; }; - class NestedColumn; - - class NestColumn : public ColumnBase - { - std::vector mNestedColumns; - - public: - NestColumn(int columnId, Display displayType, int flags, bool canNest); - - void addNestedColumn(int columnId, Display displayType); - - bool canHaveNestedColumns() const; - - const ColumnBase& nestedColumn(int subColumn) const; - - int nestedColumnCount() const; - }; - - class NestedColumn : public ColumnBase - { - const ColumnBase* mParent; - - public: - NestedColumn(int columnId, Display displayType, int flag, const NestColumn* parent); - - virtual bool isEditable() const; - }; - template - struct Column : public NestColumn + struct Column : public ColumnBase { - Column (int columnId, Display displayType, int flags = Flag_Table | Flag_Dialogue, bool canNest = false) - : NestColumn (columnId, displayType, flags, canNest) {} + Column (int columnId, Display displayType, int flags = Flag_Table | Flag_Dialogue) + : ColumnBase (columnId, displayType, flags) {} virtual QVariant get (const Record& record) const = 0; diff --git a/apps/opencs/model/world/commands.cpp b/apps/opencs/model/world/commands.cpp index 959f6b345c..7acc6058ef 100644 --- a/apps/opencs/model/world/commands.cpp +++ b/apps/opencs/model/world/commands.cpp @@ -3,6 +3,7 @@ #include #include "idtable.hpp" +#include "idtree.hpp" #include #include "nestedtablewrapper.hpp" @@ -172,10 +173,10 @@ void CSMWorld::CloneCommand::undo() mModel.removeRow (mModel.getModelIndex (mId, 0).row()); } -CSMWorld::DeleteNestedCommand::DeleteNestedCommand (IdTable& model, +CSMWorld::DeleteNestedCommand::DeleteNestedCommand (IdTree& model, const std::string& id, - int nestedRow, - int parentColumn, + int nestedRow, + int parentColumn, QUndoCommand* parent) : mId(id), mModel(model), @@ -192,7 +193,7 @@ void CSMWorld::DeleteNestedCommand::redo() const QModelIndex& parentIndex = mModel.getModelIndex(mId, mParentColumn); mModel.removeRows (mNestedRow, 1, parentIndex); -} +} void CSMWorld::DeleteNestedCommand::undo() @@ -202,7 +203,7 @@ void CSMWorld::DeleteNestedCommand::undo() mModel.setNestedTable(parentIndex, getOld()); } -CSMWorld::AddNestedCommand::AddNestedCommand(IdTable& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent) +CSMWorld::AddNestedCommand::AddNestedCommand(IdTree& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent) : mModel(model), mId(id), mNewRow(nestedRow), @@ -227,7 +228,7 @@ void CSMWorld::AddNestedCommand::undo() mModel.setNestedTable(parentIndex, getOld()); } -CSMWorld::NestedTableStoring::NestedTableStoring(const IdTable& 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))) {} CSMWorld::NestedTableStoring::~NestedTableStoring() diff --git a/apps/opencs/model/world/commands.hpp b/apps/opencs/model/world/commands.hpp index c194e2779b..42405a2f9d 100644 --- a/apps/opencs/model/world/commands.hpp +++ b/apps/opencs/model/world/commands.hpp @@ -10,7 +10,6 @@ #include #include #include -#include #include "universalid.hpp" #include "nestedtablewrapper.hpp" @@ -21,7 +20,7 @@ class QAbstractItemModel; namespace CSMWorld { class IdTable; - class IdTable; + class IdTree; struct RecordBase; class NestedTableWrapperBase; @@ -148,18 +147,18 @@ namespace CSMWorld NestedTableWrapperBase* mOld; public: - NestedTableStoring(const IdTable& model, const std::string& id, int parentColumn); - + NestedTableStoring(const IdTree& model, const std::string& id, int parentColumn); + ~NestedTableStoring(); - + protected: const NestedTableWrapperBase& getOld() const; }; - + class DeleteNestedCommand : public QUndoCommand, private NestedTableStoring { - IdTable& mModel; + IdTree& mModel; std::string mId; @@ -169,16 +168,16 @@ namespace CSMWorld public: - DeleteNestedCommand (IdTable& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent = 0); + DeleteNestedCommand (IdTree& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent = 0); virtual void redo(); virtual void undo(); }; - + class AddNestedCommand : public QUndoCommand, private NestedTableStoring { - IdTable& mModel; + IdTree& mModel; std::string mId; @@ -188,7 +187,7 @@ namespace CSMWorld public: - AddNestedCommand(IdTable& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent = 0); + AddNestedCommand(IdTree& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent = 0); virtual void redo(); diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 39cff3db65..a5ef439a7e 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -12,6 +12,7 @@ #include #include "idtable.hpp" +#include "idtree.hpp" #include "columnimp.hpp" #include "regionmap.hpp" #include "columns.hpp" @@ -332,7 +333,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc addModel (new IdTable (&mMagicEffects), UniversalId::Type_MagicEffect); addModel (new IdTable (&mPathgrids), UniversalId::Type_Pathgrid); addModel (new IdTable (&mStartScripts), UniversalId::Type_StartScript); - addModel (new IdTable (&mReferenceables, IdTable::Feature_Preview), + addModel (new IdTree (&mReferenceables, IdTable::Feature_Preview), UniversalId::Type_Referenceable); addModel (new IdTable (&mRefs, IdTable::Feature_ViewCell | IdTable::Feature_Preview), UniversalId::Type_Reference); addModel (new IdTable (&mFilters), UniversalId::Type_Filter); diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index 1c21e64c3d..7618a073a9 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -1,12 +1,6 @@ #include "idtable.hpp" -#include - -#include -#include -#include "nestedtablewrapper.hpp" #include "collectionbase.hpp" -#include "nestedcollection.hpp" #include "columnbase.hpp" CSMWorld::IdTable::IdTable (CollectionBase *idCollection, unsigned int features) @@ -14,26 +8,20 @@ CSMWorld::IdTable::IdTable (CollectionBase *idCollection, unsigned int features) {} CSMWorld::IdTable::~IdTable() -{ - mIdCollection = 0; // FIXME: workaround only, should stop QHideEvent calling after destruction -} +{} int CSMWorld::IdTable::rowCount (const QModelIndex & parent) const { - if (hasChildren(parent)) - { - return dynamic_cast(mIdCollection)->getNestedRowsCount(parent.row(), parent.column()); - } + if (parent.isValid()) + return 0; return mIdCollection->getSize(); } int CSMWorld::IdTable::columnCount (const QModelIndex & parent) const { - if (hasChildren(parent)) - { - return dynamic_cast(mIdCollection)->getNestedColumnsCount(parent.row(), parent.column()); - } + if (parent.isValid()) + return 0; return mIdCollection->getColumns(); } @@ -46,23 +34,10 @@ QVariant CSMWorld::IdTable::data (const QModelIndex & index, int role) const if (role==Qt::EditRole && !mIdCollection->getColumn (index.column()).isEditable()) return QVariant(); - if (index.internalId() != 0) - { - std::pair parentAdress(unfoldIndexAdress(index.internalId())); - return dynamic_cast(mIdCollection)->getNestedData(parentAdress.first, - parentAdress.second, - index.row(), - index.column()); - } - else - { - return mIdCollection->getData (index.row(), index.column()); - } + return mIdCollection->getData (index.row(), index.column()); } -QVariant CSMWorld::IdTable::headerData (int section, - Qt::Orientation orientation, - int role) const +QVariant CSMWorld::IdTable::headerData (int section, Qt::Orientation orientation, int role) const { if (orientation==Qt::Vertical) return QVariant(); @@ -74,63 +49,19 @@ QVariant CSMWorld::IdTable::headerData (int section, return mIdCollection->getColumn (section).mFlags; if (role==ColumnBase::Role_Display) - { return mIdCollection->getColumn (section).mDisplayType; - } - - return QVariant(); -} - -QVariant CSMWorld::IdTable::nestedHeaderData(int section, int subSection, Qt::Orientation orientation, int role) const -{ - // FIXME: workaround only, should stop QHideEvent calling after destruction - if (section < 0 || !mIdCollection || section >= mIdCollection->getColumns()) - return QVariant(); - - const NestColumn& parentColumn = dynamic_cast(mIdCollection->getColumn(section)); - - if (orientation==Qt::Vertical) - return QVariant(); - - if (role==Qt::DisplayRole) - return tr(parentColumn.nestedColumn(subSection).getTitle().c_str()); - - if (role==ColumnBase::Role_Flags) - return mIdCollection->getColumn (section).mFlags; - - if (role==ColumnBase::Role_Display) - return parentColumn.nestedColumn(subSection).mDisplayType; return QVariant(); } bool CSMWorld::IdTable::setData (const QModelIndex &index, const QVariant &value, int role) { - if (index.internalId() != 0) - { - if (mIdCollection->getColumn(parent(index).column()).isEditable() && role==Qt::EditRole) - { - const std::pair& parentAdress(unfoldIndexAdress(index.internalId())); - - dynamic_cast(mIdCollection)->setNestedData(parentAdress.first, parentAdress.second, value, index.row(), index.column()); - - emit dataChanged (CSMWorld::IdTable::index (parentAdress.first, 0), - CSMWorld::IdTable::index (parentAdress.second, mIdCollection->getColumns()-1)); - - return true; - } - else - { - return false; - } - } - if (mIdCollection->getColumn (index.column()).isEditable() && role==Qt::EditRole) { mIdCollection->setData (index.row(), index.column(), value); emit dataChanged (CSMWorld::IdTable::index (index.row(), 0), - CSMWorld::IdTable::index (index.row(), mIdCollection->getColumns()-1)); + CSMWorld::IdTable::index (index.row(), mIdCollection->getColumns()-1)); return true; } @@ -150,56 +81,22 @@ Qt::ItemFlags CSMWorld::IdTable::flags (const QModelIndex & index) const bool CSMWorld::IdTable::removeRows (int row, int count, const QModelIndex& parent) { + if (parent.isValid()) + return false; + beginRemoveRows (parent, row, row+count-1); - if (parent.isValid()) - { - for (int i = 0; i < count; ++i) - { - dynamic_cast(mIdCollection)->removeNestedRows(parent.row(), parent.column(), row+i); - } - } - else - { - - beginRemoveRows (parent, row, row+count-1); - - mIdCollection->removeRows (row, count); - } + mIdCollection->removeRows (row, count); endRemoveRows(); - emit dataChanged (CSMWorld::IdTable::index (parent.row(), 0), - CSMWorld::IdTable::index (parent.row(), mIdCollection->getColumns()-1)); - return true; } -void CSMWorld::IdTable::addNestedRow(const QModelIndex& parent, int position) -{ - if (!hasChildren(parent)) - { - throw std::logic_error("Tried to set nested table, but index has no children"); - } - - int row = parent.row(); - - beginInsertRows(parent, position, position); - dynamic_cast(mIdCollection)->addNestedRow(row, parent.column(), position); - - endInsertRows(); - - emit dataChanged (CSMWorld::IdTable::index (row, 0), - CSMWorld::IdTable::index (row, mIdCollection->getColumns()-1)); -} - QModelIndex CSMWorld::IdTable::index (int row, int column, const QModelIndex& parent) const { - unsigned int encodedId = 0; if (parent.isValid()) - { - encodedId = this->foldIndexAdress(parent); - } + return QModelIndex(); if (row<0 || row>=mIdCollection->getSize()) return QModelIndex(); @@ -207,24 +104,12 @@ QModelIndex CSMWorld::IdTable::index (int row, int column, const QModelIndex& pa if (column<0 || column>=mIdCollection->getColumns()) return QModelIndex(); - return createIndex(row, column, encodedId); + return createIndex (row, column); } QModelIndex CSMWorld::IdTable::parent (const QModelIndex& index) const { - if (index.internalId() == 0) //0 is used for indexs with invalid parent (top level data) - { - return QModelIndex(); - } - - unsigned int id = index.internalId(); - const std::pair& adress(unfoldIndexAdress(id)); - - if (adress.first >= this->rowCount() || adress.second >= this->columnCount()) - { - throw "Parent index is not present in the model"; - } - return createIndex(adress.first, adress.second); + return QModelIndex(); } void CSMWorld::IdTable::addRecord (const std::string& id, UniversalId::Type type) @@ -346,66 +231,3 @@ int CSMWorld::IdTable::getColumnId(int column) const { return mIdCollection->getColumn(column).getId(); } - -unsigned int CSMWorld::IdTable::foldIndexAdress (const QModelIndex& index) const -{ - unsigned int out = index.row() * this->columnCount(); - out += index.column(); - return ++out; -} - -std::pair< int, int > CSMWorld::IdTable::unfoldIndexAdress (unsigned int id) const -{ - if (id == 0) - { - throw "Attempt to unfold index id of the top level data cell"; - } - - --id; - int row = id / this->columnCount(); - int column = id - row * this->columnCount(); - return std::make_pair (row, column); -} - -bool CSMWorld::IdTable::hasChildren(const QModelIndex& index) const -{ - return (index.isValid() && - index.internalId() == 0 && - mIdCollection->getColumn(index.column()).mCanNest && - index.data().isValid()); -} - -void CSMWorld::IdTable::setNestedTable(const QModelIndex& index, const CSMWorld::NestedTableWrapperBase& nestedTable) -{ - if (!hasChildren(index)) - { - throw std::logic_error("Tried to set nested table, but index has no children"); - } - - bool removeRowsMode = false; - if (nestedTable.size() != this->nestedTable(index)->size()) - { - emit resetStart(this->index(index.row(), 0).data().toString()); - removeRowsMode = true; - } - - dynamic_cast(mIdCollection)->setNestedTable(index.row(), index.column(), nestedTable); - - emit dataChanged (CSMWorld::IdTable::index (index.row(), 0), - CSMWorld::IdTable::index (index.row(), mIdCollection->getColumns()-1)); - - if (removeRowsMode) - { - emit resetEnd(this->index(index.row(), 0).data().toString()); - } -} - -CSMWorld::NestedTableWrapperBase* CSMWorld::IdTable::nestedTable(const QModelIndex& index) const -{ - if (!hasChildren(index)) - { - throw std::logic_error("Tried to retrive nested table, but index has no children"); - } - - return dynamic_cast(mIdCollection)->nestedTable(index.row(), index.column()); -} diff --git a/apps/opencs/model/world/idtable.hpp b/apps/opencs/model/world/idtable.hpp index 05c523ccb8..ea8ab80f91 100644 --- a/apps/opencs/model/world/idtable.hpp +++ b/apps/opencs/model/world/idtable.hpp @@ -7,20 +7,10 @@ #include "universalid.hpp" #include "columns.hpp" -/*! \brief - * Clas for holding the model. Uses typical qt table abstraction/interface for granting access to the individiual fields of the records, - * Some records are holding nested data (for instance inventory list of the npc). In casses like this, table model offers interface - * to access nested data in the qt way – that is specify parent. Since some of those nested data require multiple columns to - * represent informations, single int (default way to index model in the qmodelindex) is not sufficiant. Therefore tablemodelindex class - * can hold two ints for the sake of indexing two dimensions of the table. This model does not support multiple levels of the nested - * data. Vast majority of methods makes sense only for the top level data. - */ - namespace CSMWorld { class CollectionBase; struct RecordBase; - class NestedTableWrapperBase; class IdTable : public IdTableBase { @@ -33,8 +23,6 @@ namespace CSMWorld // not implemented IdTable (const IdTable&); IdTable& operator= (const IdTable&); - unsigned int foldIndexAdress(const QModelIndex& index) const; - std::pair unfoldIndexAdress(unsigned int id) const; public: @@ -51,27 +39,17 @@ namespace CSMWorld virtual QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - QVariant nestedHeaderData(int section, int subSection, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - - NestedTableWrapperBase* nestedTable(const QModelIndex &index) const; - - void setNestedTable(const QModelIndex &index, const NestedTableWrapperBase& nestedTable); - virtual bool setData ( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); virtual Qt::ItemFlags flags (const QModelIndex & index) const; virtual bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex()); - void addNestedRow (const QModelIndex& parent, int position); - virtual QModelIndex index (int row, int column, const QModelIndex& parent = QModelIndex()) const; virtual QModelIndex parent (const QModelIndex& index) const; - virtual bool hasChildren (const QModelIndex& index) const; - void addRecord (const std::string& id, UniversalId::Type type = UniversalId::Type_None); ///< \param type Will be ignored, unless the collection supports multiple record types @@ -105,11 +83,6 @@ namespace CSMWorld virtual bool isDeleted (const std::string& id) const; int getColumnId(int column) const; - - signals: - void resetStart(const QString& id); - - void resetEnd(const QString& id); }; } diff --git a/apps/opencs/model/world/idtree.cpp b/apps/opencs/model/world/idtree.cpp new file mode 100644 index 0000000000..595b0ac51e --- /dev/null +++ b/apps/opencs/model/world/idtree.cpp @@ -0,0 +1,296 @@ +#include "idtree.hpp" + +#include "nestedtablewrapper.hpp" // FIXME: is this necessary? + +#include "nestedcollection.hpp" +#include "nestablecolumn.hpp" + +CSMWorld::IdTree::IdTree (NestedCollection *idCollection, unsigned int features) +: IdTable (idCollection, features), mIdCollection (idCollection) +{} + +CSMWorld::IdTree::~IdTree() +{ + // FIXME: workaround only, a proper fix should stop QHideEvent calls after destruction + mIdCollection = 0; +} + +int CSMWorld::IdTree::rowCount (const QModelIndex & parent) const +{ + if (hasChildren(parent)) + return mIdCollection->getNestedRowsCount(parent.row(), parent.column()); + + return mIdCollection->getSize(); +} + +int CSMWorld::IdTree::columnCount (const QModelIndex & parent) const +{ + if (hasChildren(parent)) + return mIdCollection->getNestedColumnsCount(parent.row(), parent.column()); + + return mIdCollection->getColumns(); +} + +QVariant CSMWorld::IdTree::data (const QModelIndex & index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if ((role!=Qt::DisplayRole && role!=Qt::EditRole) || index.row() < 0 || index.column() < 0) + return QVariant(); + + if (role==Qt::EditRole && !mIdCollection->getColumn (index.column()).isEditable()) + return QVariant(); + + if (index.internalId() != 0) + { + std::pair parentAdress(unfoldIndexAdress(index.internalId())); + + return mIdCollection->getNestedData(parentAdress.first, + parentAdress.second, index.row(), index.column()); + } + else + return mIdCollection->getData (index.row(), index.column()); +} + +QVariant CSMWorld::IdTree::headerData (int section, Qt::Orientation orientation, int role) const +{ + if (orientation==Qt::Vertical) + return QVariant(); + + if (orientation != Qt::Horizontal) + throw std::logic_error("Unknown header orientation specified"); + + if (role == Qt::DisplayRole) + return tr (mIdCollection->getColumn (section).getTitle().c_str()); + + if (role == ColumnBase::Role_Flags) + return mIdCollection->getColumn (section).mFlags; + + if (role == ColumnBase::Role_Display) + return mIdCollection->getColumn (section).mDisplayType; + + return QVariant(); +} + +QVariant CSMWorld::IdTree::nestedHeaderData(int section, int subSection, Qt::Orientation orientation, int role) const +{ + // FIXME: workaround only, a proper fix should stop QHideEvent calls after destruction + if (section < 0 || !mIdCollection || section >= mIdCollection->getColumns()) + return QVariant(); + + // FIXME: dynamic cast + const NestableColumn& parentColumn = dynamic_cast(mIdCollection->getColumn(section)); + + if (orientation==Qt::Vertical) + return QVariant(); + + if (role==Qt::DisplayRole) + return tr(parentColumn.nestedColumn(subSection).getTitle().c_str()); + + if (role==ColumnBase::Role_Flags) + return mIdCollection->getColumn (section).mFlags; + + if (role==ColumnBase::Role_Display) + return parentColumn.nestedColumn(subSection).mDisplayType; + + return QVariant(); +} + +bool CSMWorld::IdTree::setData (const QModelIndex &index, const QVariant &value, int role) +{ + if (index.internalId() != 0) + { + if (mIdCollection->getColumn(parent(index).column()).isEditable() && role==Qt::EditRole) + { + const std::pair& parentAdress(unfoldIndexAdress(index.internalId())); + + mIdCollection->setNestedData(parentAdress.first, parentAdress.second, value, index.row(), index.column()); + + emit dataChanged (CSMWorld::IdTree::index (parentAdress.first, 0), + CSMWorld::IdTree::index (parentAdress.second, mIdCollection->getColumns()-1)); + + return true; + } + else + return false; + } + + if (mIdCollection->getColumn (index.column()).isEditable() && role==Qt::EditRole) + { + mIdCollection->setData (index.row(), index.column(), value); + + emit dataChanged (CSMWorld::IdTree::index (index.row(), 0), + CSMWorld::IdTree::index (index.row(), mIdCollection->getColumns()-1)); + + return true; + } + + return false; +} + +Qt::ItemFlags CSMWorld::IdTree::flags (const QModelIndex & index) const +{ + if (!index.isValid()) + return 0; + + Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled; + + if (mIdCollection->getColumn (index.column()).isUserEditable()) + flags |= Qt::ItemIsEditable; + + return flags; +} + +bool CSMWorld::IdTree::removeRows (int row, int count, const QModelIndex& parent) +{ + beginRemoveRows (parent, row, row+count-1); + + if (parent.isValid()) + { + for (int i = 0; i < count; ++i) + { + mIdCollection->removeNestedRows(parent.row(), parent.column(), row+i); + } + } + else + { + + beginRemoveRows (parent, row, row+count-1); + + mIdCollection->removeRows (row, count); + } + + endRemoveRows(); + + emit dataChanged (CSMWorld::IdTree::index (parent.row(), 0), + CSMWorld::IdTree::index (parent.row(), mIdCollection->getColumns()-1)); + + return true; +} + +void CSMWorld::IdTree::addNestedRow(const QModelIndex& parent, int position) +{ + if (!hasChildren(parent)) + throw std::logic_error("Tried to set nested table, but index has no children"); + + int row = parent.row(); + + beginInsertRows(parent, position, position); + mIdCollection->addNestedRow(row, parent.column(), position); + endInsertRows(); + + emit dataChanged (CSMWorld::IdTree::index (row, 0), + CSMWorld::IdTree::index (row, mIdCollection->getColumns()-1)); +} + +QModelIndex CSMWorld::IdTree::index (int row, int column, const QModelIndex& parent) const +{ + unsigned int encodedId = 0; + if (parent.isValid()) + { + encodedId = this->foldIndexAdress(parent); + } + + if (row<0 || row>=mIdCollection->getSize()) + return QModelIndex(); + + if (column<0 || column>=mIdCollection->getColumns()) + return QModelIndex(); + + return createIndex(row, column, encodedId); // store internal id +} + +QModelIndex CSMWorld::IdTree::parent (const QModelIndex& index) const +{ + if (index.internalId() == 0) // 0 is used for indexs with invalid parent (top level data) + return QModelIndex(); + + unsigned int id = index.internalId(); + const std::pair& adress(unfoldIndexAdress(id)); + + if (adress.first >= this->rowCount() || adress.second >= this->columnCount()) + throw "Parent index is not present in the model"; + + return createIndex(adress.first, adress.second); +} + +void CSMWorld::IdTree::setRecord (const std::string& id, const RecordBase& record) +{ + int index = mIdCollection->searchId (id); + + if (index==-1) + { + int index = mIdCollection->getAppendIndex (id); + + beginInsertRows (QModelIndex(), index, index); + + mIdCollection->appendRecord (record); + + endInsertRows(); + } + else + { + mIdCollection->replace (index, record); + emit dataChanged (CSMWorld::IdTree::index (index, 0), + CSMWorld::IdTree::index (index, mIdCollection->getColumns()-1)); + } +} + +unsigned int CSMWorld::IdTree::foldIndexAdress (const QModelIndex& index) const +{ + unsigned int out = index.row() * this->columnCount(); + out += index.column(); + return ++out; +} + +std::pair< int, int > CSMWorld::IdTree::unfoldIndexAdress (unsigned int id) const +{ + if (id == 0) + throw "Attempt to unfold index id of the top level data cell"; + + --id; + int row = id / this->columnCount(); + int column = id - row * this->columnCount(); + return std::make_pair (row, column); +} + +bool CSMWorld::IdTree::hasChildren(const QModelIndex& index) const +{ + // FIXME: dynamic cast + return (index.isValid() && + index.internalId() == 0 && + dynamic_cast(mIdCollection->getColumn(index.column())).hasChildren() && + index.data().isValid()); +} + +void CSMWorld::IdTree::setNestedTable(const QModelIndex& index, const CSMWorld::NestedTableWrapperBase& nestedTable) +{ + if (!hasChildren(index)) + throw std::logic_error("Tried to set nested table, but index has no children"); + + bool removeRowsMode = false; + if (nestedTable.size() != this->nestedTable(index)->size()) + { + emit resetStart(this->index(index.row(), 0).data().toString()); + removeRowsMode = true; + } + + mIdCollection->setNestedTable(index.row(), index.column(), nestedTable); + + emit dataChanged (CSMWorld::IdTree::index (index.row(), 0), + CSMWorld::IdTree::index (index.row(), mIdCollection->getColumns()-1)); + + if (removeRowsMode) + { + emit resetEnd(this->index(index.row(), 0).data().toString()); + } +} + +CSMWorld::NestedTableWrapperBase* CSMWorld::IdTree::nestedTable(const QModelIndex& index) const +{ + if (!hasChildren(index)) + throw std::logic_error("Tried to retrive nested table, but index has no children"); + + return mIdCollection->nestedTable(index.row(), index.column()); +} diff --git a/apps/opencs/model/world/idtree.hpp b/apps/opencs/model/world/idtree.hpp new file mode 100644 index 0000000000..6a3d7423ca --- /dev/null +++ b/apps/opencs/model/world/idtree.hpp @@ -0,0 +1,88 @@ +#ifndef CSM_WOLRD_IDTREE_H +#define CSM_WOLRD_IDTREE_H + +#include "idtable.hpp" +#include "universalid.hpp" +#include "columns.hpp" + +/*! \brief + * Class for holding the model. Uses typical qt table abstraction/interface for granting access + * to the individiual fields of the records, Some records are holding nested data (for instance + * inventory list of the npc). In casses like this, table model offers interface to access + * nested data in the qt way - that is specify parent. Since some of those nested data require + * multiple columns to represent informations, single int (default way to index model in the + * qmodelindex) is not sufficiant. Therefore tablemodelindex class can hold two ints for the + * sake of indexing two dimensions of the table. This model does not support multiple levels of + * the nested data. Vast majority of methods makes sense only for the top level data. + */ + +namespace CSMWorld +{ + class NestedCollection; + struct RecordBase; + class NestedTableWrapperBase; // FIXME: is this necessary? + + class IdTree : public IdTable // IdTable is derived from QAbstractItemModel + { + Q_OBJECT + + private: + + NestedCollection *mIdCollection; + + // not implemented + IdTree (const IdTree&); + IdTree& operator= (const IdTree&); + + unsigned int foldIndexAdress(const QModelIndex& index) const; + std::pair unfoldIndexAdress(unsigned int id) const; + + public: + + IdTree (NestedCollection *idCollection, unsigned int features = 0); + ///< The ownership of \a idCollection is not transferred. + + virtual ~IdTree(); + + virtual int rowCount (const QModelIndex & parent = QModelIndex()) const; + + virtual int columnCount (const QModelIndex & parent = QModelIndex()) const; + + virtual QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const; + + virtual QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + + virtual bool setData ( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + + virtual Qt::ItemFlags flags (const QModelIndex & index) const; + + virtual bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex()); + + virtual QModelIndex index (int row, int column, const QModelIndex& parent = QModelIndex()) + const; + + virtual QModelIndex parent (const QModelIndex& index) const; + + void setRecord (const std::string& id, const RecordBase& record); + ///< Add record or overwrite existing recrod. + + // TODO: check if below methods are really needed + QVariant nestedHeaderData(int section, int subSection, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + + NestedTableWrapperBase* nestedTable(const QModelIndex &index) const; + + void setNestedTable(const QModelIndex &index, const NestedTableWrapperBase& nestedTable); + + void addNestedRow (const QModelIndex& parent, int position); + + virtual bool hasChildren (const QModelIndex& index) const; + + signals: + + void resetStart(const QString& id); + + void resetEnd(const QString& id); + }; +} + +#endif diff --git a/apps/opencs/model/world/nestablecolumn.cpp b/apps/opencs/model/world/nestablecolumn.cpp new file mode 100644 index 0000000000..4ade75b336 --- /dev/null +++ b/apps/opencs/model/world/nestablecolumn.cpp @@ -0,0 +1,44 @@ +#include "nestablecolumn.hpp" + +#include + +void CSMWorld::NestableColumn::addColumn(CSMWorld::NestableColumn *column) +{ + mNestedColumns.push_back(column); + mHasChildren = true; +} + +const CSMWorld::ColumnBase& CSMWorld::NestableColumn::nestedColumn(int subColumn) const +{ + if (!mHasChildren) + throw std::logic_error("Tried to access nested column of the non-nest column"); + + return *mNestedColumns.at(subColumn); +} + +int CSMWorld::NestableColumn::nestedColumnCount() const +{ + if (!mHasChildren) + throw std::logic_error("Tried to access number of the subcolumns in the non-nest column"); + + return mNestedColumns.size(); +} + +CSMWorld::NestableColumn::NestableColumn(int columnId, CSMWorld::ColumnBase::Display displayType, + int flag, const CSMWorld::NestableColumn* parent) + : mParent(parent), mHasChildren(false), CSMWorld::ColumnBase(columnId, displayType, flag) +{ +} + +CSMWorld::NestableColumn::~NestableColumn() +{ + for (unsigned int i = 0; i < mNestedColumns.size(); ++i) + { + delete mNestedColumns[i]; + } +} + +bool CSMWorld::NestableColumn::hasChildren() const +{ + return mHasChildren; +} diff --git a/apps/opencs/model/world/nestablecolumn.hpp b/apps/opencs/model/world/nestablecolumn.hpp new file mode 100644 index 0000000000..28ced85e99 --- /dev/null +++ b/apps/opencs/model/world/nestablecolumn.hpp @@ -0,0 +1,33 @@ +#ifndef CSM_WOLRD_NESTABLECOLUMN_H +#define CSM_WOLRD_NESTABLECOLUMN_H + +#include + +#include "columnbase.hpp" + +namespace CSMWorld +{ + class NestableColumn : public ColumnBase + { + std::vector mNestedColumns; + const NestableColumn* mParent; + bool mHasChildren; // cached + + public: + + NestableColumn(int columnId, + Display displayType, int flag, const NestableColumn* parent = 0); + + ~NestableColumn(); + + void addColumn(CSMWorld::NestableColumn *column); + + const ColumnBase& nestedColumn(int subColumn) const; + + int nestedColumnCount() const; + + bool hasChildren() const; + }; +} + +#endif diff --git a/apps/opencs/model/world/nestedcollection.hpp b/apps/opencs/model/world/nestedcollection.hpp index dffa295733..5ec50b4238 100644 --- a/apps/opencs/model/world/nestedcollection.hpp +++ b/apps/opencs/model/world/nestedcollection.hpp @@ -1,6 +1,8 @@ #ifndef CSM_WOLRD_NESTEDCOLLECTION_H #define CSM_WOLRD_NESTEDCOLLECTION_H +#include + #include "collectionbase.hpp" class QVariant; @@ -11,7 +13,12 @@ namespace CSMWorld class NestedCollection : public CollectionBase { + public: + + NestedCollection(); + virtual ~NestedCollection(); + virtual void addNestedRow(int row, int col, int position) = 0; virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const = 0; @@ -28,7 +35,10 @@ namespace CSMWorld virtual void removeNestedRows(int row, int column, int subRow) = 0; + private: + std::vector mChildren; + NestedCollection *mParent; // currently unused }; } diff --git a/apps/opencs/model/world/nestedtableproxymodel.cpp b/apps/opencs/model/world/nestedtableproxymodel.cpp index c098e03166..fede8383bc 100644 --- a/apps/opencs/model/world/nestedtableproxymodel.cpp +++ b/apps/opencs/model/world/nestedtableproxymodel.cpp @@ -1,11 +1,11 @@ #include "nestedtableproxymodel.hpp" #include -#include "idtable.hpp" +#include "idtree.hpp" CSMWorld::NestedTableProxyModel::NestedTableProxyModel(const QModelIndex& parent, ColumnBase::Display columnId, - CSMWorld::IdTable* parentModel) + CSMWorld::IdTree* parentModel) : mParentColumn(parent.column()), mMainModel(parentModel) { @@ -119,7 +119,7 @@ int CSMWorld::NestedTableProxyModel::getParentColumn() const return mParentColumn; } -CSMWorld::IdTable* CSMWorld::NestedTableProxyModel::model() const +CSMWorld::IdTree* CSMWorld::NestedTableProxyModel::model() const { return mMainModel; } diff --git a/apps/opencs/model/world/nestedtableproxymodel.hpp b/apps/opencs/model/world/nestedtableproxymodel.hpp index 7ad8fc0c23..7dc66989c7 100644 --- a/apps/opencs/model/world/nestedtableproxymodel.hpp +++ b/apps/opencs/model/world/nestedtableproxymodel.hpp @@ -17,27 +17,27 @@ namespace CSMWorld { class CollectionBase; class RecordBase; - class IdTable; + class IdTree; class NestedTableProxyModel : public QAbstractProxyModel { Q_OBJECT const int mParentColumn; - IdTable* mMainModel; + IdTree* mMainModel; std::string mId; public: NestedTableProxyModel(const QModelIndex& parent, ColumnBase::Display displayType, - IdTable* parentModel); + IdTree* parentModel); //parent is the parent of columns to work with. Columnid provides information about the column std::string getParentId() const; int getParentColumn() const; - CSMWorld::IdTable* model() const; + CSMWorld::IdTree* model() const; virtual QModelIndex mapFromSource(const QModelIndex& sourceIndex) const; diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index c488964358..ca5efcdd92 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -2,18 +2,17 @@ #include #include -#include #include #include "refidadapter.hpp" #include "refidadapterimp.hpp" #include "columns.hpp" -#include "nestedtablewrapper.hpp" +#include "nestedtablewrapper.hpp" // FIXME: is this really necessary? CSMWorld::RefIdColumn::RefIdColumn (int columnId, Display displayType, int flag, - bool editable, bool userEditable, bool canNest) - : NestColumn (columnId, displayType, flag, canNest), mEditable (editable), mUserEditable (userEditable) + bool editable, bool userEditable) + : NestableColumn (columnId, displayType, flag), mEditable (editable), mUserEditable (userEditable) {} bool CSMWorld::RefIdColumn::isEditable() const @@ -27,7 +26,8 @@ bool CSMWorld::RefIdColumn::isUserEditable() const } -CSMWorld::RefIdAdapter& CSMWorld::RefIdCollection::findAdapter (UniversalId::Type type) const +// FIXME: const problem +/*const*/ CSMWorld::RefIdAdapter& CSMWorld::RefIdCollection::findAdapter (UniversalId::Type type) const { std::map::const_iterator iter = mAdapters.find (type); @@ -99,14 +99,19 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn (Columns::ColumnId_AiAlarm, ColumnBase::Display_Integer)); actorsColumns.mAlarm = &mColumns.back(); - mColumns.push_back(RefIdColumn (Columns::ColumnId_ActorInventory, ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue, true, true, true)); + // Nested table + mColumns.push_back(RefIdColumn (Columns::ColumnId_ActorInventory, ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue)); actorsColumns.mInventory = &mColumns.back(); - mColumns.back().addNestedColumn(Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String); - mColumns.back().addNestedColumn(Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer)); - mColumns.push_back(RefIdColumn (Columns::ColumnId_ActorSpells, ColumnBase::Display_NestedSpellList, ColumnBase::Flag_Dialogue, true, true, true)); + // Nested table + mColumns.push_back(RefIdColumn (Columns::ColumnId_ActorSpells, ColumnBase::Display_NestedSpellList, ColumnBase::Flag_Dialogue)); actorsColumns.mSpells = &mColumns.back(); - mColumns.back().addNestedColumn(Columns::ColumnId_SpellId, CSMWorld::ColumnBase::Display_String); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_SpellId, CSMWorld::ColumnBase::Display_String)); static const struct { @@ -175,10 +180,13 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn (Columns::ColumnId_Respawn, ColumnBase::Display_Boolean)); const RefIdColumn *respawn = &mColumns.back(); - mColumns.push_back(RefIdColumn (Columns::ColumnId_ContainerContent, ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue, true, true, true)); + // Nested table + mColumns.push_back(RefIdColumn (Columns::ColumnId_ContainerContent, ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue)); const RefIdColumn *content = &mColumns.back(); - mColumns.back().addNestedColumn(Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String); - mColumns.back().addNestedColumn(Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer)); CreatureColumns creatureColumns (actorsColumns); @@ -315,16 +323,24 @@ CSMWorld::RefIdCollection::RefIdCollection() npcColumns.mFlags.insert (std::make_pair (metalBlood, ESM::NPC::Metal)); - mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcDestinations, ColumnBase::Display_NestedDestinationsList, ColumnBase::Flag_Dialogue, true, true, true)); + // Nested table + mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcDestinations, ColumnBase::Display_NestedDestinationsList, ColumnBase::Flag_Dialogue)); npcColumns.mDestinations = &mColumns.back(); - mColumns.back().addNestedColumn(Columns::ColumnId_DestinationCell, CSMWorld::ColumnBase::Display_String); - mColumns.back().addNestedColumn(Columns::ColumnId_PosX, CSMWorld::ColumnBase::Display_Float); - mColumns.back().addNestedColumn(Columns::ColumnId_PosY, CSMWorld::ColumnBase::Display_Float); - mColumns.back().addNestedColumn(Columns::ColumnId_PosZ, CSMWorld::ColumnBase::Display_Float); - mColumns.back().addNestedColumn(Columns::ColumnId_RotX, CSMWorld::ColumnBase::Display_Float); - mColumns.back().addNestedColumn(Columns::ColumnId_RotY, CSMWorld::ColumnBase::Display_Float); - mColumns.back().addNestedColumn(Columns::ColumnId_RotZ, CSMWorld::ColumnBase::Display_Float); - + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_DestinationCell, CSMWorld::ColumnBase::Display_String)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_PosX, CSMWorld::ColumnBase::Display_Float)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_PosY, CSMWorld::ColumnBase::Display_Float)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_PosZ, CSMWorld::ColumnBase::Display_Float)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_RotX, CSMWorld::ColumnBase::Display_Float)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_RotY, CSMWorld::ColumnBase::Display_Float)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_RotZ, CSMWorld::ColumnBase::Display_Float)); + WeaponColumns weaponColumns (enchantableColumns); mColumns.push_back (RefIdColumn (Columns::ColumnId_WeaponType, ColumnBase::Display_WeaponType)); @@ -664,8 +680,10 @@ void CSMWorld::RefIdCollection::setNestedTable(int row, int column, const CSMWor { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + // FIXME: const problem CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdapter (localIndex.second)); + // FIXME: const problem adaptor.setNestedTable(&mColumns.at(column), mData, localIndex.first, nestedTable); } diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index ab25c93fa3..dd432c5a96 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -5,8 +5,7 @@ #include #include -#include "columnbase.hpp" -#include "collectionbase.hpp" +#include "nestablecolumn.hpp" #include "nestedcollection.hpp" #include "refiddata.hpp" @@ -18,9 +17,9 @@ namespace ESM namespace CSMWorld { class RefIdAdapter; - class NestedTableWrapperBase; + class NestedTableWrapperBase; // FIXME: is this really needed? - class RefIdColumn : public NestColumn + class RefIdColumn : public NestableColumn { bool mEditable; bool mUserEditable; @@ -29,7 +28,7 @@ namespace CSMWorld RefIdColumn (int columnId, Display displayType, int flag = Flag_Table | Flag_Dialogue, bool editable = true, - bool userEditable = true, bool canNest = false); + bool userEditable = true); virtual bool isEditable() const; @@ -46,7 +45,7 @@ namespace CSMWorld private: - RefIdAdapter& findAdapter (UniversalId::Type) const; + /*const*/ RefIdAdapter& findAdapter (UniversalId::Type) const; ///< Throws an exception if no adaptor for \a Type can be found. public: @@ -57,10 +56,6 @@ namespace CSMWorld virtual int getSize() const; - virtual int getNestedRowsCount(int row, int column) const; - - virtual int getNestedColumnsCount(int row, int column) const; - virtual std::string getId (int index) const; virtual int getIndex (const std::string& id) const; @@ -71,22 +66,10 @@ namespace CSMWorld virtual QVariant getData (int index, int column) const; - virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const; - - virtual NestedTableWrapperBase* nestedTable(int row, int column) const; - - virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable); - virtual void setData (int index, int column, const QVariant& data); - virtual void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn); - virtual void removeRows (int index, int count); - virtual void removeNestedRows(int row, int column, int subRow); - - virtual void addNestedRow(int row, int col, int position); - virtual void cloneRecord(const std::string& origin, const std::string& destination, const UniversalId::Type type); @@ -128,6 +111,24 @@ namespace CSMWorld /// /// \return Success? + virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const; + + virtual NestedTableWrapperBase* nestedTable(int row, int column) const; + + virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable); + + // FIXME + virtual int getNestedRowsCount(int row, int column) const; + + // FIXME + virtual int getNestedColumnsCount(int row, int column) const; + + virtual void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn); + + virtual void removeNestedRows(int row, int column, int subRow); + + virtual void addNestedRow(int row, int col, int position); + void save (int index, ESM::ESMWriter& writer) const; const RefIdData& getDataSet() const; //I can't figure out a better name for this one :( diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index bfdd4f9eec..eaa7b115d3 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -52,7 +52,7 @@ namespace CSMWorld virtual void load (int index, ESM::ESMReader& reader, bool base) = 0; virtual void erase (int index, int count) = 0; - + virtual std::string getId (int index) const = 0; virtual void save (int index, ESM::ESMWriter& writer) const = 0; @@ -134,7 +134,7 @@ namespace CSMWorld throw std::runtime_error ("invalid RefIdDataContainer index"); mContainer.erase (mContainer.begin()+index, mContainer.begin()+index+count); - } + } template std::string RefIdDataContainer::getId (int index) const @@ -231,7 +231,7 @@ namespace CSMWorld void save (int index, ESM::ESMWriter& writer) const; - //RECORD CONTAINERS ACCESS METHODS + //RECORD CONTAINERS ACCESS METHODS const RefIdDataContainer& getBooks() const; const RefIdDataContainer& getActivators() const; const RefIdDataContainer& getPotions() const; diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index e26dcdc9ba..0aa83eb921 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -26,6 +26,7 @@ #include "../../model/world/nestedtableproxymodel.hpp" #include "../../model/world/columnbase.hpp" #include "../../model/world/idtable.hpp" +#include "../../model/world/idtree.hpp" #include "../../model/world/columns.hpp" #include "../../model/world/record.hpp" #include "../../model/world/tablemimedata.hpp" @@ -422,7 +423,7 @@ void CSVWorld::EditWidget::remake(int row) if (mTable->hasChildren(mTable->index(row, i))) { - mNestedModels.push_back(new CSMWorld::NestedTableProxyModel (mTable->index(row, i), display, mTable)); + mNestedModels.push_back(new CSMWorld::NestedTableProxyModel (mTable->index(row, i), display, dynamic_cast(mTable))); NestedTable* table = new NestedTable(mDocument, mNestedModels.back(), this); From 8eaf6b068cf6f91e0493a0e1673c691e0fbd7b55 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Thu, 2 Apr 2015 21:02:17 +1100 Subject: [PATCH 098/185] Adding missing file. --- apps/opencs/model/world/nestedcollection.cpp | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 apps/opencs/model/world/nestedcollection.cpp diff --git a/apps/opencs/model/world/nestedcollection.cpp b/apps/opencs/model/world/nestedcollection.cpp new file mode 100644 index 0000000000..f557c3ba1d --- /dev/null +++ b/apps/opencs/model/world/nestedcollection.cpp @@ -0,0 +1,7 @@ +#include "nestedcollection.hpp" + +CSMWorld::NestedCollection::NestedCollection() : mParent(0) +{} + +CSMWorld::NestedCollection::~NestedCollection() +{} From 745eae9c10b01885a6245df2f87f366867123b96 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Fri, 3 Apr 2015 12:44:32 +1100 Subject: [PATCH 099/185] Tweak DialogueSubView layout for nested tables. --- apps/opencs/view/world/dialoguesubview.cpp | 39 ++++++---------------- 1 file changed, 10 insertions(+), 29 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 0aa83eb921..d0b53a2061 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -17,11 +17,9 @@ #include #include #include -#include #include #include #include -#include #include "../../model/world/nestedtableproxymodel.hpp" #include "../../model/world/columnbase.hpp" @@ -384,27 +382,17 @@ void CSVWorld::EditWidget::remake(int row) mWidgetMapper->setModel(mTable); mWidgetMapper->setItemDelegate(&mDispatcher); - QFrame* line = new QFrame(mMainWidget); - line->setObjectName(QString::fromUtf8("line")); - line->setGeometry(QRect(320, 150, 118, 3)); - line->setFrameShape(QFrame::HLine); - line->setFrameShadow(QFrame::Sunken); - - QFrame* line2 = new QFrame(mMainWidget); - line2->setObjectName(QString::fromUtf8("line2")); - line2->setGeometry(QRect(320, 150, 118, 3)); - line2->setFrameShape(QFrame::HLine); - line2->setFrameShadow(QFrame::Sunken); - QVBoxLayout *mainLayout = new QVBoxLayout(mMainWidget); - QGridLayout *unlockedLayout = new QGridLayout(); + QScrollArea *scroll = new QScrollArea(mMainWidget); + QWidget *unlockedWidget = new QWidget(scroll); + QGridLayout *unlockedLayout = new QGridLayout(unlockedWidget); QGridLayout *lockedLayout = new QGridLayout(); QVBoxLayout *tablesLayout = new QVBoxLayout(); mainLayout->addLayout(lockedLayout, 0); - mainLayout->addWidget(line, 1); - mainLayout->addLayout(unlockedLayout, 2); - mainLayout->addWidget(line2, 1); + mainLayout->addSpacing(5); // FIXME: arbitrary number + mainLayout->addWidget(scroll, 2); + mainLayout->addSpacing(5); // FIXME: arbitrary number mainLayout->addLayout(tablesLayout, 0); mainLayout->addStretch(1); @@ -426,18 +414,8 @@ void CSVWorld::EditWidget::remake(int row) mNestedModels.push_back(new CSMWorld::NestedTableProxyModel (mTable->index(row, i), display, dynamic_cast(mTable))); NestedTable* table = new NestedTable(mDocument, mNestedModels.back(), this); + table->resizeColumnsToContents(); - int rows = mNestedModels.back()->rowCount(mTable->index(row, i)); - if (rows == 0) rows = 1; // FIXME: quick hack - int rowHeight = table->rowHeight(0); - int tableHeight = (rows * rowHeight) - + table->horizontalHeader()->height() + 2 * table->frameWidth(); - int tableMaxHeight = (5 * rowHeight) - + table->horizontalHeader()->height() + 2 * table->frameWidth(); - if (rows > 1 && rows < 5) - table->setMinimumHeight(tableHeight); - else if (rows > 1) - table->setMinimumHeight(tableMaxHeight); QLabel* label = new QLabel (mTable->headerData (i, Qt::Horizontal, Qt::DisplayRole).toString(), mMainWidget); @@ -479,6 +457,9 @@ void CSVWorld::EditWidget::remake(int row) mWidgetMapper->setCurrentModelIndex(mTable->index(row, 0)); + scroll->setWidget(unlockedWidget); + scroll->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Fixed); + scroll->setWidgetResizable(true); this->setWidget(mMainWidget); this->setWidgetResizable(true); } From bdf0d8db22c2a766e1774b2649b1e91cc69da24b Mon Sep 17 00:00:00 2001 From: cc9cii Date: Thu, 9 Apr 2015 19:11:19 +1000 Subject: [PATCH 100/185] Re-organise the inheritance structure once more in preparation for adding Pathgrid tables. --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/world/collection.hpp | 11 ++ apps/opencs/model/world/columnbase.cpp | 33 ++++ apps/opencs/model/world/columnbase.hpp | 24 ++- apps/opencs/model/world/data.cpp | 2 +- apps/opencs/model/world/idtable.cpp | 10 ++ apps/opencs/model/world/idtable.hpp | 4 + apps/opencs/model/world/idtree.cpp | 162 ++++++------------- apps/opencs/model/world/idtree.hpp | 13 +- apps/opencs/model/world/nestablecolumn.cpp | 44 ----- apps/opencs/model/world/nestablecolumn.hpp | 33 ---- apps/opencs/model/world/nestedcollection.cpp | 12 +- apps/opencs/model/world/nestedcollection.hpp | 26 ++- apps/opencs/model/world/refidcollection.cpp | 8 +- apps/opencs/model/world/refidcollection.hpp | 11 +- 15 files changed, 168 insertions(+), 227 deletions(-) delete mode 100644 apps/opencs/model/world/nestablecolumn.cpp delete mode 100644 apps/opencs/model/world/nestablecolumn.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 39b4c486bc..8cf37da1d2 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -25,7 +25,7 @@ opencs_units (model/world opencs_units_noqt (model/world universalid record commands columnbase scriptcontext cell refidcollection refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope - pathgrid landtexture land nestedtablewrapper nestedadapters nestedcollection nestablecolumn + pathgrid landtexture land nestedtablewrapper nestedadapters nestedcollection ) opencs_hdrs_noqt (model/world diff --git a/apps/opencs/model/world/collection.hpp b/apps/opencs/model/world/collection.hpp index 1fb3e1f1db..dc52ae663b 100644 --- a/apps/opencs/model/world/collection.hpp +++ b/apps/opencs/model/world/collection.hpp @@ -148,6 +148,8 @@ namespace CSMWorld void setRecord (int index, const Record& record); ///< \attention This function must not change the ID. + + NestableColumn *getNestableColumn (int column); }; template @@ -289,6 +291,15 @@ namespace CSMWorld return *mColumns.at (column); } + template + NestableColumn *Collection::getNestableColumn (int column) + { + if (column < 0 || column >= static_cast(mColumns.size())) + throw std::runtime_error("column index out of range"); + + return mColumns.at (column); + } + template void Collection::addColumn (Column *column) { diff --git a/apps/opencs/model/world/columnbase.cpp b/apps/opencs/model/world/columnbase.cpp index 665ab93545..94c5afb83a 100644 --- a/apps/opencs/model/world/columnbase.cpp +++ b/apps/opencs/model/world/columnbase.cpp @@ -23,3 +23,36 @@ int CSMWorld::ColumnBase::getId() const { return mColumnId; } + +void CSMWorld::NestableColumn::addColumn(CSMWorld::NestableColumn *column) +{ + mNestedColumns.push_back(column); + mHasChildren = true; +} + +const CSMWorld::ColumnBase& CSMWorld::NestableColumn::nestedColumn(int subColumn) const +{ + if (!mHasChildren) + throw std::logic_error("Tried to access nested column of the non-nest column"); + + return *mNestedColumns.at(subColumn); +} + +CSMWorld::NestableColumn::NestableColumn(int columnId, CSMWorld::ColumnBase::Display displayType, + int flag) + : mHasChildren(false), CSMWorld::ColumnBase(columnId, displayType, flag) +{ +} + +CSMWorld::NestableColumn::~NestableColumn() +{ + for (unsigned int i = 0; i < mNestedColumns.size(); ++i) + { + delete mNestedColumns[i]; + } +} + +bool CSMWorld::NestableColumn::hasChildren() const +{ + return mHasChildren; +} diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index b717f3a52b..da1d8f0df5 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -129,14 +129,32 @@ namespace CSMWorld virtual std::string getTitle() const; - virtual int getId() const; + virtual int getId() const; // FIXME: why have an accessor for a public member? + }; + + class NestableColumn : public ColumnBase + { + std::vector mNestedColumns; + bool mHasChildren; + + public: + + NestableColumn(int columnId, Display displayType, int flag); + + ~NestableColumn(); + + void addColumn(CSMWorld::NestableColumn *column); + + const ColumnBase& nestedColumn(int subColumn) const; + + bool hasChildren() const; }; template - struct Column : public ColumnBase + struct Column : public NestableColumn { Column (int columnId, Display displayType, int flags = Flag_Table | Flag_Dialogue) - : ColumnBase (columnId, displayType, flags) {} + : NestableColumn (columnId, displayType, flags) {} virtual QVariant get (const Record& record) const = 0; diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index a5ef439a7e..0cfc890ea6 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -333,7 +333,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc addModel (new IdTable (&mMagicEffects), UniversalId::Type_MagicEffect); addModel (new IdTable (&mPathgrids), UniversalId::Type_Pathgrid); addModel (new IdTable (&mStartScripts), UniversalId::Type_StartScript); - addModel (new IdTree (&mReferenceables, IdTable::Feature_Preview), + addModel (new IdTree (&mReferenceables, &mReferenceables, IdTable::Feature_Preview), UniversalId::Type_Referenceable); addModel (new IdTable (&mRefs, IdTable::Feature_ViewCell | IdTable::Feature_Preview), UniversalId::Type_Reference); addModel (new IdTable (&mFilters), UniversalId::Type_Filter); diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index 7618a073a9..28742c8f2c 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -1,5 +1,7 @@ #include "idtable.hpp" +#include + #include "collectionbase.hpp" #include "columnbase.hpp" @@ -42,6 +44,9 @@ QVariant CSMWorld::IdTable::headerData (int section, Qt::Orientation orientation if (orientation==Qt::Vertical) return QVariant(); + if (orientation != Qt::Horizontal) + throw std::logic_error("Unknown header orientation specified"); + if (role==Qt::DisplayRole) return tr (mIdCollection->getColumn (section).getTitle().c_str()); @@ -231,3 +236,8 @@ int CSMWorld::IdTable::getColumnId(int column) const { return mIdCollection->getColumn(column).getId(); } + +CSMWorld::CollectionBase *CSMWorld::IdTable::idCollection() const +{ + return mIdCollection; +} diff --git a/apps/opencs/model/world/idtable.hpp b/apps/opencs/model/world/idtable.hpp index ea8ab80f91..914b01cf9e 100644 --- a/apps/opencs/model/world/idtable.hpp +++ b/apps/opencs/model/world/idtable.hpp @@ -83,6 +83,10 @@ namespace CSMWorld virtual bool isDeleted (const std::string& id) const; int getColumnId(int column) const; + + protected: + + virtual CollectionBase *idCollection() const; }; } diff --git a/apps/opencs/model/world/idtree.cpp b/apps/opencs/model/world/idtree.cpp index 595b0ac51e..4befd1eeec 100644 --- a/apps/opencs/model/world/idtree.cpp +++ b/apps/opencs/model/world/idtree.cpp @@ -1,34 +1,33 @@ #include "idtree.hpp" -#include "nestedtablewrapper.hpp" // FIXME: is this necessary? +#include "nestedtablewrapper.hpp" +#include "collectionbase.hpp" #include "nestedcollection.hpp" -#include "nestablecolumn.hpp" +#include "columnbase.hpp" -CSMWorld::IdTree::IdTree (NestedCollection *idCollection, unsigned int features) -: IdTable (idCollection, features), mIdCollection (idCollection) +// NOTE: parent class still needs idCollection +CSMWorld::IdTree::IdTree (NestedCollection *nestedCollection, CollectionBase *idCollection, unsigned int features) +: IdTable (idCollection, features), mNestedCollection (nestedCollection) {} CSMWorld::IdTree::~IdTree() -{ - // FIXME: workaround only, a proper fix should stop QHideEvent calls after destruction - mIdCollection = 0; -} +{} int CSMWorld::IdTree::rowCount (const QModelIndex & parent) const { if (hasChildren(parent)) - return mIdCollection->getNestedRowsCount(parent.row(), parent.column()); + return mNestedCollection->getNestedRowsCount(parent.row(), parent.column()); - return mIdCollection->getSize(); + return IdTable::rowCount(parent); } int CSMWorld::IdTree::columnCount (const QModelIndex & parent) const { if (hasChildren(parent)) - return mIdCollection->getNestedColumnsCount(parent.row(), parent.column()); + return mNestedCollection->getNestedColumnsCount(parent.row(), parent.column()); - return mIdCollection->getColumns(); + return IdTable::columnCount(parent); } QVariant CSMWorld::IdTree::data (const QModelIndex & index, int role) const @@ -39,60 +38,39 @@ QVariant CSMWorld::IdTree::data (const QModelIndex & index, int role) const if ((role!=Qt::DisplayRole && role!=Qt::EditRole) || index.row() < 0 || index.column() < 0) return QVariant(); - if (role==Qt::EditRole && !mIdCollection->getColumn (index.column()).isEditable()) + if (role==Qt::EditRole && !idCollection()->getColumn (index.column()).isEditable()) return QVariant(); if (index.internalId() != 0) { std::pair parentAdress(unfoldIndexAdress(index.internalId())); - return mIdCollection->getNestedData(parentAdress.first, + return mNestedCollection->getNestedData(parentAdress.first, parentAdress.second, index.row(), index.column()); } else - return mIdCollection->getData (index.row(), index.column()); -} - -QVariant CSMWorld::IdTree::headerData (int section, Qt::Orientation orientation, int role) const -{ - if (orientation==Qt::Vertical) - return QVariant(); - - if (orientation != Qt::Horizontal) - throw std::logic_error("Unknown header orientation specified"); - - if (role == Qt::DisplayRole) - return tr (mIdCollection->getColumn (section).getTitle().c_str()); - - if (role == ColumnBase::Role_Flags) - return mIdCollection->getColumn (section).mFlags; - - if (role == ColumnBase::Role_Display) - return mIdCollection->getColumn (section).mDisplayType; - - return QVariant(); + return idCollection()->getData (index.row(), index.column()); } QVariant CSMWorld::IdTree::nestedHeaderData(int section, int subSection, Qt::Orientation orientation, int role) const { // FIXME: workaround only, a proper fix should stop QHideEvent calls after destruction - if (section < 0 || !mIdCollection || section >= mIdCollection->getColumns()) + if (section < 0 || !idCollection() || section >= idCollection()->getColumns()) return QVariant(); - // FIXME: dynamic cast - const NestableColumn& parentColumn = dynamic_cast(mIdCollection->getColumn(section)); + const NestableColumn *parentColumn = mNestedCollection->getNestableColumn(section); if (orientation==Qt::Vertical) return QVariant(); if (role==Qt::DisplayRole) - return tr(parentColumn.nestedColumn(subSection).getTitle().c_str()); + return tr(parentColumn->nestedColumn(subSection).getTitle().c_str()); if (role==ColumnBase::Role_Flags) - return mIdCollection->getColumn (section).mFlags; + return idCollection()->getColumn (section).mFlags; if (role==ColumnBase::Role_Display) - return parentColumn.nestedColumn(subSection).mDisplayType; + return parentColumn->nestedColumn(subSection).mDisplayType; return QVariant(); } @@ -101,32 +79,21 @@ bool CSMWorld::IdTree::setData (const QModelIndex &index, const QVariant &value, { if (index.internalId() != 0) { - if (mIdCollection->getColumn(parent(index).column()).isEditable() && role==Qt::EditRole) + if (idCollection()->getColumn(parent(index).column()).isEditable() && role==Qt::EditRole) { const std::pair& parentAdress(unfoldIndexAdress(index.internalId())); - mIdCollection->setNestedData(parentAdress.first, parentAdress.second, value, index.row(), index.column()); + mNestedCollection->setNestedData(parentAdress.first, parentAdress.second, value, index.row(), index.column()); emit dataChanged (CSMWorld::IdTree::index (parentAdress.first, 0), - CSMWorld::IdTree::index (parentAdress.second, mIdCollection->getColumns()-1)); + CSMWorld::IdTree::index (parentAdress.second, idCollection()->getColumns()-1)); return true; } else return false; } - - if (mIdCollection->getColumn (index.column()).isEditable() && role==Qt::EditRole) - { - mIdCollection->setData (index.row(), index.column(), value); - - emit dataChanged (CSMWorld::IdTree::index (index.row(), 0), - CSMWorld::IdTree::index (index.row(), mIdCollection->getColumns()-1)); - - return true; - } - - return false; + return IdTable::setData(index, value, role); } Qt::ItemFlags CSMWorld::IdTree::flags (const QModelIndex & index) const @@ -134,39 +101,29 @@ Qt::ItemFlags CSMWorld::IdTree::flags (const QModelIndex & index) const if (!index.isValid()) return 0; - Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled; - - if (mIdCollection->getColumn (index.column()).isUserEditable()) - flags |= Qt::ItemIsEditable; - - return flags; + return IdTable::flags(index); } bool CSMWorld::IdTree::removeRows (int row, int count, const QModelIndex& parent) { - beginRemoveRows (parent, row, row+count-1); - if (parent.isValid()) { - for (int i = 0; i < count; ++i) - { - mIdCollection->removeNestedRows(parent.row(), parent.column(), row+i); - } - } - else - { - beginRemoveRows (parent, row, row+count-1); - mIdCollection->removeRows (row, count); + for (int i = 0; i < count; ++i) + { + mNestedCollection->removeNestedRows(parent.row(), parent.column(), row+i); + } + + endRemoveRows(); + + emit dataChanged (CSMWorld::IdTree::index (parent.row(), 0), + CSMWorld::IdTree::index (parent.row(), idCollection()->getColumns()-1)); + + return true; } - - endRemoveRows(); - - emit dataChanged (CSMWorld::IdTree::index (parent.row(), 0), - CSMWorld::IdTree::index (parent.row(), mIdCollection->getColumns()-1)); - - return true; + else + return IdTable::removeRows(row, count, parent); } void CSMWorld::IdTree::addNestedRow(const QModelIndex& parent, int position) @@ -177,11 +134,11 @@ void CSMWorld::IdTree::addNestedRow(const QModelIndex& parent, int position) int row = parent.row(); beginInsertRows(parent, position, position); - mIdCollection->addNestedRow(row, parent.column(), position); + mNestedCollection->addNestedRow(row, parent.column(), position); endInsertRows(); emit dataChanged (CSMWorld::IdTree::index (row, 0), - CSMWorld::IdTree::index (row, mIdCollection->getColumns()-1)); + CSMWorld::IdTree::index (row, idCollection()->getColumns()-1)); } QModelIndex CSMWorld::IdTree::index (int row, int column, const QModelIndex& parent) const @@ -192,10 +149,10 @@ QModelIndex CSMWorld::IdTree::index (int row, int column, const QModelIndex& par encodedId = this->foldIndexAdress(parent); } - if (row<0 || row>=mIdCollection->getSize()) + if (row<0 || row>=idCollection()->getSize()) return QModelIndex(); - if (column<0 || column>=mIdCollection->getColumns()) + if (column<0 || column>=idCollection()->getColumns()) return QModelIndex(); return createIndex(row, column, encodedId); // store internal id @@ -215,28 +172,6 @@ QModelIndex CSMWorld::IdTree::parent (const QModelIndex& index) const return createIndex(adress.first, adress.second); } -void CSMWorld::IdTree::setRecord (const std::string& id, const RecordBase& record) -{ - int index = mIdCollection->searchId (id); - - if (index==-1) - { - int index = mIdCollection->getAppendIndex (id); - - beginInsertRows (QModelIndex(), index, index); - - mIdCollection->appendRecord (record); - - endInsertRows(); - } - else - { - mIdCollection->replace (index, record); - emit dataChanged (CSMWorld::IdTree::index (index, 0), - CSMWorld::IdTree::index (index, mIdCollection->getColumns()-1)); - } -} - unsigned int CSMWorld::IdTree::foldIndexAdress (const QModelIndex& index) const { unsigned int out = index.row() * this->columnCount(); @@ -255,13 +190,16 @@ std::pair< int, int > CSMWorld::IdTree::unfoldIndexAdress (unsigned int id) cons return std::make_pair (row, column); } +// index.data().isValid() requires RefIdAdapter::getData() to return a valid QVariant for +// nested columns (refidadapterimp.hpp) +// +// Also see comments in refidadapter.hpp and refidadapterimp.hpp. bool CSMWorld::IdTree::hasChildren(const QModelIndex& index) const { - // FIXME: dynamic cast return (index.isValid() && index.internalId() == 0 && - dynamic_cast(mIdCollection->getColumn(index.column())).hasChildren() && - index.data().isValid()); + mNestedCollection->getNestableColumn(index.column())->hasChildren() && + index.data().isValid()); // FIXME: not sure why this check is also needed } void CSMWorld::IdTree::setNestedTable(const QModelIndex& index, const CSMWorld::NestedTableWrapperBase& nestedTable) @@ -276,10 +214,10 @@ void CSMWorld::IdTree::setNestedTable(const QModelIndex& index, const CSMWorld:: removeRowsMode = true; } - mIdCollection->setNestedTable(index.row(), index.column(), nestedTable); + mNestedCollection->setNestedTable(index.row(), index.column(), nestedTable); emit dataChanged (CSMWorld::IdTree::index (index.row(), 0), - CSMWorld::IdTree::index (index.row(), mIdCollection->getColumns()-1)); + CSMWorld::IdTree::index (index.row(), idCollection()->getColumns()-1)); if (removeRowsMode) { @@ -292,5 +230,5 @@ CSMWorld::NestedTableWrapperBase* CSMWorld::IdTree::nestedTable(const QModelInde if (!hasChildren(index)) throw std::logic_error("Tried to retrive nested table, but index has no children"); - return mIdCollection->nestedTable(index.row(), index.column()); + return mNestedCollection->nestedTable(index.row(), index.column()); } diff --git a/apps/opencs/model/world/idtree.hpp b/apps/opencs/model/world/idtree.hpp index 6a3d7423ca..80b44d241f 100644 --- a/apps/opencs/model/world/idtree.hpp +++ b/apps/opencs/model/world/idtree.hpp @@ -22,13 +22,13 @@ namespace CSMWorld struct RecordBase; class NestedTableWrapperBase; // FIXME: is this necessary? - class IdTree : public IdTable // IdTable is derived from QAbstractItemModel + class IdTree : public IdTable { Q_OBJECT private: - NestedCollection *mIdCollection; + NestedCollection *mNestedCollection; // not implemented IdTree (const IdTree&); @@ -39,8 +39,8 @@ namespace CSMWorld public: - IdTree (NestedCollection *idCollection, unsigned int features = 0); - ///< The ownership of \a idCollection is not transferred. + IdTree (NestedCollection *nestedCollection, CollectionBase *idCollection, unsigned int features = 0); + ///< The ownerships of \a nestedCollecton and \a idCollection are not transferred. virtual ~IdTree(); @@ -50,8 +50,6 @@ namespace CSMWorld virtual QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const; - virtual QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - virtual bool setData ( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); virtual Qt::ItemFlags flags (const QModelIndex & index) const; @@ -63,9 +61,6 @@ namespace CSMWorld virtual QModelIndex parent (const QModelIndex& index) const; - void setRecord (const std::string& id, const RecordBase& record); - ///< Add record or overwrite existing recrod. - // TODO: check if below methods are really needed QVariant nestedHeaderData(int section, int subSection, Qt::Orientation orientation, int role = Qt::DisplayRole) const; diff --git a/apps/opencs/model/world/nestablecolumn.cpp b/apps/opencs/model/world/nestablecolumn.cpp deleted file mode 100644 index 4ade75b336..0000000000 --- a/apps/opencs/model/world/nestablecolumn.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "nestablecolumn.hpp" - -#include - -void CSMWorld::NestableColumn::addColumn(CSMWorld::NestableColumn *column) -{ - mNestedColumns.push_back(column); - mHasChildren = true; -} - -const CSMWorld::ColumnBase& CSMWorld::NestableColumn::nestedColumn(int subColumn) const -{ - if (!mHasChildren) - throw std::logic_error("Tried to access nested column of the non-nest column"); - - return *mNestedColumns.at(subColumn); -} - -int CSMWorld::NestableColumn::nestedColumnCount() const -{ - if (!mHasChildren) - throw std::logic_error("Tried to access number of the subcolumns in the non-nest column"); - - return mNestedColumns.size(); -} - -CSMWorld::NestableColumn::NestableColumn(int columnId, CSMWorld::ColumnBase::Display displayType, - int flag, const CSMWorld::NestableColumn* parent) - : mParent(parent), mHasChildren(false), CSMWorld::ColumnBase(columnId, displayType, flag) -{ -} - -CSMWorld::NestableColumn::~NestableColumn() -{ - for (unsigned int i = 0; i < mNestedColumns.size(); ++i) - { - delete mNestedColumns[i]; - } -} - -bool CSMWorld::NestableColumn::hasChildren() const -{ - return mHasChildren; -} diff --git a/apps/opencs/model/world/nestablecolumn.hpp b/apps/opencs/model/world/nestablecolumn.hpp deleted file mode 100644 index 28ced85e99..0000000000 --- a/apps/opencs/model/world/nestablecolumn.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef CSM_WOLRD_NESTABLECOLUMN_H -#define CSM_WOLRD_NESTABLECOLUMN_H - -#include - -#include "columnbase.hpp" - -namespace CSMWorld -{ - class NestableColumn : public ColumnBase - { - std::vector mNestedColumns; - const NestableColumn* mParent; - bool mHasChildren; // cached - - public: - - NestableColumn(int columnId, - Display displayType, int flag, const NestableColumn* parent = 0); - - ~NestableColumn(); - - void addColumn(CSMWorld::NestableColumn *column); - - const ColumnBase& nestedColumn(int subColumn) const; - - int nestedColumnCount() const; - - bool hasChildren() const; - }; -} - -#endif diff --git a/apps/opencs/model/world/nestedcollection.cpp b/apps/opencs/model/world/nestedcollection.cpp index f557c3ba1d..937ad6ad60 100644 --- a/apps/opencs/model/world/nestedcollection.cpp +++ b/apps/opencs/model/world/nestedcollection.cpp @@ -1,7 +1,17 @@ #include "nestedcollection.hpp" -CSMWorld::NestedCollection::NestedCollection() : mParent(0) +CSMWorld::NestedCollection::NestedCollection() {} CSMWorld::NestedCollection::~NestedCollection() {} + +int CSMWorld::NestedCollection::getNestedRowsCount(int row, int column) const +{ + return 0; +} + +int CSMWorld::NestedCollection::getNestedColumnsCount(int row, int column) const +{ + return 0; +} diff --git a/apps/opencs/model/world/nestedcollection.hpp b/apps/opencs/model/world/nestedcollection.hpp index 5ec50b4238..8046f9a09b 100644 --- a/apps/opencs/model/world/nestedcollection.hpp +++ b/apps/opencs/model/world/nestedcollection.hpp @@ -1,17 +1,14 @@ #ifndef CSM_WOLRD_NESTEDCOLLECTION_H #define CSM_WOLRD_NESTEDCOLLECTION_H -#include - -#include "collectionbase.hpp" - class QVariant; namespace CSMWorld { + class NestableColumn; class NestedTableWrapperBase; - class NestedCollection : public CollectionBase + class NestedCollection { public: @@ -21,25 +18,22 @@ namespace CSMWorld virtual void addNestedRow(int row, int col, int position) = 0; + virtual void removeNestedRows(int row, int column, int subRow) = 0; + virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const = 0; + virtual void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn) = 0; + virtual NestedTableWrapperBase* nestedTable(int row, int column) const = 0; virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable) = 0; - virtual void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn) = 0; + virtual int getNestedRowsCount(int row, int column) const; - virtual int getNestedRowsCount(int row, int column) const = 0; + virtual int getNestedColumnsCount(int row, int column) const; - virtual int getNestedColumnsCount(int row, int column) const = 0; - - virtual void removeNestedRows(int row, int column, int subRow) = 0; - - private: - - std::vector mChildren; - NestedCollection *mParent; // currently unused + virtual NestableColumn *getNestableColumn(int column) = 0; }; } -#endif +#endif // CSM_WOLRD_NESTEDCOLLECTION_H diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index ca5efcdd92..41ca7e4409 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -8,7 +8,7 @@ #include "refidadapter.hpp" #include "refidadapterimp.hpp" #include "columns.hpp" -#include "nestedtablewrapper.hpp" // FIXME: is this really necessary? +#include "nestedtablewrapper.hpp" CSMWorld::RefIdColumn::RefIdColumn (int columnId, Display displayType, int flag, bool editable, bool userEditable) @@ -25,7 +25,6 @@ bool CSMWorld::RefIdColumn::isUserEditable() const return mUserEditable; } - // FIXME: const problem /*const*/ CSMWorld::RefIdAdapter& CSMWorld::RefIdCollection::findAdapter (UniversalId::Type type) const { @@ -667,6 +666,11 @@ int CSMWorld::RefIdCollection::getNestedColumnsCount(int row, int column) const return adaptor.getNestedColumnsCount(&mColumns.at(column), mData); } +CSMWorld::NestableColumn *CSMWorld::RefIdCollection::getNestableColumn(int column) +{ + return &mColumns.at(column); +} + void CSMWorld::RefIdCollection::addNestedRow(int row, int col, int position) { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index dd432c5a96..2a271a8463 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -5,7 +5,8 @@ #include #include -#include "nestablecolumn.hpp" +#include "columnbase.hpp" +#include "collectionbase.hpp" #include "nestedcollection.hpp" #include "refiddata.hpp" @@ -17,7 +18,7 @@ namespace ESM namespace CSMWorld { class RefIdAdapter; - class NestedTableWrapperBase; // FIXME: is this really needed? + class NestedTableWrapperBase; class RefIdColumn : public NestableColumn { @@ -35,7 +36,7 @@ namespace CSMWorld virtual bool isUserEditable() const; }; - class RefIdCollection : public NestedCollection + class RefIdCollection : public CollectionBase, public NestedCollection { private: @@ -117,12 +118,12 @@ namespace CSMWorld virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable); - // FIXME virtual int getNestedRowsCount(int row, int column) const; - // FIXME virtual int getNestedColumnsCount(int row, int column) const; + NestableColumn *getNestableColumn(int column); + virtual void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn); virtual void removeNestedRows(int row, int column, int subRow); From 05210d7f2133387cdd8b581c1ea30dba3b15449a Mon Sep 17 00:00:00 2001 From: cc9cii Date: Thu, 9 Apr 2015 19:29:03 +1000 Subject: [PATCH 101/185] Nested table support for Pathgrids. --- apps/opencs/model/world/collection.hpp | 8 + apps/opencs/model/world/columnbase.cpp | 1 - apps/opencs/model/world/columnbase.hpp | 2 + apps/opencs/model/world/columnimp.hpp | 99 ++++++++- apps/opencs/model/world/columns.cpp | 8 + apps/opencs/model/world/columns.hpp | 9 + apps/opencs/model/world/data.cpp | 19 +- apps/opencs/model/world/idadapter.hpp | 39 ++++ apps/opencs/model/world/idadapterimp.hpp | 202 ++++++++++++++++++ apps/opencs/model/world/subcellcollection.hpp | 122 ++++++++++- 10 files changed, 503 insertions(+), 6 deletions(-) create mode 100644 apps/opencs/model/world/idadapter.hpp create mode 100644 apps/opencs/model/world/idadapterimp.hpp diff --git a/apps/opencs/model/world/collection.hpp b/apps/opencs/model/world/collection.hpp index dc52ae663b..4bc9632a8d 100644 --- a/apps/opencs/model/world/collection.hpp +++ b/apps/opencs/model/world/collection.hpp @@ -120,6 +120,8 @@ namespace CSMWorld virtual const Record& getRecord (int index) const; + virtual Record& getRecord (int index); + virtual int getAppendIndex (const std::string& id, UniversalId::Type type = UniversalId::Type_None) const; ///< \param type Will be ignored, unless the collection supports multiple record types @@ -433,6 +435,12 @@ namespace CSMWorld return mRecords.at (index); } + template + Record& Collection::getRecord (int index) + { + return mRecords.at (index); + } + template void Collection::insertRecord (const RecordBase& record, int index, UniversalId::Type type) diff --git a/apps/opencs/model/world/columnbase.cpp b/apps/opencs/model/world/columnbase.cpp index 94c5afb83a..e4d2195bea 100644 --- a/apps/opencs/model/world/columnbase.cpp +++ b/apps/opencs/model/world/columnbase.cpp @@ -1,4 +1,3 @@ - #include "columnbase.hpp" #include "columns.hpp" diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index da1d8f0df5..aef68fdbd1 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -97,6 +97,8 @@ namespace CSMWorld Display_NestedItemList, Display_NestedSpellList, Display_NestedDestinationsList, + Display_PathgridPointList, + Display_PathgridEdgeList, Display_EnchantmentType, Display_BodyPartType, diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index da14bb4955..27fc3ad047 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -1277,7 +1277,6 @@ namespace CSMWorld } }; - template struct PosColumn : public Column { @@ -2265,6 +2264,104 @@ namespace CSMWorld return true; } }; + + template + struct PathgridPointListColumn : public Column + { + PathgridPointListColumn () + : Column (Columns::ColumnId_PathgridPoints, + ColumnBase::Display_PathgridPointList, ColumnBase::Flag_Dialogue) + { + } + + virtual QVariant get (const Record& record) const + { + return true; // required by IdTree::hasChildren() + } + + virtual void set (Record& record, const QVariant& data) + { + } + + virtual bool isEditable() const + { + return true; + } + }; + + template + struct PathgridPointColumn : public Column + { + int mIndex; // 0=PosX, 1=PosY, 2=PosZ + + PathgridPointColumn(int index) + : Column (Columns::ColumnId_PathgridPosX+index, ColumnBase::Display_Integer), mIndex(index) + {} + + virtual QVariant get (const Record& record) const + { + return QVariant(); // FIXME + } + + virtual void set (Record& record, const QVariant& data) + { + } + + virtual bool isEditable() const + { + return true; + } + }; + + template + struct PathgridEdgeListColumn : public Column + { + PathgridEdgeListColumn () + : Column (Columns::ColumnId_PathgridEdges, + ColumnBase::Display_PathgridEdgeList, ColumnBase::Flag_Dialogue) + { + } + + virtual QVariant get (const Record& record) const + { + return true; // required by IdTree::hasChildren() + } + + virtual void set (Record& record, const QVariant& data) + { + } + + virtual bool isEditable() const + { + return true; + } + + }; + + template + struct PathgridEdgeColumn : public Column + { + int mIndex; + + PathgridEdgeColumn (int index) + : Column (Columns::ColumnId_PathgridEdge0+index, ColumnBase::Display_Integer), mIndex(index) + { + } + + virtual QVariant get (const Record& record) const + { + return QVariant(); // FIXME + } + + virtual void set (Record& record, const QVariant& data) + { + } + + virtual bool isEditable() const + { + return true; + } + }; } #endif diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 1d3bc7641e..db0ebfd866 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -223,6 +223,14 @@ namespace CSMWorld { ColumnId_AreaSound, "Area Sound" }, { ColumnId_BoltSound, "Bolt Sound" }, + { ColumnId_PathgridPoints, "Points"}, + { ColumnId_PathgridPosX, "X"}, + { ColumnId_PathgridPosY, "Y"}, + { ColumnId_PathgridPosZ, "Z"}, + { ColumnId_PathgridEdges, "Edges"}, + { ColumnId_PathgridEdge0, "Edge 0"}, + { ColumnId_PathgridEdge1, "Edge 1"}, + { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, { ColumnId_UseValue3, "Use value 3" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 1c0af217bc..e36e29b3b6 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -211,6 +211,15 @@ namespace CSMWorld ColumnId_HitSound = 196, ColumnId_AreaSound = 197, ColumnId_BoltSound = 198, + + ColumnId_PathgridPoints = 199, + ColumnId_PathgridPosX = 200, + ColumnId_PathgridPosY = 201, + ColumnId_PathgridPosZ = 202, + ColumnId_PathgridEdges = 203, + ColumnId_PathgridEdge0 = 204, + ColumnId_PathgridEdge1 = 205, + // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. ColumnId_UseValue1 = 0x10000, diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 0cfc890ea6..ea94fe9056 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -18,6 +18,7 @@ #include "columns.hpp" #include "resourcesmanager.hpp" #include "resourcetable.hpp" +#include "idadapterimp.hpp" void CSMWorld::Data::addModel (QAbstractItemModel *model, UniversalId::Type type, bool update) { @@ -255,6 +256,22 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mPathgrids.addColumn (new RecordStateColumn); mPathgrids.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Pathgrid)); + // new object deleted in dtor of Collection + PathgridPointListColumn *pointList = new PathgridPointListColumn (); + mPathgrids.addColumn (pointList); + // new object deleted in dtor of SubCellCollection + mPathgrids.addAdapter (std::make_pair(pointList, new PathgridPointListAdapter ())); + // new objects deleted in dtor of NestableColumn + mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridPointColumn (0)); + mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridPointColumn (1)); + mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridPointColumn (2)); + + PathgridEdgeListColumn *edgeList = new PathgridEdgeListColumn (); + mPathgrids.addColumn (edgeList); + mPathgrids.addAdapter (std::make_pair(edgeList, new PathgridEdgeListAdapter ())); + mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridEdgeColumn (0)); + mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridEdgeColumn (1)); + mStartScripts.addColumn (new StringIdColumn); mStartScripts.addColumn (new RecordStateColumn); mStartScripts.addColumn (new FixedRecordTypeColumn (UniversalId::Type_StartScript)); @@ -331,7 +348,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc addModel (new IdTable (&mBodyParts), UniversalId::Type_BodyPart); addModel (new IdTable (&mSoundGens), UniversalId::Type_SoundGen); addModel (new IdTable (&mMagicEffects), UniversalId::Type_MagicEffect); - addModel (new IdTable (&mPathgrids), UniversalId::Type_Pathgrid); + addModel (new IdTree (&mPathgrids, &mPathgrids), UniversalId::Type_Pathgrid); addModel (new IdTable (&mStartScripts), UniversalId::Type_StartScript); addModel (new IdTree (&mReferenceables, &mReferenceables, IdTable::Feature_Preview), UniversalId::Type_Referenceable); diff --git a/apps/opencs/model/world/idadapter.hpp b/apps/opencs/model/world/idadapter.hpp new file mode 100644 index 0000000000..bec21a0f34 --- /dev/null +++ b/apps/opencs/model/world/idadapter.hpp @@ -0,0 +1,39 @@ +#ifndef CSM_WOLRD_IDADAPTER_H +#define CSM_WOLRD_IDADAPTER_H + +#include "record.hpp" + +class QVariant; + +namespace CSMWorld +{ + class NestedTableWrapperBase; + + template + class NestedIdAdapter + { + public: + + NestedIdAdapter() {} + + virtual ~NestedIdAdapter() {} + + virtual void addNestedRow(Record& record, int position) const = 0; + + virtual void removeNestedRow(Record& record, int rowToRemove) const = 0; + + virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) = 0; + + virtual NestedTableWrapperBase* nestedTable(const Record& record) const = 0; + + virtual QVariant getNestedData(const Record& record, int subRowIndex, int subColIndex) const = 0; + + virtual void setNestedData(Record& record, const QVariant& value, int subRowIndex, int subColIndex) const = 0; + + virtual int getNestedColumnsCount(const Record& record) const = 0; + + virtual int getNestedRowsCount(const Record& record) const = 0; + }; +} + +#endif // CSM_WOLRD_IDADAPTER_H diff --git a/apps/opencs/model/world/idadapterimp.hpp b/apps/opencs/model/world/idadapterimp.hpp new file mode 100644 index 0000000000..fa7c55bd36 --- /dev/null +++ b/apps/opencs/model/world/idadapterimp.hpp @@ -0,0 +1,202 @@ +#ifndef CSM_WOLRD_IDADAPTERIMP_H +#define CSM_WOLRD_IDADAPTERIMP_H + +#include + +#include + +#include "idadapter.hpp" + +namespace CSMWorld +{ + class NestedTableWrapperBase; + + template + class PathgridPointListAdapter : public NestedIdAdapter + { + public: + PathgridPointListAdapter () {} + + virtual void addNestedRow(Record& record, int position) const + { + ESXRecordT pathgrid = record.get(); + + ESXRecordT::PointList& points = pathgrid.mPoints; + + // blank row + ESM::Pathgrid::Point point; + point.mX = 0; + point.mY = 0; + point.mZ = 0; + point.mAutogenerated = 0; + point.mConnectionNum = 0; + point.mUnknown = 0; + + // FIXME: inserting a point should trigger re-indexing of the edges + points.insert(points.begin()+position, point); + pathgrid.mData.mS2 += 1; // increment the number of points + + record.setModified (pathgrid); + } + + virtual void removeNestedRow(Record& record, int rowToRemove) const + { + ESXRecordT pathgrid = record.get(); + + ESXRecordT::PointList& points = pathgrid.mPoints; + + if (rowToRemove < 0 || rowToRemove >= static_cast (points.size())) + throw std::runtime_error ("index out of range"); + + // FIXME: deleting a point should trigger re-indexing of the edges + points.erase(points.begin()+rowToRemove); + pathgrid.mData.mS2 -= 1; // decrement the number of points + + record.setModified (pathgrid); + } + + virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) + { + record.get().mPoints = + static_cast &>(nestedTable).mNestedTable; + } + + virtual NestedTableWrapperBase* nestedTable(const Record& record) const + { + // deleted by dtor of NestedTableStoring + return new NestedTableWrapper(record.get().mPoints); + } + + virtual QVariant getNestedData(const Record& record, int subRowIndex, int subColIndex) const + { + ESM::Pathgrid::Point point = record.get().mPoints[subRowIndex]; + switch (subColIndex) + { + case 0: return point.mX; + case 1: return point.mY; + case 2: return point.mZ; + default: throw std::logic_error("Pathgrid point subcolumn index out of range"); + } + } + + virtual void setNestedData(Record& record, const QVariant& value, + int subRowIndex, int subColIndex) const + { + ESXRecordT pathgrid = record.get(); + ESM::Pathgrid::Point point = pathgrid.mPoints[subRowIndex]; + switch (subColIndex) + { + case 0: point.mX = value.toInt(); break; + case 1: point.mY = value.toInt(); break; + case 2: point.mZ = value.toInt(); break; + default: throw std::logic_error("Pathgrid point subcolumn index out of range"); + } + + pathgrid.mPoints[subRowIndex] = point; + + record.setModified (pathgrid); + } + + virtual int getNestedColumnsCount(const Record& record) const + { + return 3; + } + + virtual int getNestedRowsCount(const Record& record) const + { + return static_cast(record.get().mPoints.size()); + } + }; + + template + class PathgridEdgeListAdapter : public NestedIdAdapter + { + public: + PathgridEdgeListAdapter () {} + + // FIXME: seems to be auto-sorted in the dialog table display after insertion + virtual void addNestedRow(Record& record, int position) const + { + ESXRecordT pathgrid = record.get(); + + ESXRecordT::EdgeList& edges = pathgrid.mEdges; + + // blank row + ESM::Pathgrid::Edge edge; + edge.mV0 = 0; + edge.mV1 = 0; + + // FIXME: inserting a blank edge does not really make sense, perhaps this should be a + // logic_error exception + edges.insert(edges.begin()+position, edge); + + record.setModified (pathgrid); + } + + virtual void removeNestedRow(Record& record, int rowToRemove) const + { + ESXRecordT pathgrid = record.get(); + + ESXRecordT::EdgeList& edges = pathgrid.mEdges; + + if (rowToRemove < 0 || rowToRemove >= static_cast (edges.size())) + throw std::runtime_error ("index out of range"); + + edges.erase(edges.begin()+rowToRemove); + + record.setModified (pathgrid); + } + + virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) + { + record.get().mEdges = + static_cast &>(nestedTable).mNestedTable; + } + + virtual NestedTableWrapperBase* nestedTable(const Record& record) const + { + // deleted by dtor of NestedTableStoring + return new NestedTableWrapper(record.get().mEdges); + } + + virtual QVariant getNestedData(const Record& record, int subRowIndex, int subColIndex) const + { + ESM::Pathgrid::Edge edge = record.get().mEdges[subRowIndex]; + switch (subColIndex) + { + case 0: return edge.mV0; + case 1: return edge.mV1; + default: throw std::logic_error("Pathgrid edge subcolumn index out of range"); + } + } + + virtual void setNestedData(Record& record, const QVariant& value, + int subRowIndex, int subColIndex) const + { + ESXRecordT pathgrid = record.get(); + ESM::Pathgrid::Edge edge = pathgrid.mEdges[subRowIndex]; + switch (subColIndex) + { + case 0: edge.mV0 = value.toInt(); break; + case 1: edge.mV1 = value.toInt(); break; + default: throw std::logic_error("Pathgrid edge subcolumn index out of range"); + } + + pathgrid.mEdges[subRowIndex] = edge; + + record.setModified (pathgrid); + } + + virtual int getNestedColumnsCount(const Record& record) const + { + return 2; + } + + virtual int getNestedRowsCount(const Record& record) const + { + return static_cast(record.get().mEdges.size()); + } + }; +} + +#endif // CSM_WOLRD_IDADAPTERIMP_H diff --git a/apps/opencs/model/world/subcellcollection.hpp b/apps/opencs/model/world/subcellcollection.hpp index 74bb6c9551..f2aeb5aaf2 100644 --- a/apps/opencs/model/world/subcellcollection.hpp +++ b/apps/opencs/model/world/subcellcollection.hpp @@ -1,6 +1,17 @@ #ifndef CSM_WOLRD_SUBCOLLECTION_H #define CSM_WOLRD_SUBCOLLECTION_H +#include +#include + +#include + +#include "columnimp.hpp" +#include "idcollection.hpp" +#include "nestedcollection.hpp" +#include "nestedtablewrapper.hpp" +#include "idadapterimp.hpp" + namespace ESM { class ESMReader; @@ -14,17 +25,40 @@ namespace CSMWorld /// \brief Single type collection of top level records that are associated with cells template > - class SubCellCollection : public IdCollection + class SubCellCollection : public IdCollection, public NestedCollection { const IdCollection& mCells; + std::map* > mAdapters; virtual void loadRecord (ESXRecordT& record, ESM::ESMReader& reader); + NestedIdAdapter* getAdapter(const ColumnBase &column) const; + public: SubCellCollection (const IdCollection& cells); + ~SubCellCollection(); + virtual void addNestedRow(int row, int column, int position); + virtual void removeNestedRows(int row, int column, int subRow); + + virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const; + + virtual void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn); + + virtual NestedTableWrapperBase* nestedTable(int row, int column) const; + + virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable); + + virtual int getNestedRowsCount(int row, int column) const; + + virtual int getNestedColumnsCount(int row, int column) const; + + // this method is inherited from NestedCollection, not from Collection + virtual NestableColumn *getNestableColumn(int column); + + void addAdapter(std::pair* > adapter); }; template @@ -35,11 +69,93 @@ namespace CSMWorld } template - SubCellCollection::SubCellCollection ( - const IdCollection& cells) + SubCellCollection::SubCellCollection (const IdCollection& cells) : mCells (cells) {} + template + SubCellCollection::~SubCellCollection() + { + for (std::map* >::iterator iter (mAdapters.begin()); + iter!=mAdapters.end(); ++iter) + delete (*iter).second; + } + + template + void SubCellCollection::addAdapter(std::pair* > adapter) + { + mAdapters.insert(adapter); + } + + template + NestedIdAdapter* SubCellCollection::getAdapter(const ColumnBase &column) const + { + std::map* >::const_iterator iter = + mAdapters.find (&column); + + if (iter==mAdapters.end()) + throw std::logic_error("No such column in the nestedidadapter"); + + return iter->second; + } + + template + void SubCellCollection::addNestedRow(int row, int column, int position) + { + getAdapter(getColumn(column))->addNestedRow(getRecord(row), position); + } + + template + void SubCellCollection::removeNestedRows(int row, int column, int subRow) + { + getAdapter(getColumn(column))->removeNestedRow(getRecord(row), subRow); + } + + template + QVariant SubCellCollection::getNestedData (int row, + int column, int subRow, int subColumn) const + { + return getAdapter(getColumn(column))->getNestedData(getRecord(row), subRow, subColumn); + } + + template + void SubCellCollection::setNestedData(int row, + int column, const QVariant& data, int subRow, int subColumn) + { + getAdapter(getColumn(column))->setNestedData(getRecord(row), data, subRow, subColumn); + } + + template + CSMWorld::NestedTableWrapperBase* SubCellCollection::nestedTable(int row, + int column) const + { + return getAdapter(getColumn(column))->nestedTable(getRecord(row)); + } + + template + void SubCellCollection::setNestedTable(int row, + int column, const CSMWorld::NestedTableWrapperBase& nestedTable) + { + getAdapter(getColumn(column))->setNestedTable(getRecord(row), nestedTable); + } + + template + int SubCellCollection::getNestedRowsCount(int row, int column) const + { + return getAdapter(getColumn(column))->getNestedRowsCount(getRecord(row)); + } + + template + int SubCellCollection::getNestedColumnsCount(int row, int column) const + { + return getAdapter(getColumn(column))->getNestedColumnsCount(getRecord(row)); + } + + template + CSMWorld::NestableColumn *SubCellCollection::getNestableColumn(int column) + { + return Collection::getNestableColumn(column); + } } #endif From 860754e460523abad2a865d99b0e8ab68ada65cb Mon Sep 17 00:00:00 2001 From: cc9cii Date: Thu, 9 Apr 2015 19:33:42 +1000 Subject: [PATCH 102/185] Minor formatting cleanup and comments. --- apps/opencs/model/world/nestedadapters.hpp | 123 ------------------ .../model/world/nestedtableproxymodel.cpp | 2 +- .../model/world/nestedtableproxymodel.hpp | 6 +- apps/opencs/model/world/refidadapter.hpp | 5 +- apps/opencs/model/world/refidadapterimp.cpp | 13 +- apps/opencs/model/world/refidadapterimp.hpp | 4 +- 6 files changed, 15 insertions(+), 138 deletions(-) diff --git a/apps/opencs/model/world/nestedadapters.hpp b/apps/opencs/model/world/nestedadapters.hpp index ac2a650d47..a2cbea1a69 100644 --- a/apps/opencs/model/world/nestedadapters.hpp +++ b/apps/opencs/model/world/nestedadapters.hpp @@ -177,129 +177,6 @@ namespace CSMWorld }; - /* - template - class MagicEffectsHelper : public CastableHelper - { - public: - - MagicEffectsHelper(CSMWorld::UniversalId::Type type) - : CastableHelper(type) {} - - virtual void setNestedTable(RefIdData& data, - int index, - const NestedTableWrapperBase& nestedTable) - { - CastableHelper::getRecord(data, index).get().mEffects = - (static_cast&>(nestedTable)).mNestedTable; - } - - virtual NestedTableWrapperBase* nestedTable(const RefIdData& data, - int index) const - { - return new NestedTableWrapper(CastableHelper::getRecord(data, index).get().mEffects); - } - - virtual QVariant getNestedData(const CSMWorld::RefIdData& data, - int index, - int subRowIndex, - int subColIndex) const - { - const ESM::EffectList& content = CastableHelper::getRecord(data, index).get().mEffects; - - switch (subColIndex) - { - case 0: - return content.at(subRowIndex).mEffectID; - - case 1: - return content.at(subRowIndex).mRange; - - case 2: - return content.at(subRowIndex).mDuration; - - case 3: - return content.at(subRowIndex).mArea; - - case 4: - return content.at(subRowIndex).mMagMin; - - case 5: - return content.at(subRowIndex).mMagMax; - - case 6: - return (int)content.at(rubRowIndex).mSkill; - - case 7: - return (int)content.at(subRowIndex).mAttribute; - - default: - throw std::logic_error("Trying to access non-existing column in the nested table!"); - } - } - - virtual void removeNestedRow (RefIdData& data, int index, int rowToRemove) const - { - ESM::EffectList& list = CastableHelper::getRecord(data, index).get().mEffects; - - list.erase (list.begin () + rowToRemove); - } - - void setNestedData (RefIdData& data, - int index, - const QVariant& value, - int subRowIndex, - int subColIndex) const - { - switch(subColIndex) - { - case 0: - CastableHelper::getRecord(data, index).get().mEffects.at(subRowIndex).mEffectID = value.toInt(); - break; - - default: - throw std::logic_error("Trying to access non-existing column in the nested table!"); - } - } - - virtual void addNestedRow (RefIdData& data, int index, int position) const - { - std::vector& list = CastableHelper::getRecord(data, index).get().mTransport.mList; - - ESM::Position newPos; - for (unsigned i = 0; i < 3; ++i) - { - newPos.pos[i] = 0; - newPos.rot[i] = 0; - } - - ESM::Transport::Dest newRow; - newRow.mPos = newPos; - newRow.mCellName = ""; - - if (position >= (int)list.size()) - { - list.push_back(newRow); - return; - } - - list.insert(list.begin()+position, newRow); - } - - virtual int getNestedColumnsCount(const RefIdData& data) const - { - return 7; - } - - - virtual int getNestedRowsCount(const RefIdData& data, - int index) const - { - return CastableHelper::getRecord(data, index).get().mTransport.mList.size(); - } - - }; - */ template class DestinationsHelper : public CastableHelper { diff --git a/apps/opencs/model/world/nestedtableproxymodel.cpp b/apps/opencs/model/world/nestedtableproxymodel.cpp index fede8383bc..182ed11ab5 100644 --- a/apps/opencs/model/world/nestedtableproxymodel.cpp +++ b/apps/opencs/model/world/nestedtableproxymodel.cpp @@ -99,7 +99,7 @@ QVariant CSMWorld::NestedTableProxyModel::headerData(int section, } -bool CSMWorld::NestedTableProxyModel::setData ( const QModelIndex & index, const QVariant & value, int role) +bool CSMWorld::NestedTableProxyModel::setData (const QModelIndex & index, const QVariant & value, int role) { return mMainModel->setData(mapToSource(index), value, role); } diff --git a/apps/opencs/model/world/nestedtableproxymodel.hpp b/apps/opencs/model/world/nestedtableproxymodel.hpp index 7dc66989c7..177a25d281 100644 --- a/apps/opencs/model/world/nestedtableproxymodel.hpp +++ b/apps/opencs/model/world/nestedtableproxymodel.hpp @@ -27,7 +27,7 @@ namespace CSMWorld IdTree* mMainModel; std::string mId; - public: + public: NestedTableProxyModel(const QModelIndex& parent, ColumnBase::Display displayType, IdTree* parentModel); @@ -51,9 +51,9 @@ namespace CSMWorld virtual QModelIndex parent(const QModelIndex& index) const; - virtual QVariant headerData ( int section, Qt::Orientation orientation, int role ) const; + virtual QVariant headerData (int section, Qt::Orientation orientation, int role) const; - virtual bool setData ( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole ); + virtual bool setData (const QModelIndex & index, const QVariant & value, int role = Qt::EditRole); virtual Qt::ItemFlags flags(const QModelIndex& index) const; diff --git a/apps/opencs/model/world/refidadapter.hpp b/apps/opencs/model/world/refidadapter.hpp index af74696372..7f7d004136 100644 --- a/apps/opencs/model/world/refidadapter.hpp +++ b/apps/opencs/model/world/refidadapter.hpp @@ -9,6 +9,7 @@ /*! \brief * Adapters acts as indirection layer, abstracting details of the record types (in the wrappers) from the higher levels of model. * Please notice that nested adaptor uses helper classes for actually performing any actions. Different record types require different helpers (needs to be created in the subclass and then fetched via member function). + * * Important point: don't forget to make sure that getData on the nestedColumn returns true (otherwise code will not treat the index pointing to the column as having childs! */ @@ -44,7 +45,7 @@ namespace CSMWorld virtual std::string getId (const RecordBase& record) const = 0; - virtual void setId(RecordBase& record, const std::string& id) = 0; + virtual void setId(RecordBase& record, const std::string& id) = 0; // FIXME: used by RefIdCollection::cloneRecord() }; class NestedRefIdAdapterBase @@ -75,7 +76,7 @@ namespace CSMWorld class NestedRefIdAdapter : public NestedRefIdAdapterBase { - std::vector > mAssociatedColumns; //basicly, i wanted map, but with pointer key + std::vector > mAssociatedColumns; //basically, i wanted a map, but with pointer key public: NestedRefIdAdapter(); diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 99117cc7f2..b2a08e71c8 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -186,11 +186,11 @@ CSMWorld::ContainerRefIdAdapter::ContainerRefIdAdapter (const NameColumns& colum std::vector > assoCol; assoCol.push_back(std::make_pair(content, new InventoryHelper(UniversalId::Type_Container))); - + setAssocColumns(assoCol); } -QVariant CSMWorld::ContainerRefIdAdapter::getData (const RefIdColumn *column, +QVariant CSMWorld::ContainerRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, int index) const { @@ -207,12 +207,11 @@ QVariant CSMWorld::ContainerRefIdAdapter::getData (const RefIdColumn *column, return (record.get().mFlags & ESM::Container::Respawn)!=0; if (column==mContent) - return true; + return true; // required by IdTree::hasChildren() return NameRefIdAdapter::getData (column, data, index); } - void CSMWorld::ContainerRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, const QVariant& value) const { @@ -490,16 +489,16 @@ QVariant CSMWorld::NpcRefIdAdapter::getData (const RefIdColumn *column, const Re if (column==mColumns.mHead) return QString::fromUtf8 (record.get().mHead.c_str()); - + if (column==mColumns.mDestinations) - return true; + return true; // required by IdTree::hasChildren() std::map::const_iterator iter = mColumns.mFlags.find (column); if (iter!=mColumns.mFlags.end()) return (record.get().mFlags & iter->second)!=0; - + return ActorRefIdAdapter::getData (column, data, index); } diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index acc6c40c1c..f72c0d196e 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -536,10 +536,10 @@ namespace CSMWorld return record.get().mAiData.mAlarm; if (column==mActors.mInventory) - return true; + return true; // required by IdTree::hasChildren() if (column==mActors.mSpells) - return true; + return true; // required by IdTree::hasChildren() std::map::const_iterator iter = mActors.mServices.find (column); From 787cef1386d52abe04b28fafa35882de67054027 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Thu, 9 Apr 2015 19:39:09 +1000 Subject: [PATCH 103/185] DialogueSubView layout update for dialogues with nested tables only. --- apps/opencs/view/world/dialoguesubview.cpp | 36 ++++++++++++++++------ 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index d0b53a2061..79eb48534a 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -293,7 +293,6 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase:: connect(proxy, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)), this, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*))); - //skip = true; } else if (qobject_cast(editor)) { @@ -382,18 +381,27 @@ void CSVWorld::EditWidget::remake(int row) mWidgetMapper->setModel(mTable); mWidgetMapper->setItemDelegate(&mDispatcher); + QFrame* line = new QFrame(mMainWidget); + line->setObjectName(QString::fromUtf8("line")); + line->setGeometry(QRect(320, 150, 118, 3)); + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Sunken); QVBoxLayout *mainLayout = new QVBoxLayout(mMainWidget); + QGridLayout *lockedLayout = new QGridLayout(); QScrollArea *scroll = new QScrollArea(mMainWidget); QWidget *unlockedWidget = new QWidget(scroll); - QGridLayout *unlockedLayout = new QGridLayout(unlockedWidget); - QGridLayout *lockedLayout = new QGridLayout(); + QVBoxLayout *overLayout = new QVBoxLayout(unlockedWidget); + QGridLayout *unlockedLayout = new QGridLayout(); QVBoxLayout *tablesLayout = new QVBoxLayout(); - mainLayout->addLayout(lockedLayout, 0); + mainLayout->addLayout(lockedLayout, QSizePolicy::Fixed); mainLayout->addSpacing(5); // FIXME: arbitrary number - mainLayout->addWidget(scroll, 2); + mainLayout->addWidget(line, 1); + mainLayout->addWidget(scroll, QSizePolicy::Preferred); + overLayout->addLayout(unlockedLayout, QSizePolicy::Preferred); + overLayout->addStretch(1); mainLayout->addSpacing(5); // FIXME: arbitrary number - mainLayout->addLayout(tablesLayout, 0); + mainLayout->addLayout(tablesLayout, QSizePolicy::Preferred); mainLayout->addStretch(1); int unlocked = 0; @@ -457,9 +465,19 @@ void CSVWorld::EditWidget::remake(int row) mWidgetMapper->setCurrentModelIndex(mTable->index(row, 0)); - scroll->setWidget(unlockedWidget); - scroll->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Fixed); - scroll->setWidgetResizable(true); + if (unlocked != 0) + { + mainLayout->removeWidget(line); + scroll->setWidget(unlockedWidget); + scroll->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Minimum); + scroll->setWidgetResizable(true); + } + else + { + delete unlockedWidget; + delete scroll; + } + this->setWidget(mMainWidget); this->setWidgetResizable(true); } From 3a46512b7f22b52bc8e276b86c6f8102ae48c1cc Mon Sep 17 00:00:00 2001 From: cc9cii Date: Thu, 9 Apr 2015 20:15:38 +1000 Subject: [PATCH 104/185] Attempt to account for gcc differences. --- apps/opencs/model/world/data.hpp | 2 ++ apps/opencs/model/world/idadapterimp.hpp | 16 +++++++------- apps/opencs/model/world/subcellcollection.hpp | 22 +++++++++---------- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index 298a9be1fc..b9e0600024 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -42,7 +42,9 @@ #include "refcollection.hpp" #include "infocollection.hpp" #include "pathgrid.hpp" +#ifndef Q_MOC_RUN #include "subcellcollection.hpp" +#endif class QAbstractItemModel; diff --git a/apps/opencs/model/world/idadapterimp.hpp b/apps/opencs/model/world/idadapterimp.hpp index fa7c55bd36..025c2e137a 100644 --- a/apps/opencs/model/world/idadapterimp.hpp +++ b/apps/opencs/model/world/idadapterimp.hpp @@ -21,7 +21,7 @@ namespace CSMWorld { ESXRecordT pathgrid = record.get(); - ESXRecordT::PointList& points = pathgrid.mPoints; + ESM::Pathgrid::PointList& points = pathgrid.mPoints; // blank row ESM::Pathgrid::Point point; @@ -43,7 +43,7 @@ namespace CSMWorld { ESXRecordT pathgrid = record.get(); - ESXRecordT::PointList& points = pathgrid.mPoints; + ESM::Pathgrid::PointList& points = pathgrid.mPoints; if (rowToRemove < 0 || rowToRemove >= static_cast (points.size())) throw std::runtime_error ("index out of range"); @@ -58,13 +58,13 @@ namespace CSMWorld virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) { record.get().mPoints = - static_cast &>(nestedTable).mNestedTable; + static_cast &>(nestedTable).mNestedTable; } virtual NestedTableWrapperBase* nestedTable(const Record& record) const { // deleted by dtor of NestedTableStoring - return new NestedTableWrapper(record.get().mPoints); + return new NestedTableWrapper(record.get().mPoints); } virtual QVariant getNestedData(const Record& record, int subRowIndex, int subColIndex) const @@ -119,7 +119,7 @@ namespace CSMWorld { ESXRecordT pathgrid = record.get(); - ESXRecordT::EdgeList& edges = pathgrid.mEdges; + ESM::Pathgrid::EdgeList& edges = pathgrid.mEdges; // blank row ESM::Pathgrid::Edge edge; @@ -137,7 +137,7 @@ namespace CSMWorld { ESXRecordT pathgrid = record.get(); - ESXRecordT::EdgeList& edges = pathgrid.mEdges; + ESM::Pathgrid::EdgeList& edges = pathgrid.mEdges; if (rowToRemove < 0 || rowToRemove >= static_cast (edges.size())) throw std::runtime_error ("index out of range"); @@ -150,13 +150,13 @@ namespace CSMWorld virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) { record.get().mEdges = - static_cast &>(nestedTable).mNestedTable; + static_cast &>(nestedTable).mNestedTable; } virtual NestedTableWrapperBase* nestedTable(const Record& record) const { // deleted by dtor of NestedTableStoring - return new NestedTableWrapper(record.get().mEdges); + return new NestedTableWrapper(record.get().mEdges); } virtual QVariant getNestedData(const Record& record, int subRowIndex, int subColIndex) const diff --git a/apps/opencs/model/world/subcellcollection.hpp b/apps/opencs/model/world/subcellcollection.hpp index f2aeb5aaf2..919a0a6044 100644 --- a/apps/opencs/model/world/subcellcollection.hpp +++ b/apps/opencs/model/world/subcellcollection.hpp @@ -76,7 +76,7 @@ namespace CSMWorld template SubCellCollection::~SubCellCollection() { - for (std::map* >::iterator iter (mAdapters.begin()); + for (typename std::map* >::iterator iter (mAdapters.begin()); iter!=mAdapters.end(); ++iter) delete (*iter).second; } @@ -90,7 +90,7 @@ namespace CSMWorld template NestedIdAdapter* SubCellCollection::getAdapter(const ColumnBase &column) const { - std::map* >::const_iterator iter = + typename std::map* >::const_iterator iter = mAdapters.find (&column); if (iter==mAdapters.end()) @@ -102,59 +102,59 @@ namespace CSMWorld template void SubCellCollection::addNestedRow(int row, int column, int position) { - getAdapter(getColumn(column))->addNestedRow(getRecord(row), position); + getAdapter(Collection::getColumn(column))->addNestedRow(getRecord(row), position); } template void SubCellCollection::removeNestedRows(int row, int column, int subRow) { - getAdapter(getColumn(column))->removeNestedRow(getRecord(row), subRow); + getAdapter(Collection::getColumn(column))->removeNestedRow(getRecord(row), subRow); } template QVariant SubCellCollection::getNestedData (int row, int column, int subRow, int subColumn) const { - return getAdapter(getColumn(column))->getNestedData(getRecord(row), subRow, subColumn); + return getAdapter(Collection::getColumn(column))->getNestedData(getRecord(row), subRow, subColumn); } template void SubCellCollection::setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn) { - getAdapter(getColumn(column))->setNestedData(getRecord(row), data, subRow, subColumn); + getAdapter(Collection::getColumn(column))->setNestedData(getRecord(row), data, subRow, subColumn); } template CSMWorld::NestedTableWrapperBase* SubCellCollection::nestedTable(int row, int column) const { - return getAdapter(getColumn(column))->nestedTable(getRecord(row)); + return getAdapter(Collection::getColumn(column))->nestedTable(getRecord(row)); } template void SubCellCollection::setNestedTable(int row, int column, const CSMWorld::NestedTableWrapperBase& nestedTable) { - getAdapter(getColumn(column))->setNestedTable(getRecord(row), nestedTable); + getAdapter(Collection::getColumn(column))->setNestedTable(getRecord(row), nestedTable); } template int SubCellCollection::getNestedRowsCount(int row, int column) const { - return getAdapter(getColumn(column))->getNestedRowsCount(getRecord(row)); + return getAdapter(Collection::getColumn(column))->getNestedRowsCount(getRecord(row)); } template int SubCellCollection::getNestedColumnsCount(int row, int column) const { - return getAdapter(getColumn(column))->getNestedColumnsCount(getRecord(row)); + return getAdapter(Collection::getColumn(column))->getNestedColumnsCount(getRecord(row)); } template CSMWorld::NestableColumn *SubCellCollection::getNestableColumn(int column) { - return Collection::getNestableColumn(column); + return Collection::getNestableColumn(column); } } From 23db79ebab328298a8a39783299c3ca7e01a0dc7 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Thu, 9 Apr 2015 20:53:41 +1000 Subject: [PATCH 105/185] Fix for more gcc differences. --- apps/opencs/model/world/commands.hpp | 2 +- apps/opencs/model/world/idadapter.hpp | 2 +- apps/opencs/model/world/idtree.hpp | 2 +- apps/opencs/model/world/nestedcollection.hpp | 2 +- apps/opencs/model/world/refidadapter.hpp | 2 +- apps/opencs/model/world/refidadapterimp.hpp | 2 +- apps/opencs/model/world/refidcollection.hpp | 2 +- apps/opencs/model/world/subcellcollection.hpp | 24 ++++++++++++------- 8 files changed, 23 insertions(+), 15 deletions(-) diff --git a/apps/opencs/model/world/commands.hpp b/apps/opencs/model/world/commands.hpp index 42405a2f9d..a70b361783 100644 --- a/apps/opencs/model/world/commands.hpp +++ b/apps/opencs/model/world/commands.hpp @@ -22,7 +22,7 @@ namespace CSMWorld class IdTable; class IdTree; struct RecordBase; - class NestedTableWrapperBase; + struct NestedTableWrapperBase; class ModifyCommand : public QUndoCommand { diff --git a/apps/opencs/model/world/idadapter.hpp b/apps/opencs/model/world/idadapter.hpp index bec21a0f34..753ac01f0d 100644 --- a/apps/opencs/model/world/idadapter.hpp +++ b/apps/opencs/model/world/idadapter.hpp @@ -7,7 +7,7 @@ class QVariant; namespace CSMWorld { - class NestedTableWrapperBase; + struct NestedTableWrapperBase; template class NestedIdAdapter diff --git a/apps/opencs/model/world/idtree.hpp b/apps/opencs/model/world/idtree.hpp index 80b44d241f..d06d86a4f1 100644 --- a/apps/opencs/model/world/idtree.hpp +++ b/apps/opencs/model/world/idtree.hpp @@ -20,7 +20,7 @@ namespace CSMWorld { class NestedCollection; struct RecordBase; - class NestedTableWrapperBase; // FIXME: is this necessary? + struct NestedTableWrapperBase; class IdTree : public IdTable { diff --git a/apps/opencs/model/world/nestedcollection.hpp b/apps/opencs/model/world/nestedcollection.hpp index 8046f9a09b..b075f53c41 100644 --- a/apps/opencs/model/world/nestedcollection.hpp +++ b/apps/opencs/model/world/nestedcollection.hpp @@ -6,7 +6,7 @@ class QVariant; namespace CSMWorld { class NestableColumn; - class NestedTableWrapperBase; + struct NestedTableWrapperBase; class NestedCollection { diff --git a/apps/opencs/model/world/refidadapter.hpp b/apps/opencs/model/world/refidadapter.hpp index 7f7d004136..91f19577bd 100644 --- a/apps/opencs/model/world/refidadapter.hpp +++ b/apps/opencs/model/world/refidadapter.hpp @@ -20,7 +20,7 @@ namespace CSMWorld class RefIdColumn; class RefIdData; struct RecordBase; - class NestedTableWrapperBase; + struct NestedTableWrapperBase; class HelperBase; class RefIdAdapter diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index f72c0d196e..7296b6c682 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -16,7 +16,7 @@ namespace CSMWorld { - class NestedTableWrapperBase; + struct NestedTableWrapperBase; struct BaseColumns { diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index 2a271a8463..5bf7c177e8 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -18,7 +18,7 @@ namespace ESM namespace CSMWorld { class RefIdAdapter; - class NestedTableWrapperBase; + struct NestedTableWrapperBase; class RefIdColumn : public NestableColumn { diff --git a/apps/opencs/model/world/subcellcollection.hpp b/apps/opencs/model/world/subcellcollection.hpp index 919a0a6044..92091cf57e 100644 --- a/apps/opencs/model/world/subcellcollection.hpp +++ b/apps/opencs/model/world/subcellcollection.hpp @@ -102,53 +102,61 @@ namespace CSMWorld template void SubCellCollection::addNestedRow(int row, int column, int position) { - getAdapter(Collection::getColumn(column))->addNestedRow(getRecord(row), position); + getAdapter(Collection::getColumn(column))->addNestedRow( + Collection::getRecord(row), position); } template void SubCellCollection::removeNestedRows(int row, int column, int subRow) { - getAdapter(Collection::getColumn(column))->removeNestedRow(getRecord(row), subRow); + getAdapter(Collection::getColumn(column))->removeNestedRow( + Collection::getRecord(row), subRow); } template QVariant SubCellCollection::getNestedData (int row, int column, int subRow, int subColumn) const { - return getAdapter(Collection::getColumn(column))->getNestedData(getRecord(row), subRow, subColumn); + return getAdapter(Collection::getColumn(column))->getNestedData( + Collection::getRecord(row), subRow, subColumn); } template void SubCellCollection::setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn) { - getAdapter(Collection::getColumn(column))->setNestedData(getRecord(row), data, subRow, subColumn); + getAdapter(Collection::getColumn(column))->setNestedData( + Collection::getRecord(row), data, subRow, subColumn); } template CSMWorld::NestedTableWrapperBase* SubCellCollection::nestedTable(int row, int column) const { - return getAdapter(Collection::getColumn(column))->nestedTable(getRecord(row)); + return getAdapter(Collection::getColumn(column))->nestedTable( + Collection::getRecord(row)); } template void SubCellCollection::setNestedTable(int row, int column, const CSMWorld::NestedTableWrapperBase& nestedTable) { - getAdapter(Collection::getColumn(column))->setNestedTable(getRecord(row), nestedTable); + getAdapter(Collection::getColumn(column))->setNestedTable( + Collection::getRecord(row), nestedTable); } template int SubCellCollection::getNestedRowsCount(int row, int column) const { - return getAdapter(Collection::getColumn(column))->getNestedRowsCount(getRecord(row)); + return getAdapter(Collection::getColumn(column))->getNestedRowsCount( + Collection::getRecord(row)); } template int SubCellCollection::getNestedColumnsCount(int row, int column) const { - return getAdapter(Collection::getColumn(column))->getNestedColumnsCount(getRecord(row)); + return getAdapter(Collection::getColumn(column))->getNestedColumnsCount( + Collection::getRecord(row)); } template From be9f94b7663940010a4ff1bc8748aab4ac3b57a2 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Thu, 9 Apr 2015 21:23:02 +1000 Subject: [PATCH 106/185] Adjust edge indexes when adding/removing points. Fix some travis warnings. --- apps/opencs/model/world/idadapterimp.hpp | 29 +++++++++++++++++-- apps/opencs/model/world/nestedadapters.hpp | 2 +- .../model/world/nestedtableproxymodel.hpp | 2 +- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/apps/opencs/model/world/idadapterimp.hpp b/apps/opencs/model/world/idadapterimp.hpp index 025c2e137a..aed847909c 100644 --- a/apps/opencs/model/world/idadapterimp.hpp +++ b/apps/opencs/model/world/idadapterimp.hpp @@ -9,7 +9,7 @@ namespace CSMWorld { - class NestedTableWrapperBase; + struct NestedTableWrapperBase; template class PathgridPointListAdapter : public NestedIdAdapter @@ -32,7 +32,16 @@ namespace CSMWorld point.mConnectionNum = 0; point.mUnknown = 0; - // FIXME: inserting a point should trigger re-indexing of the edges + // inserting a point should trigger re-indexing of the edges + std::vector::iterator iter = pathgrid.mEdges.begin(); + for (;iter != pathgrid.mEdges.end(); ++iter) + { + if ((*iter).mV0 > position) + (*iter).mV0++; + if ((*iter).mV1 > position) + (*iter).mV1++; + } + points.insert(points.begin()+position, point); pathgrid.mData.mS2 += 1; // increment the number of points @@ -48,7 +57,21 @@ namespace CSMWorld if (rowToRemove < 0 || rowToRemove >= static_cast (points.size())) throw std::runtime_error ("index out of range"); - // FIXME: deleting a point should trigger re-indexing of the edges + // deleting a point should trigger re-indexing of the edges + // dangling edges are not allowed and hence removed + std::vector::iterator iter = pathgrid.mEdges.begin(); + for (;iter != pathgrid.mEdges.end(); ++iter) + { + if (((*iter).mV0 == rowToRemove) || ((*iter).mV1 == rowToRemove)) + pathgrid.mEdges.erase(iter); + + if ((*iter).mV0 > rowToRemove) + (*iter).mV0--; + + if ((*iter).mV1 > rowToRemove) + (*iter).mV1--; + } + points.erase(points.begin()+rowToRemove); pathgrid.mData.mS2 -= 1; // decrement the number of points diff --git a/apps/opencs/model/world/nestedadapters.hpp b/apps/opencs/model/world/nestedadapters.hpp index a2cbea1a69..0157653806 100644 --- a/apps/opencs/model/world/nestedadapters.hpp +++ b/apps/opencs/model/world/nestedadapters.hpp @@ -393,7 +393,7 @@ namespace CSMWorld { std::vector& list = CastableHelper::getRecord(data, index).get().mInventory.mList; - ESM::ContItem newRow = {0, ""}; + ESM::ContItem newRow = {0, {""}}; if (position >= (int)list.size()) { list.push_back(newRow); diff --git a/apps/opencs/model/world/nestedtableproxymodel.hpp b/apps/opencs/model/world/nestedtableproxymodel.hpp index 177a25d281..2ab04a5843 100644 --- a/apps/opencs/model/world/nestedtableproxymodel.hpp +++ b/apps/opencs/model/world/nestedtableproxymodel.hpp @@ -16,7 +16,7 @@ namespace CSMWorld { class CollectionBase; - class RecordBase; + struct RecordBase; class IdTree; class NestedTableProxyModel : public QAbstractProxyModel From 330920daa8df5e8294f5e2982de94eb8d2835f36 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Thu, 9 Apr 2015 21:41:46 +1000 Subject: [PATCH 107/185] Fix off by one error(s). --- apps/opencs/model/world/idadapterimp.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/opencs/model/world/idadapterimp.hpp b/apps/opencs/model/world/idadapterimp.hpp index aed847909c..510a14f12b 100644 --- a/apps/opencs/model/world/idadapterimp.hpp +++ b/apps/opencs/model/world/idadapterimp.hpp @@ -36,9 +36,9 @@ namespace CSMWorld std::vector::iterator iter = pathgrid.mEdges.begin(); for (;iter != pathgrid.mEdges.end(); ++iter) { - if ((*iter).mV0 > position) + if ((*iter).mV0 >= position) (*iter).mV0++; - if ((*iter).mV1 > position) + if ((*iter).mV1 >= position) (*iter).mV1++; } @@ -65,10 +65,10 @@ namespace CSMWorld if (((*iter).mV0 == rowToRemove) || ((*iter).mV1 == rowToRemove)) pathgrid.mEdges.erase(iter); - if ((*iter).mV0 > rowToRemove) + if ((*iter).mV0 >= rowToRemove) (*iter).mV0--; - if ((*iter).mV1 > rowToRemove) + if ((*iter).mV1 >= rowToRemove) (*iter).mV1--; } From bc9dad3ff2a776b084c00065da7529ac170091b0 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Fri, 10 Apr 2015 07:31:01 +1000 Subject: [PATCH 108/185] Add index columns and fix edge indexing for point deletion. --- apps/opencs/model/world/columnimp.hpp | 44 ++++++++++++++++++ apps/opencs/model/world/columns.cpp | 6 ++- apps/opencs/model/world/columns.hpp | 14 +++--- apps/opencs/model/world/data.cpp | 3 ++ apps/opencs/model/world/idadapterimp.hpp | 57 +++++++++++++++--------- 5 files changed, 96 insertions(+), 28 deletions(-) diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index 27fc3ad047..70c134e012 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -2289,6 +2289,28 @@ namespace CSMWorld } }; + template + struct PathgridIndexColumn : public Column + { + PathgridIndexColumn() + : Column (Columns::ColumnId_PathgridIndex, ColumnBase::Display_Integer) + {} + + virtual QVariant get (const Record& record) const + { + return QVariant(); // FIXME + } + + virtual void set (Record& record, const QVariant& data) + { + } + + virtual bool isEditable() const + { + return false; + } + }; + template struct PathgridPointColumn : public Column { @@ -2338,6 +2360,28 @@ namespace CSMWorld }; + template + struct PathgridEdgeIndexColumn : public Column + { + PathgridEdgeIndexColumn() + : Column (Columns::ColumnId_PathgridEdgeIndex, ColumnBase::Display_Integer) + {} + + virtual QVariant get (const Record& record) const + { + return QVariant(); // FIXME + } + + virtual void set (Record& record, const QVariant& data) + { + } + + virtual bool isEditable() const + { + return false; + } + }; + template struct PathgridEdgeColumn : public Column { diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index db0ebfd866..e6a27138f7 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -224,12 +224,14 @@ namespace CSMWorld { ColumnId_BoltSound, "Bolt Sound" }, { ColumnId_PathgridPoints, "Points"}, + { ColumnId_PathgridIndex, "Index"}, { ColumnId_PathgridPosX, "X"}, { ColumnId_PathgridPosY, "Y"}, { ColumnId_PathgridPosZ, "Z"}, { ColumnId_PathgridEdges, "Edges"}, - { ColumnId_PathgridEdge0, "Edge 0"}, - { ColumnId_PathgridEdge1, "Edge 1"}, + { ColumnId_PathgridEdgeIndex, "Index"}, + { ColumnId_PathgridEdge0, "Point 0"}, + { ColumnId_PathgridEdge1, "Point 1"}, { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index e36e29b3b6..2cb7101b01 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -213,12 +213,14 @@ namespace CSMWorld ColumnId_BoltSound = 198, ColumnId_PathgridPoints = 199, - ColumnId_PathgridPosX = 200, - ColumnId_PathgridPosY = 201, - ColumnId_PathgridPosZ = 202, - ColumnId_PathgridEdges = 203, - ColumnId_PathgridEdge0 = 204, - ColumnId_PathgridEdge1 = 205, + ColumnId_PathgridIndex = 200, + ColumnId_PathgridPosX = 201, + ColumnId_PathgridPosY = 202, + ColumnId_PathgridPosZ = 203, + ColumnId_PathgridEdges = 204, + ColumnId_PathgridEdgeIndex = 205, + ColumnId_PathgridEdge0 = 206, + ColumnId_PathgridEdge1 = 207, // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index ea94fe9056..76e34961fb 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -262,6 +262,8 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc // new object deleted in dtor of SubCellCollection mPathgrids.addAdapter (std::make_pair(pointList, new PathgridPointListAdapter ())); // new objects deleted in dtor of NestableColumn + // WARNING: The order of the columns below are assumed in PathgridPointListAdapter + mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridIndexColumn ()); mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridPointColumn (0)); mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridPointColumn (1)); mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridPointColumn (2)); @@ -269,6 +271,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc PathgridEdgeListColumn *edgeList = new PathgridEdgeListColumn (); mPathgrids.addColumn (edgeList); mPathgrids.addAdapter (std::make_pair(edgeList, new PathgridEdgeListAdapter ())); + mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridEdgeIndexColumn ()); mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridEdgeColumn (0)); mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridEdgeColumn (1)); diff --git a/apps/opencs/model/world/idadapterimp.hpp b/apps/opencs/model/world/idadapterimp.hpp index 510a14f12b..f5ed2e6e1c 100644 --- a/apps/opencs/model/world/idadapterimp.hpp +++ b/apps/opencs/model/world/idadapterimp.hpp @@ -33,6 +33,9 @@ namespace CSMWorld point.mUnknown = 0; // inserting a point should trigger re-indexing of the edges + // + // FIXME: undo does not restore edges table view + // FIXME: does not auto refresh edges table view std::vector::iterator iter = pathgrid.mEdges.begin(); for (;iter != pathgrid.mEdges.end(); ++iter) { @@ -59,19 +62,25 @@ namespace CSMWorld // deleting a point should trigger re-indexing of the edges // dangling edges are not allowed and hence removed + // + // FIXME: undo does not restore edges table view + // FIXME: does not auto refresh edges table view std::vector::iterator iter = pathgrid.mEdges.begin(); - for (;iter != pathgrid.mEdges.end(); ++iter) + for (; iter != pathgrid.mEdges.end();) { if (((*iter).mV0 == rowToRemove) || ((*iter).mV1 == rowToRemove)) - pathgrid.mEdges.erase(iter); + iter = pathgrid.mEdges.erase(iter); + else + { + if ((*iter).mV0 > rowToRemove) + (*iter).mV0--; - if ((*iter).mV0 >= rowToRemove) - (*iter).mV0--; + if ((*iter).mV1 > rowToRemove) + (*iter).mV1--; - if ((*iter).mV1 >= rowToRemove) - (*iter).mV1--; + ++iter; + } } - points.erase(points.begin()+rowToRemove); pathgrid.mData.mS2 -= 1; // decrement the number of points @@ -95,9 +104,10 @@ namespace CSMWorld ESM::Pathgrid::Point point = record.get().mPoints[subRowIndex]; switch (subColIndex) { - case 0: return point.mX; - case 1: return point.mY; - case 2: return point.mZ; + case 0: return subRowIndex; + case 1: return point.mX; + case 2: return point.mY; + case 3: return point.mZ; default: throw std::logic_error("Pathgrid point subcolumn index out of range"); } } @@ -109,9 +119,10 @@ namespace CSMWorld ESM::Pathgrid::Point point = pathgrid.mPoints[subRowIndex]; switch (subColIndex) { - case 0: point.mX = value.toInt(); break; - case 1: point.mY = value.toInt(); break; - case 2: point.mZ = value.toInt(); break; + case 0: break; + case 1: point.mX = value.toInt(); break; + case 2: point.mY = value.toInt(); break; + case 3: point.mZ = value.toInt(); break; default: throw std::logic_error("Pathgrid point subcolumn index out of range"); } @@ -122,7 +133,7 @@ namespace CSMWorld virtual int getNestedColumnsCount(const Record& record) const { - return 3; + return 4; } virtual int getNestedRowsCount(const Record& record) const @@ -149,8 +160,11 @@ namespace CSMWorld edge.mV0 = 0; edge.mV1 = 0; - // FIXME: inserting a blank edge does not really make sense, perhaps this should be a + // NOTE: inserting a blank edge does not really make sense, perhaps this should be a // logic_error exception + // + // Currently the code assumes that the end user to know what he/she is doing. + // e.g. Edges come in pairs, from points a->b and b->a edges.insert(edges.begin()+position, edge); record.setModified (pathgrid); @@ -187,12 +201,14 @@ namespace CSMWorld ESM::Pathgrid::Edge edge = record.get().mEdges[subRowIndex]; switch (subColIndex) { - case 0: return edge.mV0; - case 1: return edge.mV1; + case 0: return subRowIndex; + case 1: return edge.mV0; + case 2: return edge.mV1; default: throw std::logic_error("Pathgrid edge subcolumn index out of range"); } } + // FIXME: detect duplicates in mEdges virtual void setNestedData(Record& record, const QVariant& value, int subRowIndex, int subColIndex) const { @@ -200,8 +216,9 @@ namespace CSMWorld ESM::Pathgrid::Edge edge = pathgrid.mEdges[subRowIndex]; switch (subColIndex) { - case 0: edge.mV0 = value.toInt(); break; - case 1: edge.mV1 = value.toInt(); break; + case 0: break; + case 1: edge.mV0 = value.toInt(); break; + case 2: edge.mV1 = value.toInt(); break; default: throw std::logic_error("Pathgrid edge subcolumn index out of range"); } @@ -212,7 +229,7 @@ namespace CSMWorld virtual int getNestedColumnsCount(const Record& record) const { - return 2; + return 3; } virtual int getNestedRowsCount(const Record& record) const From 9a564f50628f5c29ce8ea4913d4082c5b92823ec Mon Sep 17 00:00:00 2001 From: cc9cii Date: Fri, 10 Apr 2015 15:28:09 +1000 Subject: [PATCH 109/185] Fix undo for pathgrid points add/remove. --- apps/opencs/model/world/idadapterimp.hpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/idadapterimp.hpp b/apps/opencs/model/world/idadapterimp.hpp index f5ed2e6e1c..7468154141 100644 --- a/apps/opencs/model/world/idadapterimp.hpp +++ b/apps/opencs/model/world/idadapterimp.hpp @@ -87,16 +87,36 @@ namespace CSMWorld record.setModified (pathgrid); } + struct PathgridPointsWrap : public NestedTableWrapperBase + { + ESM::Pathgrid mRecord; + + PathgridPointsWrap(ESM::Pathgrid pathgrid) + : mRecord(pathgrid) {} + + virtual ~PathgridPointsWrap() {} + + virtual int size() const + { + return mRecord.mPoints.size(); // used in IdTree::setNestedTable() + } + }; + virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) { record.get().mPoints = - static_cast &>(nestedTable).mNestedTable; + static_cast(nestedTable).mRecord.mPoints; + record.get().mData.mS2 = + static_cast(nestedTable).mRecord.mData.mS2; + // also update edges in case points were added/removed + record.get().mEdges = + static_cast(nestedTable).mRecord.mEdges; } virtual NestedTableWrapperBase* nestedTable(const Record& record) const { // deleted by dtor of NestedTableStoring - return new NestedTableWrapper(record.get().mPoints); + return new PathgridPointsWrap(record.get()); } virtual QVariant getNestedData(const Record& record, int subRowIndex, int subColIndex) const From 7990fab708c153545ffef6a5af3be49905b9d705 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Fri, 10 Apr 2015 18:09:33 +1000 Subject: [PATCH 110/185] Fix crash when exiting via window manager on some systems. --- apps/opencs/model/world/idtree.cpp | 3 +-- apps/opencs/model/world/idtree.hpp | 1 - apps/opencs/view/doc/view.cpp | 4 ++++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/world/idtree.cpp b/apps/opencs/model/world/idtree.cpp index 4befd1eeec..952c9e3297 100644 --- a/apps/opencs/model/world/idtree.cpp +++ b/apps/opencs/model/world/idtree.cpp @@ -54,8 +54,7 @@ QVariant CSMWorld::IdTree::data (const QModelIndex & index, int role) const QVariant CSMWorld::IdTree::nestedHeaderData(int section, int subSection, Qt::Orientation orientation, int role) const { - // FIXME: workaround only, a proper fix should stop QHideEvent calls after destruction - if (section < 0 || !idCollection() || section >= idCollection()->getColumns()) + if (section < 0 || section >= idCollection()->getColumns()) return QVariant(); const NestableColumn *parentColumn = mNestedCollection->getNestableColumn(section); diff --git a/apps/opencs/model/world/idtree.hpp b/apps/opencs/model/world/idtree.hpp index d06d86a4f1..5f005c4d3b 100644 --- a/apps/opencs/model/world/idtree.hpp +++ b/apps/opencs/model/world/idtree.hpp @@ -61,7 +61,6 @@ namespace CSMWorld virtual QModelIndex parent (const QModelIndex& index) const; - // TODO: check if below methods are really needed QVariant nestedHeaderData(int section, int subSection, Qt::Orientation orientation, int role = Qt::DisplayRole) const; NestedTableWrapperBase* nestedTable(const QModelIndex &index) const; diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index cf2940b999..f9fe613ef0 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -32,6 +32,10 @@ void CSVDoc::View::closeEvent (QCloseEvent *event) event->ignore(); else { + // delete the subviews first + for (QList::iterator iter = mSubViews.begin(); iter != mSubViews.end(); ++iter) + delete *iter; + // closeRequest() returns true if last document mViewManager.removeDocAndView(mDocument); } From 1220369da3abb6ed4f065908de6fa42df5df51e4 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 11 Apr 2015 11:26:29 +1000 Subject: [PATCH 111/185] Changes as per feedback comments. --- apps/opencs/model/world/collection.hpp | 12 +-- apps/opencs/model/world/columnbase.cpp | 7 +- apps/opencs/model/world/columnbase.hpp | 1 - apps/opencs/model/world/columnimp.hpp | 81 ++++--------------- apps/opencs/model/world/columns.cpp | 6 -- apps/opencs/model/world/commands.cpp | 8 +- apps/opencs/model/world/data.cpp | 14 ++-- apps/opencs/model/world/idadapter.hpp | 2 +- apps/opencs/model/world/idadapterimp.hpp | 4 +- apps/opencs/model/world/nestedadapters.hpp | 4 +- apps/opencs/model/world/refidadapter.cpp | 2 +- apps/opencs/model/world/refidadapter.hpp | 4 +- apps/opencs/model/world/refidcollection.cpp | 7 +- apps/opencs/model/world/refidcollection.hpp | 2 +- apps/opencs/model/world/subcellcollection.hpp | 48 +++++++---- 15 files changed, 77 insertions(+), 125 deletions(-) diff --git a/apps/opencs/model/world/collection.hpp b/apps/opencs/model/world/collection.hpp index 4bc9632a8d..b0571bbed1 100644 --- a/apps/opencs/model/world/collection.hpp +++ b/apps/opencs/model/world/collection.hpp @@ -120,8 +120,6 @@ namespace CSMWorld virtual const Record& getRecord (int index) const; - virtual Record& getRecord (int index); - virtual int getAppendIndex (const std::string& id, UniversalId::Type type = UniversalId::Type_None) const; ///< \param type Will be ignored, unless the collection supports multiple record types @@ -151,7 +149,7 @@ namespace CSMWorld void setRecord (int index, const Record& record); ///< \attention This function must not change the ID. - NestableColumn *getNestableColumn (int column); + NestableColumn *getNestableColumn (int column) const; }; template @@ -294,7 +292,7 @@ namespace CSMWorld } template - NestableColumn *Collection::getNestableColumn (int column) + NestableColumn *Collection::getNestableColumn (int column) const { if (column < 0 || column >= static_cast(mColumns.size())) throw std::runtime_error("column index out of range"); @@ -435,12 +433,6 @@ namespace CSMWorld return mRecords.at (index); } - template - Record& Collection::getRecord (int index) - { - return mRecords.at (index); - } - template void Collection::insertRecord (const RecordBase& record, int index, UniversalId::Type type) diff --git a/apps/opencs/model/world/columnbase.cpp b/apps/opencs/model/world/columnbase.cpp index e4d2195bea..8d1985ff27 100644 --- a/apps/opencs/model/world/columnbase.cpp +++ b/apps/opencs/model/world/columnbase.cpp @@ -26,12 +26,11 @@ int CSMWorld::ColumnBase::getId() const void CSMWorld::NestableColumn::addColumn(CSMWorld::NestableColumn *column) { mNestedColumns.push_back(column); - mHasChildren = true; } const CSMWorld::ColumnBase& CSMWorld::NestableColumn::nestedColumn(int subColumn) const { - if (!mHasChildren) + if (mNestedColumns.empty()) throw std::logic_error("Tried to access nested column of the non-nest column"); return *mNestedColumns.at(subColumn); @@ -39,7 +38,7 @@ const CSMWorld::ColumnBase& CSMWorld::NestableColumn::nestedColumn(int subColumn CSMWorld::NestableColumn::NestableColumn(int columnId, CSMWorld::ColumnBase::Display displayType, int flag) - : mHasChildren(false), CSMWorld::ColumnBase(columnId, displayType, flag) + : CSMWorld::ColumnBase(columnId, displayType, flag) { } @@ -53,5 +52,5 @@ CSMWorld::NestableColumn::~NestableColumn() bool CSMWorld::NestableColumn::hasChildren() const { - return mHasChildren; + return !mNestedColumns.empty(); } diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index aef68fdbd1..e6799cf563 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -137,7 +137,6 @@ namespace CSMWorld class NestableColumn : public ColumnBase { std::vector mNestedColumns; - bool mHasChildren; public: diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index 70c134e012..3fb9a4685f 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -2271,64 +2271,39 @@ namespace CSMWorld PathgridPointListColumn () : Column (Columns::ColumnId_PathgridPoints, ColumnBase::Display_PathgridPointList, ColumnBase::Flag_Dialogue) - { - } + {} virtual QVariant get (const Record& record) const { return true; // required by IdTree::hasChildren() } - virtual void set (Record& record, const QVariant& data) - { - } - virtual bool isEditable() const { return true; } }; - template - struct PathgridIndexColumn : public Column + struct PathgridIndexColumn : public NestableColumn { PathgridIndexColumn() - : Column (Columns::ColumnId_PathgridIndex, ColumnBase::Display_Integer) + : NestableColumn (Columns::ColumnId_PathgridIndex, + ColumnBase::Display_Integer, ColumnBase::Flag_Dialogue) {} - virtual QVariant get (const Record& record) const - { - return QVariant(); // FIXME - } - - virtual void set (Record& record, const QVariant& data) - { - } - virtual bool isEditable() const { return false; } }; - template - struct PathgridPointColumn : public Column + struct PathgridPointColumn : public NestableColumn { - int mIndex; // 0=PosX, 1=PosY, 2=PosZ - PathgridPointColumn(int index) - : Column (Columns::ColumnId_PathgridPosX+index, ColumnBase::Display_Integer), mIndex(index) + : NestableColumn (Columns::ColumnId_PathgridPosX+index, + ColumnBase::Display_Integer, ColumnBase::Flag_Dialogue) {} - virtual QVariant get (const Record& record) const - { - return QVariant(); // FIXME - } - - virtual void set (Record& record, const QVariant& data) - { - } - virtual bool isEditable() const { return true; @@ -2341,18 +2316,13 @@ namespace CSMWorld PathgridEdgeListColumn () : Column (Columns::ColumnId_PathgridEdges, ColumnBase::Display_PathgridEdgeList, ColumnBase::Flag_Dialogue) - { - } + {} virtual QVariant get (const Record& record) const { return true; // required by IdTree::hasChildren() } - virtual void set (Record& record, const QVariant& data) - { - } - virtual bool isEditable() const { return true; @@ -2360,46 +2330,25 @@ namespace CSMWorld }; - template - struct PathgridEdgeIndexColumn : public Column + struct PathgridEdgeIndexColumn : public NestableColumn { PathgridEdgeIndexColumn() - : Column (Columns::ColumnId_PathgridEdgeIndex, ColumnBase::Display_Integer) + : NestableColumn (Columns::ColumnId_PathgridEdgeIndex, + ColumnBase::Display_Integer, ColumnBase::Flag_Dialogue) {} - virtual QVariant get (const Record& record) const - { - return QVariant(); // FIXME - } - - virtual void set (Record& record, const QVariant& data) - { - } - virtual bool isEditable() const { return false; } }; - template - struct PathgridEdgeColumn : public Column + struct PathgridEdgeColumn : public NestableColumn { - int mIndex; - PathgridEdgeColumn (int index) - : Column (Columns::ColumnId_PathgridEdge0+index, ColumnBase::Display_Integer), mIndex(index) - { - } - - virtual QVariant get (const Record& record) const - { - return QVariant(); // FIXME - } - - virtual void set (Record& record, const QVariant& data) - { - } + : NestableColumn (Columns::ColumnId_PathgridEdge0+index, + ColumnBase::Display_Integer, ColumnBase::Flag_Dialogue) + {} virtual bool isEditable() const { diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index e6a27138f7..b65cf7f968 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -287,11 +287,6 @@ int CSMWorld::Columns::getId (const std::string& name) namespace { - static const char *sSkills[] = - { - "Long Blade" - }; - static const char *sSpecialisations[] = { "Combat", "Magic", "Stealth", 0 @@ -394,7 +389,6 @@ namespace switch (column) { case CSMWorld::Columns::ColumnId_Specialisation: return sSpecialisations; - case CSMWorld::Columns::ColumnId_Skill: return sSkills; case CSMWorld::Columns::ColumnId_Attribute: return sAttributes; case CSMWorld::Columns::ColumnId_SpellType: return sSpellTypes; case CSMWorld::Columns::ColumnId_ApparatusType: return sApparatusTypes; diff --git a/apps/opencs/model/world/commands.cpp b/apps/opencs/model/world/commands.cpp index 7acc6058ef..d12c5d228f 100644 --- a/apps/opencs/model/world/commands.cpp +++ b/apps/opencs/model/world/commands.cpp @@ -185,7 +185,9 @@ CSMWorld::DeleteNestedCommand::DeleteNestedCommand (IdTree& model, mNestedRow(nestedRow), NestedTableStoring(model, id, parentColumn) { - setText (("Delete nested row in " + mId).c_str()); + std::string title = + model.headerData(parentColumn, Qt::Horizontal, Qt::DisplayRole).toString().toUtf8().constData(); + setText (("Delete row in " + title + " sub-table of " + mId).c_str()); } void CSMWorld::DeleteNestedCommand::redo() @@ -211,7 +213,9 @@ CSMWorld::AddNestedCommand::AddNestedCommand(IdTree& model, const std::string& i QUndoCommand(parent), NestedTableStoring(model, id, parentColumn) { - setText (("Added nested row in " + mId).c_str()); + std::string title = + model.headerData(parentColumn, Qt::Horizontal, Qt::DisplayRole).toString().toUtf8().constData(); + setText (("Add row in " + title + " sub-table of " + mId).c_str()); } void CSMWorld::AddNestedCommand::redo() diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 76e34961fb..87d5116f16 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -263,17 +263,17 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mPathgrids.addAdapter (std::make_pair(pointList, new PathgridPointListAdapter ())); // new objects deleted in dtor of NestableColumn // WARNING: The order of the columns below are assumed in PathgridPointListAdapter - mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridIndexColumn ()); - mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridPointColumn (0)); - mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridPointColumn (1)); - mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridPointColumn (2)); + mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridIndexColumn ()); + mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridPointColumn (0)); + mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridPointColumn (1)); + mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridPointColumn (2)); PathgridEdgeListColumn *edgeList = new PathgridEdgeListColumn (); mPathgrids.addColumn (edgeList); mPathgrids.addAdapter (std::make_pair(edgeList, new PathgridEdgeListAdapter ())); - mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridEdgeIndexColumn ()); - mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridEdgeColumn (0)); - mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridEdgeColumn (1)); + mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridEdgeIndexColumn ()); + mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridEdgeColumn (0)); + mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridEdgeColumn (1)); mStartScripts.addColumn (new StringIdColumn); mStartScripts.addColumn (new RecordStateColumn); diff --git a/apps/opencs/model/world/idadapter.hpp b/apps/opencs/model/world/idadapter.hpp index 753ac01f0d..84ef2d1f81 100644 --- a/apps/opencs/model/world/idadapter.hpp +++ b/apps/opencs/model/world/idadapter.hpp @@ -22,7 +22,7 @@ namespace CSMWorld virtual void removeNestedRow(Record& record, int rowToRemove) const = 0; - virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) = 0; + virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) const = 0; virtual NestedTableWrapperBase* nestedTable(const Record& record) const = 0; diff --git a/apps/opencs/model/world/idadapterimp.hpp b/apps/opencs/model/world/idadapterimp.hpp index 7468154141..2ce0777ac2 100644 --- a/apps/opencs/model/world/idadapterimp.hpp +++ b/apps/opencs/model/world/idadapterimp.hpp @@ -102,7 +102,7 @@ namespace CSMWorld } }; - virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) + virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) const { record.get().mPoints = static_cast(nestedTable).mRecord.mPoints; @@ -204,7 +204,7 @@ namespace CSMWorld record.setModified (pathgrid); } - virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) + virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) const { record.get().mEdges = static_cast &>(nestedTable).mNestedTable; diff --git a/apps/opencs/model/world/nestedadapters.hpp b/apps/opencs/model/world/nestedadapters.hpp index 0157653806..97046276f0 100644 --- a/apps/opencs/model/world/nestedadapters.hpp +++ b/apps/opencs/model/world/nestedadapters.hpp @@ -145,8 +145,8 @@ namespace CSMWorld { CastableHelper::getRecord(data, index).get().mSpells.mList.at(subRowIndex) = std::string(value.toString().toUtf8()); } - - throw std::logic_error("Trying to access non-existing column in the nested table!"); + else + throw std::logic_error("Trying to access non-existing column in the nested table!"); } virtual void addNestedRow (RefIdData& data, int index, int position) const diff --git a/apps/opencs/model/world/refidadapter.cpp b/apps/opencs/model/world/refidadapter.cpp index 58b775f47f..a12a95196c 100644 --- a/apps/opencs/model/world/refidadapter.cpp +++ b/apps/opencs/model/world/refidadapter.cpp @@ -57,7 +57,7 @@ void CSMWorld::NestedRefIdAdapter::addNestedRow (const RefIdColumn *column, RefI getHelper(column)->addNestedRow(data, index, position); //This code grows more boring and boring. I would love some macros. } -void CSMWorld::NestedRefIdAdapter::setNestedTable (const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) +void CSMWorld::NestedRefIdAdapter::setNestedTable (const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const { getHelper(column)->setNestedTable(data, index, nestedTable); } diff --git a/apps/opencs/model/world/refidadapter.hpp b/apps/opencs/model/world/refidadapter.hpp index 91f19577bd..1a3f2700e3 100644 --- a/apps/opencs/model/world/refidadapter.hpp +++ b/apps/opencs/model/world/refidadapter.hpp @@ -69,7 +69,7 @@ namespace CSMWorld virtual void addNestedRow (const RefIdColumn *column, RefIdData& data, int index, int position) const = 0; - virtual void setNestedTable (const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) = 0; + virtual void setNestedTable (const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const = 0; virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, const RefIdData& data, int index) const = 0; }; @@ -97,7 +97,7 @@ namespace CSMWorld virtual void addNestedRow (const RefIdColumn *column, RefIdData& data, int index, int position) const; - virtual void setNestedTable (const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable); + virtual void setNestedTable (const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const; virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, const RefIdData& data, int index) const; diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 41ca7e4409..b85deef4e6 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -25,8 +25,7 @@ bool CSMWorld::RefIdColumn::isUserEditable() const return mUserEditable; } -// FIXME: const problem -/*const*/ CSMWorld::RefIdAdapter& CSMWorld::RefIdCollection::findAdapter (UniversalId::Type type) const +const CSMWorld::RefIdAdapter& CSMWorld::RefIdCollection::findAdapter (UniversalId::Type type) const { std::map::const_iterator iter = mAdapters.find (type); @@ -684,10 +683,8 @@ void CSMWorld::RefIdCollection::setNestedTable(int row, int column, const CSMWor { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); - // FIXME: const problem - CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdapter (localIndex.second)); + const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdapter (localIndex.second)); - // FIXME: const problem adaptor.setNestedTable(&mColumns.at(column), mData, localIndex.first, nestedTable); } diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index 5bf7c177e8..3315212c18 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -46,7 +46,7 @@ namespace CSMWorld private: - /*const*/ RefIdAdapter& findAdapter (UniversalId::Type) const; + const RefIdAdapter& findAdapter (UniversalId::Type) const; ///< Throws an exception if no adaptor for \a Type can be found. public: diff --git a/apps/opencs/model/world/subcellcollection.hpp b/apps/opencs/model/world/subcellcollection.hpp index 92091cf57e..c53c7006ad 100644 --- a/apps/opencs/model/world/subcellcollection.hpp +++ b/apps/opencs/model/world/subcellcollection.hpp @@ -32,7 +32,7 @@ namespace CSMWorld virtual void loadRecord (ESXRecordT& record, ESM::ESMReader& reader); - NestedIdAdapter* getAdapter(const ColumnBase &column) const; + const NestedIdAdapter& getAdapter(const ColumnBase &column) const; public: @@ -88,7 +88,7 @@ namespace CSMWorld } template - NestedIdAdapter* SubCellCollection::getAdapter(const ColumnBase &column) const + const NestedIdAdapter& SubCellCollection::getAdapter(const ColumnBase &column) const { typename std::map* >::const_iterator iter = mAdapters.find (&column); @@ -96,28 +96,36 @@ namespace CSMWorld if (iter==mAdapters.end()) throw std::logic_error("No such column in the nestedidadapter"); - return iter->second; + return *iter->second; } template void SubCellCollection::addNestedRow(int row, int column, int position) { - getAdapter(Collection::getColumn(column))->addNestedRow( - Collection::getRecord(row), position); + Record record; + record.assign(Collection::getRecord(row)); + + getAdapter(Collection::getColumn(column)).addNestedRow(record, position); + + Collection::setRecord(row, record); } template void SubCellCollection::removeNestedRows(int row, int column, int subRow) { - getAdapter(Collection::getColumn(column))->removeNestedRow( - Collection::getRecord(row), subRow); + Record record; + record.assign(Collection::getRecord(row)); + + getAdapter(Collection::getColumn(column)).removeNestedRow(record, subRow); + + Collection::setRecord(row, record); } template QVariant SubCellCollection::getNestedData (int row, int column, int subRow, int subColumn) const { - return getAdapter(Collection::getColumn(column))->getNestedData( + return getAdapter(Collection::getColumn(column)).getNestedData( Collection::getRecord(row), subRow, subColumn); } @@ -125,15 +133,20 @@ namespace CSMWorld void SubCellCollection::setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn) { - getAdapter(Collection::getColumn(column))->setNestedData( - Collection::getRecord(row), data, subRow, subColumn); + Record record; + record.assign(Collection::getRecord(row)); + + getAdapter(Collection::getColumn(column)).setNestedData( + record, data, subRow, subColumn); + + Collection::setRecord(row, record); } template CSMWorld::NestedTableWrapperBase* SubCellCollection::nestedTable(int row, int column) const { - return getAdapter(Collection::getColumn(column))->nestedTable( + return getAdapter(Collection::getColumn(column)).nestedTable( Collection::getRecord(row)); } @@ -141,21 +154,26 @@ namespace CSMWorld void SubCellCollection::setNestedTable(int row, int column, const CSMWorld::NestedTableWrapperBase& nestedTable) { - getAdapter(Collection::getColumn(column))->setNestedTable( - Collection::getRecord(row), nestedTable); + Record record; + record.assign(Collection::getRecord(row)); + + getAdapter(Collection::getColumn(column)).setNestedTable( + record, nestedTable); + + Collection::setRecord(row, record); } template int SubCellCollection::getNestedRowsCount(int row, int column) const { - return getAdapter(Collection::getColumn(column))->getNestedRowsCount( + return getAdapter(Collection::getColumn(column)).getNestedRowsCount( Collection::getRecord(row)); } template int SubCellCollection::getNestedColumnsCount(int row, int column) const { - return getAdapter(Collection::getColumn(column))->getNestedColumnsCount( + return getAdapter(Collection::getColumn(column)).getNestedColumnsCount( Collection::getRecord(row)); } From a632b2cfebd8e71e223f74d06dc0cee1d9ff60d9 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 11 Apr 2015 11:27:48 +1000 Subject: [PATCH 112/185] Fix editing "ID" column within nested tables in dialogue subview. --- apps/opencs/model/world/idtree.cpp | 45 ++++++++++++------- apps/opencs/model/world/idtree.hpp | 6 ++- .../model/world/nestedtableproxymodel.cpp | 6 ++- .../model/world/nestedtableproxymodel.hpp | 2 + 4 files changed, 41 insertions(+), 18 deletions(-) diff --git a/apps/opencs/model/world/idtree.cpp b/apps/opencs/model/world/idtree.cpp index 952c9e3297..49ceced2c7 100644 --- a/apps/opencs/model/world/idtree.cpp +++ b/apps/opencs/model/world/idtree.cpp @@ -38,18 +38,26 @@ QVariant CSMWorld::IdTree::data (const QModelIndex & index, int role) const if ((role!=Qt::DisplayRole && role!=Qt::EditRole) || index.row() < 0 || index.column() < 0) return QVariant(); - if (role==Qt::EditRole && !idCollection()->getColumn (index.column()).isEditable()) - return QVariant(); - if (index.internalId() != 0) { - std::pair parentAdress(unfoldIndexAdress(index.internalId())); + std::pair parentAddress(unfoldIndexAddress(index.internalId())); - return mNestedCollection->getNestedData(parentAdress.first, - parentAdress.second, index.row(), index.column()); + if (role == Qt::EditRole && + !mNestedCollection->getNestableColumn(parentAddress.second)->nestedColumn(index.column()).isEditable()) + { + return QVariant(); + } + + return mNestedCollection->getNestedData(parentAddress.first, + parentAddress.second, index.row(), index.column()); } else + { + if (role==Qt::EditRole && !idCollection()->getColumn (index.column()).isEditable()) + return QVariant(); + return idCollection()->getData (index.row(), index.column()); + } } QVariant CSMWorld::IdTree::nestedHeaderData(int section, int subSection, Qt::Orientation orientation, int role) const @@ -80,12 +88,12 @@ bool CSMWorld::IdTree::setData (const QModelIndex &index, const QVariant &value, { if (idCollection()->getColumn(parent(index).column()).isEditable() && role==Qt::EditRole) { - const std::pair& parentAdress(unfoldIndexAdress(index.internalId())); + const std::pair& parentAddress(unfoldIndexAddress(index.internalId())); - mNestedCollection->setNestedData(parentAdress.first, parentAdress.second, value, index.row(), index.column()); + mNestedCollection->setNestedData(parentAddress.first, parentAddress.second, value, index.row(), index.column()); - emit dataChanged (CSMWorld::IdTree::index (parentAdress.first, 0), - CSMWorld::IdTree::index (parentAdress.second, idCollection()->getColumns()-1)); + emit dataChanged (CSMWorld::IdTree::index (parentAddress.first, 0), + CSMWorld::IdTree::index (parentAddress.second, idCollection()->getColumns()-1)); return true; } @@ -145,7 +153,7 @@ QModelIndex CSMWorld::IdTree::index (int row, int column, const QModelIndex& par unsigned int encodedId = 0; if (parent.isValid()) { - encodedId = this->foldIndexAdress(parent); + encodedId = this->foldIndexAddress(parent); } if (row<0 || row>=idCollection()->getSize()) @@ -157,13 +165,18 @@ QModelIndex CSMWorld::IdTree::index (int row, int column, const QModelIndex& par return createIndex(row, column, encodedId); // store internal id } +QModelIndex CSMWorld::IdTree::getNestedModelIndex (const std::string& id, int column) const +{ + return CSMWorld::IdTable::index(idCollection()->getIndex (id), column); +} + QModelIndex CSMWorld::IdTree::parent (const QModelIndex& index) const { if (index.internalId() == 0) // 0 is used for indexs with invalid parent (top level data) return QModelIndex(); unsigned int id = index.internalId(); - const std::pair& adress(unfoldIndexAdress(id)); + const std::pair& adress(unfoldIndexAddress(id)); if (adress.first >= this->rowCount() || adress.second >= this->columnCount()) throw "Parent index is not present in the model"; @@ -171,14 +184,14 @@ QModelIndex CSMWorld::IdTree::parent (const QModelIndex& index) const return createIndex(adress.first, adress.second); } -unsigned int CSMWorld::IdTree::foldIndexAdress (const QModelIndex& index) const +unsigned int CSMWorld::IdTree::foldIndexAddress (const QModelIndex& index) const { unsigned int out = index.row() * this->columnCount(); out += index.column(); return ++out; } -std::pair< int, int > CSMWorld::IdTree::unfoldIndexAdress (unsigned int id) const +std::pair< int, int > CSMWorld::IdTree::unfoldIndexAddress (unsigned int id) const { if (id == 0) throw "Attempt to unfold index id of the top level data cell"; @@ -189,6 +202,8 @@ std::pair< int, int > CSMWorld::IdTree::unfoldIndexAdress (unsigned int id) cons return std::make_pair (row, column); } +// FIXME: Not sure why this check is also needed? +// // index.data().isValid() requires RefIdAdapter::getData() to return a valid QVariant for // nested columns (refidadapterimp.hpp) // @@ -198,7 +213,7 @@ bool CSMWorld::IdTree::hasChildren(const QModelIndex& index) const return (index.isValid() && index.internalId() == 0 && mNestedCollection->getNestableColumn(index.column())->hasChildren() && - index.data().isValid()); // FIXME: not sure why this check is also needed + index.data().isValid()); } void CSMWorld::IdTree::setNestedTable(const QModelIndex& index, const CSMWorld::NestedTableWrapperBase& nestedTable) diff --git a/apps/opencs/model/world/idtree.hpp b/apps/opencs/model/world/idtree.hpp index 5f005c4d3b..5337ed82b8 100644 --- a/apps/opencs/model/world/idtree.hpp +++ b/apps/opencs/model/world/idtree.hpp @@ -34,8 +34,8 @@ namespace CSMWorld IdTree (const IdTree&); IdTree& operator= (const IdTree&); - unsigned int foldIndexAdress(const QModelIndex& index) const; - std::pair unfoldIndexAdress(unsigned int id) const; + unsigned int foldIndexAddress(const QModelIndex& index) const; + std::pair unfoldIndexAddress(unsigned int id) const; public: @@ -61,6 +61,8 @@ namespace CSMWorld virtual QModelIndex parent (const QModelIndex& index) const; + QModelIndex getNestedModelIndex (const std::string& id, int column) const; + QVariant nestedHeaderData(int section, int subSection, Qt::Orientation orientation, int role = Qt::DisplayRole) const; NestedTableWrapperBase* nestedTable(const QModelIndex &index) const; diff --git a/apps/opencs/model/world/nestedtableproxymodel.cpp b/apps/opencs/model/world/nestedtableproxymodel.cpp index 182ed11ab5..7b35c88e4c 100644 --- a/apps/opencs/model/world/nestedtableproxymodel.cpp +++ b/apps/opencs/model/world/nestedtableproxymodel.cpp @@ -50,7 +50,7 @@ QModelIndex CSMWorld::NestedTableProxyModel::mapFromSource(const QModelIndex& so QModelIndex CSMWorld::NestedTableProxyModel::mapToSource(const QModelIndex& proxyIndex) const { - const QModelIndex& parent = mMainModel->getModelIndex (mId, mParentColumn); + const QModelIndex& parent = mMainModel->getNestedModelIndex (mId, mParentColumn); return mMainModel->index(proxyIndex.row(), proxyIndex.column(), parent); } @@ -98,6 +98,10 @@ QVariant CSMWorld::NestedTableProxyModel::headerData(int section, return mMainModel->nestedHeaderData(mParentColumn, section, orientation, role); } +QVariant CSMWorld::NestedTableProxyModel::data(const QModelIndex& index, int role) const +{ + return mMainModel->data(mapToSource(index), role); +} bool CSMWorld::NestedTableProxyModel::setData (const QModelIndex & index, const QVariant & value, int role) { diff --git a/apps/opencs/model/world/nestedtableproxymodel.hpp b/apps/opencs/model/world/nestedtableproxymodel.hpp index 2ab04a5843..f5cbdb10b4 100644 --- a/apps/opencs/model/world/nestedtableproxymodel.hpp +++ b/apps/opencs/model/world/nestedtableproxymodel.hpp @@ -53,6 +53,8 @@ namespace CSMWorld virtual QVariant headerData (int section, Qt::Orientation orientation, int role) const; + virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; + virtual bool setData (const QModelIndex & index, const QVariant & value, int role = Qt::EditRole); virtual Qt::ItemFlags flags(const QModelIndex& index) const; From ce7e2e06c15baaebad91a4be4472c75e24af0292 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 11 Apr 2015 13:11:20 +1000 Subject: [PATCH 113/185] Fix editor being created for a non-editable item. --- apps/opencs/model/world/idtree.cpp | 14 +++++++++++++- apps/opencs/model/world/nestedtableproxymodel.cpp | 2 +- apps/opencs/view/world/util.cpp | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/world/idtree.cpp b/apps/opencs/model/world/idtree.cpp index 49ceced2c7..eddde5a898 100644 --- a/apps/opencs/model/world/idtree.cpp +++ b/apps/opencs/model/world/idtree.cpp @@ -108,7 +108,19 @@ Qt::ItemFlags CSMWorld::IdTree::flags (const QModelIndex & index) const if (!index.isValid()) return 0; - return IdTable::flags(index); + if (index.internalId() != 0) + { + std::pair parentAddress(unfoldIndexAddress(index.internalId())); + + Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled; + + if (mNestedCollection->getNestableColumn(parentAddress.second)->nestedColumn(index.column()).isEditable()) + flags |= Qt::ItemIsEditable; + + return flags; + } + else + return IdTable::flags(index); } bool CSMWorld::IdTree::removeRows (int row, int count, const QModelIndex& parent) diff --git a/apps/opencs/model/world/nestedtableproxymodel.cpp b/apps/opencs/model/world/nestedtableproxymodel.cpp index 7b35c88e4c..0f137d78f8 100644 --- a/apps/opencs/model/world/nestedtableproxymodel.cpp +++ b/apps/opencs/model/world/nestedtableproxymodel.cpp @@ -110,7 +110,7 @@ bool CSMWorld::NestedTableProxyModel::setData (const QModelIndex & index, const Qt::ItemFlags CSMWorld::NestedTableProxyModel::flags(const QModelIndex& index) const { - return mMainModel->flags(mMainModel->index(0, mParentColumn)); + return mMainModel->flags(mapToSource(index)); } std::string CSMWorld::NestedTableProxyModel::getParentId() const diff --git a/apps/opencs/view/world/util.cpp b/apps/opencs/view/world/util.cpp index b0f8a035a1..f3b23100a6 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -120,7 +120,7 @@ void CSVWorld::CommandDelegate::setModelDataImp (QWidget *editor, QAbstractItemM QVariant new_ = hack.getData(); - if (model->data (index)!=new_) + if ((model->data (index)!=new_) && (model->flags(index) & Qt::ItemIsEditable)) getUndoStack().push (new CSMWorld::ModifyCommand (*model, index, new_)); } From 5da2f53bec3f6bc7910f7c12e6f46b09f358ceda Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 11 Apr 2015 13:54:05 +1000 Subject: [PATCH 114/185] Code reorganisation to prepare for nested sound table in regions. --- apps/opencs/model/world/idadapterimp.hpp | 3 +- .../opencs/model/world/nestedidcollection.hpp | 172 ++++++++++++++++++ apps/opencs/model/world/subcellcollection.hpp | 151 +-------------- 3 files changed, 177 insertions(+), 149 deletions(-) create mode 100644 apps/opencs/model/world/nestedidcollection.hpp diff --git a/apps/opencs/model/world/idadapterimp.hpp b/apps/opencs/model/world/idadapterimp.hpp index 2ce0777ac2..7df653059b 100644 --- a/apps/opencs/model/world/idadapterimp.hpp +++ b/apps/opencs/model/world/idadapterimp.hpp @@ -6,11 +6,10 @@ #include #include "idadapter.hpp" +#include "nestedtablewrapper.hpp" namespace CSMWorld { - struct NestedTableWrapperBase; - template class PathgridPointListAdapter : public NestedIdAdapter { diff --git a/apps/opencs/model/world/nestedidcollection.hpp b/apps/opencs/model/world/nestedidcollection.hpp new file mode 100644 index 0000000000..c7e840955b --- /dev/null +++ b/apps/opencs/model/world/nestedidcollection.hpp @@ -0,0 +1,172 @@ +#ifndef CSM_WOLRD_NESTEDIDCOLLECTION_H +#define CSM_WOLRD_NESTEDIDCOLLECTION_H + +#include +#include + +#include "nestedcollection.hpp" +#include "idadapterimp.hpp" + +namespace ESM +{ + class ESMReader; +} + +namespace CSMWorld +{ + struct NestedTableWrapperBase; + struct Cell; + + template + class IdCollection; + + template > + class NestedIdCollection : public IdCollection, public NestedCollection + { + std::map* > mAdapters; + + const NestedIdAdapter& getAdapter(const ColumnBase &column) const; + + public: + + NestedIdCollection (); + ~NestedIdCollection(); + + virtual void addNestedRow(int row, int column, int position); + + virtual void removeNestedRows(int row, int column, int subRow); + + virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const; + + virtual void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn); + + virtual NestedTableWrapperBase* nestedTable(int row, int column) const; + + virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable); + + virtual int getNestedRowsCount(int row, int column) const; + + virtual int getNestedColumnsCount(int row, int column) const; + + // this method is inherited from NestedCollection, not from Collection + virtual NestableColumn *getNestableColumn(int column); + + void addAdapter(std::pair* > adapter); + }; + + template + NestedIdCollection::NestedIdCollection () + {} + + template + NestedIdCollection::~NestedIdCollection() + { + for (typename std::map* >::iterator iter (mAdapters.begin()); + iter!=mAdapters.end(); ++iter) + delete (*iter).second; + } + + template + void NestedIdCollection::addAdapter(std::pair* > adapter) + { + mAdapters.insert(adapter); + } + + template + const NestedIdAdapter& NestedIdCollection::getAdapter(const ColumnBase &column) const + { + typename std::map* >::const_iterator iter = + mAdapters.find (&column); + + if (iter==mAdapters.end()) + throw std::logic_error("No such column in the nestedidadapter"); + + return *iter->second; + } + + template + void NestedIdCollection::addNestedRow(int row, int column, int position) + { + Record record; + record.assign(Collection::getRecord(row)); + + getAdapter(Collection::getColumn(column)).addNestedRow(record, position); + + Collection::setRecord(row, record); + } + + template + void NestedIdCollection::removeNestedRows(int row, int column, int subRow) + { + Record record; + record.assign(Collection::getRecord(row)); + + getAdapter(Collection::getColumn(column)).removeNestedRow(record, subRow); + + Collection::setRecord(row, record); + } + + template + QVariant NestedIdCollection::getNestedData (int row, + int column, int subRow, int subColumn) const + { + return getAdapter(Collection::getColumn(column)).getNestedData( + Collection::getRecord(row), subRow, subColumn); + } + + template + void NestedIdCollection::setNestedData(int row, + int column, const QVariant& data, int subRow, int subColumn) + { + Record record; + record.assign(Collection::getRecord(row)); + + getAdapter(Collection::getColumn(column)).setNestedData( + record, data, subRow, subColumn); + + Collection::setRecord(row, record); + } + + template + CSMWorld::NestedTableWrapperBase* NestedIdCollection::nestedTable(int row, + int column) const + { + return getAdapter(Collection::getColumn(column)).nestedTable( + Collection::getRecord(row)); + } + + template + void NestedIdCollection::setNestedTable(int row, + int column, const CSMWorld::NestedTableWrapperBase& nestedTable) + { + Record record; + record.assign(Collection::getRecord(row)); + + getAdapter(Collection::getColumn(column)).setNestedTable( + record, nestedTable); + + Collection::setRecord(row, record); + } + + template + int NestedIdCollection::getNestedRowsCount(int row, int column) const + { + return getAdapter(Collection::getColumn(column)).getNestedRowsCount( + Collection::getRecord(row)); + } + + template + int NestedIdCollection::getNestedColumnsCount(int row, int column) const + { + return getAdapter(Collection::getColumn(column)).getNestedColumnsCount( + Collection::getRecord(row)); + } + + template + CSMWorld::NestableColumn *NestedIdCollection::getNestableColumn(int column) + { + return Collection::getNestableColumn(column); + } +} + +#endif // CSM_WOLRD_NESTEDIDCOLLECTION_H diff --git a/apps/opencs/model/world/subcellcollection.hpp b/apps/opencs/model/world/subcellcollection.hpp index c53c7006ad..df1f8a12ea 100644 --- a/apps/opencs/model/world/subcellcollection.hpp +++ b/apps/opencs/model/world/subcellcollection.hpp @@ -1,16 +1,7 @@ #ifndef CSM_WOLRD_SUBCOLLECTION_H #define CSM_WOLRD_SUBCOLLECTION_H -#include -#include - -#include - -#include "columnimp.hpp" -#include "idcollection.hpp" -#include "nestedcollection.hpp" -#include "nestedtablewrapper.hpp" -#include "idadapterimp.hpp" +#include "nestedidcollection.hpp" namespace ESM { @@ -25,40 +16,15 @@ namespace CSMWorld /// \brief Single type collection of top level records that are associated with cells template > - class SubCellCollection : public IdCollection, public NestedCollection + class SubCellCollection : public NestedIdCollection { const IdCollection& mCells; - std::map* > mAdapters; virtual void loadRecord (ESXRecordT& record, ESM::ESMReader& reader); - const NestedIdAdapter& getAdapter(const ColumnBase &column) const; - public: SubCellCollection (const IdCollection& cells); - ~SubCellCollection(); - - virtual void addNestedRow(int row, int column, int position); - - virtual void removeNestedRows(int row, int column, int subRow); - - virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const; - - virtual void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn); - - virtual NestedTableWrapperBase* nestedTable(int row, int column) const; - - virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable); - - virtual int getNestedRowsCount(int row, int column) const; - - virtual int getNestedColumnsCount(int row, int column) const; - - // this method is inherited from NestedCollection, not from Collection - virtual NestableColumn *getNestableColumn(int column); - - void addAdapter(std::pair* > adapter); }; template @@ -69,119 +35,10 @@ namespace CSMWorld } template - SubCellCollection::SubCellCollection (const IdCollection& cells) + SubCellCollection::SubCellCollection ( + const IdCollection& cells) : mCells (cells) {} - - template - SubCellCollection::~SubCellCollection() - { - for (typename std::map* >::iterator iter (mAdapters.begin()); - iter!=mAdapters.end(); ++iter) - delete (*iter).second; - } - - template - void SubCellCollection::addAdapter(std::pair* > adapter) - { - mAdapters.insert(adapter); - } - - template - const NestedIdAdapter& SubCellCollection::getAdapter(const ColumnBase &column) const - { - typename std::map* >::const_iterator iter = - mAdapters.find (&column); - - if (iter==mAdapters.end()) - throw std::logic_error("No such column in the nestedidadapter"); - - return *iter->second; - } - - template - void SubCellCollection::addNestedRow(int row, int column, int position) - { - Record record; - record.assign(Collection::getRecord(row)); - - getAdapter(Collection::getColumn(column)).addNestedRow(record, position); - - Collection::setRecord(row, record); - } - - template - void SubCellCollection::removeNestedRows(int row, int column, int subRow) - { - Record record; - record.assign(Collection::getRecord(row)); - - getAdapter(Collection::getColumn(column)).removeNestedRow(record, subRow); - - Collection::setRecord(row, record); - } - - template - QVariant SubCellCollection::getNestedData (int row, - int column, int subRow, int subColumn) const - { - return getAdapter(Collection::getColumn(column)).getNestedData( - Collection::getRecord(row), subRow, subColumn); - } - - template - void SubCellCollection::setNestedData(int row, - int column, const QVariant& data, int subRow, int subColumn) - { - Record record; - record.assign(Collection::getRecord(row)); - - getAdapter(Collection::getColumn(column)).setNestedData( - record, data, subRow, subColumn); - - Collection::setRecord(row, record); - } - - template - CSMWorld::NestedTableWrapperBase* SubCellCollection::nestedTable(int row, - int column) const - { - return getAdapter(Collection::getColumn(column)).nestedTable( - Collection::getRecord(row)); - } - - template - void SubCellCollection::setNestedTable(int row, - int column, const CSMWorld::NestedTableWrapperBase& nestedTable) - { - Record record; - record.assign(Collection::getRecord(row)); - - getAdapter(Collection::getColumn(column)).setNestedTable( - record, nestedTable); - - Collection::setRecord(row, record); - } - - template - int SubCellCollection::getNestedRowsCount(int row, int column) const - { - return getAdapter(Collection::getColumn(column)).getNestedRowsCount( - Collection::getRecord(row)); - } - - template - int SubCellCollection::getNestedColumnsCount(int row, int column) const - { - return getAdapter(Collection::getColumn(column)).getNestedColumnsCount( - Collection::getRecord(row)); - } - - template - CSMWorld::NestableColumn *SubCellCollection::getNestableColumn(int column) - { - return Collection::getNestableColumn(column); - } } #endif From 88bc62e05450fbd5b35a9beb76c0cccb50122e15 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 11 Apr 2015 15:55:26 +1000 Subject: [PATCH 115/185] Add Region sounds table to dialogue subview. --- apps/opencs/model/world/columnbase.hpp | 1 + apps/opencs/model/world/columnimp.hpp | 46 ++++++++++++ apps/opencs/model/world/columns.cpp | 4 + apps/opencs/model/world/columns.hpp | 4 + apps/opencs/model/world/data.cpp | 8 +- apps/opencs/model/world/data.hpp | 3 +- apps/opencs/model/world/idadapterimp.hpp | 96 +++++++++++++++++++++++- 7 files changed, 156 insertions(+), 6 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index e6799cf563..3902a009b9 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -99,6 +99,7 @@ namespace CSMWorld Display_NestedDestinationsList, Display_PathgridPointList, Display_PathgridEdgeList, + Display_RegionSoundList, Display_EnchantmentType, Display_BodyPartType, diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index 3fb9a4685f..06467a6328 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -2355,6 +2355,52 @@ namespace CSMWorld return true; } }; + + template + struct RegionSoundListColumn : public Column + { + RegionSoundListColumn () + : Column (Columns::ColumnId_RegionSounds, + ColumnBase::Display_RegionSoundList, ColumnBase::Flag_Dialogue) + {} + + virtual QVariant get (const Record& record) const + { + return true; // required by IdTree::hasChildren() + } + + virtual bool isEditable() const + { + return true; + } + + }; + + struct RegionSoundNameColumn : public NestableColumn + { + RegionSoundNameColumn () + : NestableColumn (Columns::ColumnId_SoundName, + ColumnBase::Display_String, ColumnBase::Flag_Dialogue) + {} + + virtual bool isEditable() const + { + return true; + } + }; + + struct RegionSoundChanceColumn : public NestableColumn + { + RegionSoundChanceColumn () + : NestableColumn (Columns::ColumnId_SoundChance, + ColumnBase::Display_Integer, ColumnBase::Flag_Dialogue) + {} + + virtual bool isEditable() const + { + return true; + } + }; } #endif diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index b65cf7f968..39b3ea2e31 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -233,6 +233,10 @@ namespace CSMWorld { ColumnId_PathgridEdge0, "Point 0"}, { ColumnId_PathgridEdge1, "Point 1"}, + { ColumnId_RegionSounds, "Sounds"}, + { ColumnId_SoundName, "Name"}, + { ColumnId_SoundChance, "Chance"}, + { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, { ColumnId_UseValue3, "Use value 3" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 2cb7101b01..49a9208b02 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -222,6 +222,10 @@ namespace CSMWorld ColumnId_PathgridEdge0 = 206, ColumnId_PathgridEdge1 = 207, + ColumnId_RegionSounds = 208, + ColumnId_SoundName = 209, + ColumnId_SoundChance = 210, + // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. ColumnId_UseValue1 = 0x10000, diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 87d5116f16..c387298d2f 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -140,6 +140,12 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mRegions.addColumn (new NameColumn); mRegions.addColumn (new MapColourColumn); mRegions.addColumn (new SleepListColumn); + // see idadapterimpl.hpp and columnimp.hpp + RegionSoundListColumn *soundList = new RegionSoundListColumn (); + mRegions.addColumn (soundList); + mRegions.addAdapter (std::make_pair(soundList, new RegionSoundListAdapter ())); + mRegions.getNestableColumn(mRegions.getColumns()-1)->addColumn(new RegionSoundNameColumn ()); + mRegions.getNestableColumn(mRegions.getColumns()-1)->addColumn(new RegionSoundChanceColumn ()); mBirthsigns.addColumn (new StringIdColumn); mBirthsigns.addColumn (new RecordStateColumn); @@ -339,7 +345,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc addModel (new IdTable (&mRaces), UniversalId::Type_Race); addModel (new IdTable (&mSounds), UniversalId::Type_Sound); addModel (new IdTable (&mScripts), UniversalId::Type_Script); - addModel (new IdTable (&mRegions), UniversalId::Type_Region); + addModel (new IdTree (&mRegions, &mRegions), UniversalId::Type_Region); addModel (new IdTable (&mBirthsigns), UniversalId::Type_Birthsign); addModel (new IdTable (&mSpells), UniversalId::Type_Spell); addModel (new IdTable (&mTopics), UniversalId::Type_Topic); diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index b9e0600024..329aceaf7e 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -34,6 +34,7 @@ #include "../doc/stage.hpp" #include "idcollection.hpp" +#include "nestedidcollection.hpp" #include "universalid.hpp" #include "cell.hpp" #include "land.hpp" @@ -72,7 +73,7 @@ namespace CSMWorld IdCollection mRaces; IdCollection mSounds; IdCollection mScripts; - IdCollection mRegions; + NestedIdCollection mRegions; IdCollection mBirthsigns; IdCollection mSpells; IdCollection mTopics; diff --git a/apps/opencs/model/world/idadapterimp.hpp b/apps/opencs/model/world/idadapterimp.hpp index 7df653059b..d5a44aea2c 100644 --- a/apps/opencs/model/world/idadapterimp.hpp +++ b/apps/opencs/model/world/idadapterimp.hpp @@ -4,6 +4,7 @@ #include #include +#include #include "idadapter.hpp" #include "nestedtablewrapper.hpp" @@ -127,7 +128,7 @@ namespace CSMWorld case 1: return point.mX; case 2: return point.mY; case 3: return point.mZ; - default: throw std::logic_error("Pathgrid point subcolumn index out of range"); + default: throw std::runtime_error("Pathgrid point subcolumn index out of range"); } } @@ -142,7 +143,7 @@ namespace CSMWorld case 1: point.mX = value.toInt(); break; case 2: point.mY = value.toInt(); break; case 3: point.mZ = value.toInt(); break; - default: throw std::logic_error("Pathgrid point subcolumn index out of range"); + default: throw std::runtime_error("Pathgrid point subcolumn index out of range"); } pathgrid.mPoints[subRowIndex] = point; @@ -223,7 +224,7 @@ namespace CSMWorld case 0: return subRowIndex; case 1: return edge.mV0; case 2: return edge.mV1; - default: throw std::logic_error("Pathgrid edge subcolumn index out of range"); + default: throw std::runtime_error("Pathgrid edge subcolumn index out of range"); } } @@ -238,7 +239,7 @@ namespace CSMWorld case 0: break; case 1: edge.mV0 = value.toInt(); break; case 2: edge.mV1 = value.toInt(); break; - default: throw std::logic_error("Pathgrid edge subcolumn index out of range"); + default: throw std::runtime_error("Pathgrid edge subcolumn index out of range"); } pathgrid.mEdges[subRowIndex] = edge; @@ -256,6 +257,93 @@ namespace CSMWorld return static_cast(record.get().mEdges.size()); } }; + + template + class RegionSoundListAdapter : public NestedIdAdapter + { + public: + RegionSoundListAdapter () {} + + virtual void addNestedRow(Record& record, int position) const + { + ESXRecordT region = record.get(); + + std::vector& soundList = region.mSoundList; + + // blank row + ESXRecordT::SoundRef soundRef; + soundRef.mSound.assign(""); + soundRef.mChance = 0; + + soundList.insert(soundList.begin()+position, soundRef); + + record.setModified (region); + } + + virtual void removeNestedRow(Record& record, int rowToRemove) const + { + ESXRecordT region = record.get(); + + std::vector& soundList = region.mSoundList; + + if (rowToRemove < 0 || rowToRemove >= static_cast (soundList.size())) + throw std::runtime_error ("index out of range"); + + soundList.erase(soundList.begin()+rowToRemove); + + record.setModified (region); + } + + virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) const + { + record.get().mSoundList = + static_cast >&>(nestedTable).mNestedTable; + } + + virtual NestedTableWrapperBase* nestedTable(const Record& record) const + { + // deleted by dtor of NestedTableStoring + return new NestedTableWrapper >(record.get().mSoundList); + } + + virtual QVariant getNestedData(const Record& record, int subRowIndex, int subColIndex) const + { + ESXRecordT::SoundRef soundRef = record.get().mSoundList[subRowIndex]; + switch (subColIndex) + { + case 0: return QString(soundRef.mSound.toString().c_str()); + case 1: return soundRef.mChance; + default: throw std::runtime_error("Region sounds subcolumn index out of range"); + } + } + + virtual void setNestedData(Record& record, const QVariant& value, + int subRowIndex, int subColIndex) const + { + ESXRecordT region = record.get(); + ESXRecordT::SoundRef soundRef = region.mSoundList[subRowIndex]; + switch (subColIndex) + { + case 0: soundRef.mSound.assign(value.toString().toUtf8().constData()); break; + case 1: soundRef.mChance = static_cast(value.toInt()); break; + default: throw std::runtime_error("Region sounds subcolumn index out of range"); + } + + region.mSoundList[subRowIndex] = soundRef; + + record.setModified (region); + } + + virtual int getNestedColumnsCount(const Record& record) const + { + return 2; + } + + virtual int getNestedRowsCount(const Record& record) const + { + return static_cast(record.get().mSoundList.size()); + } + }; } #endif // CSM_WOLRD_IDADAPTERIMP_H From ea9563ad92c13397497846afad39fcc5d4cafb2d Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 11 Apr 2015 17:51:30 +1000 Subject: [PATCH 116/185] Add faction reactions table to dialogue subview. Fix gcc compile issues. Change nested columns to generic ones where possible. --- apps/opencs/model/world/columnbase.hpp | 2 +- apps/opencs/model/world/columnimp.hpp | 21 ++- apps/opencs/model/world/columns.cpp | 5 + apps/opencs/model/world/columns.hpp | 7 +- apps/opencs/model/world/data.cpp | 22 +++- apps/opencs/model/world/data.hpp | 2 +- apps/opencs/model/world/idadapterimp.hpp | 159 +++++++++++++++++++++-- 7 files changed, 190 insertions(+), 28 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 3902a009b9..c994ced156 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -99,7 +99,7 @@ namespace CSMWorld Display_NestedDestinationsList, Display_PathgridPointList, Display_PathgridEdgeList, - Display_RegionSoundList, + Display_NestedHeader, Display_EnchantmentType, Display_BodyPartType, diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index 06467a6328..675352d35c 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -2357,11 +2357,10 @@ namespace CSMWorld }; template - struct RegionSoundListColumn : public Column + struct NestedParentColumn : public Column { - RegionSoundListColumn () - : Column (Columns::ColumnId_RegionSounds, - ColumnBase::Display_RegionSoundList, ColumnBase::Flag_Dialogue) + NestedParentColumn (Columns::ColumnId id) + : Column (id, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue) {} virtual QVariant get (const Record& record) const @@ -2376,11 +2375,10 @@ namespace CSMWorld }; - struct RegionSoundNameColumn : public NestableColumn + struct NestedStringColumn : public NestableColumn { - RegionSoundNameColumn () - : NestableColumn (Columns::ColumnId_SoundName, - ColumnBase::Display_String, ColumnBase::Flag_Dialogue) + NestedStringColumn (Columns::ColumnId id) + : NestableColumn (id, ColumnBase::Display_String, ColumnBase::Flag_Dialogue) {} virtual bool isEditable() const @@ -2389,11 +2387,10 @@ namespace CSMWorld } }; - struct RegionSoundChanceColumn : public NestableColumn + struct NestedIntegerColumn : public NestableColumn { - RegionSoundChanceColumn () - : NestableColumn (Columns::ColumnId_SoundChance, - ColumnBase::Display_Integer, ColumnBase::Flag_Dialogue) + NestedIntegerColumn (Columns::ColumnId id) + : NestableColumn (id, ColumnBase::Display_Integer, ColumnBase::Flag_Dialogue) {} virtual bool isEditable() const diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 39b3ea2e31..c9155a5ad4 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -237,6 +237,10 @@ namespace CSMWorld { ColumnId_SoundName, "Name"}, { ColumnId_SoundChance, "Chance"}, + { ColumnId_FactionReactions, "Reactions"}, + //{ ColumnId_FactionID, "Faction ID"}, + { ColumnId_FactionReaction, "Reaction"}, + { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, { ColumnId_UseValue3, "Use value 3" }, @@ -263,6 +267,7 @@ namespace CSMWorld { ColumnId_Skill4, "Skill 4" }, { ColumnId_Skill5, "Skill 5" }, { ColumnId_Skill6, "Skill 6" }, + { ColumnId_Skill7, "Skill 7" }, { -1, 0 } // end marker }; diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 49a9208b02..531cf9972b 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -226,6 +226,10 @@ namespace CSMWorld ColumnId_SoundName = 209, ColumnId_SoundChance = 210, + ColumnId_FactionReactions = 211, + //ColumnId_FactionID = 212, + ColumnId_FactionReaction = 213, + // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. ColumnId_UseValue1 = 0x10000, @@ -259,7 +263,8 @@ namespace CSMWorld ColumnId_Skill3 = 0x50002, ColumnId_Skill4 = 0x50003, ColumnId_Skill5 = 0x50004, - ColumnId_Skill6 = 0x50005 + ColumnId_Skill6 = 0x50005, + ColumnId_Skill7 = 0x50006 }; std::string getName (ColumnId column); diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index c387298d2f..3352dd30e5 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -108,6 +108,15 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mFactions.addColumn (new HiddenColumn); for (int i=0; i<7; ++i) mFactions.addColumn (new SkillsColumn (i)); + // Faction Reactions + NestedParentColumn *reactions = + new NestedParentColumn (Columns::ColumnId_FactionReactions); + mFactions.addColumn (reactions); + mFactions.addAdapter (std::make_pair(reactions, new FactionReactionsAdapter ())); + mFactions.getNestableColumn(mFactions.getColumns()-1)->addColumn( + new NestedStringColumn (Columns::ColumnId_Faction)); + mFactions.getNestableColumn(mFactions.getColumns()-1)->addColumn( + new NestedIntegerColumn (Columns::ColumnId_FactionReaction)); mRaces.addColumn (new StringIdColumn); mRaces.addColumn (new RecordStateColumn); @@ -140,12 +149,15 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mRegions.addColumn (new NameColumn); mRegions.addColumn (new MapColourColumn); mRegions.addColumn (new SleepListColumn); - // see idadapterimpl.hpp and columnimp.hpp - RegionSoundListColumn *soundList = new RegionSoundListColumn (); + // Region Sounds + NestedParentColumn *soundList = + new NestedParentColumn (Columns::ColumnId_RegionSounds); mRegions.addColumn (soundList); mRegions.addAdapter (std::make_pair(soundList, new RegionSoundListAdapter ())); - mRegions.getNestableColumn(mRegions.getColumns()-1)->addColumn(new RegionSoundNameColumn ()); - mRegions.getNestableColumn(mRegions.getColumns()-1)->addColumn(new RegionSoundChanceColumn ()); + mRegions.getNestableColumn(mRegions.getColumns()-1)->addColumn( + new NestedStringColumn (Columns::ColumnId_SoundName)); + mRegions.getNestableColumn(mRegions.getColumns()-1)->addColumn( + new NestedIntegerColumn (Columns::ColumnId_SoundChance)); mBirthsigns.addColumn (new StringIdColumn); mBirthsigns.addColumn (new RecordStateColumn); @@ -341,7 +353,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc addModel (new IdTable (&mGmsts), UniversalId::Type_Gmst); addModel (new IdTable (&mSkills), UniversalId::Type_Skill); addModel (new IdTable (&mClasses), UniversalId::Type_Class); - addModel (new IdTable (&mFactions), UniversalId::Type_Faction); + addModel (new IdTree (&mFactions, &mFactions), UniversalId::Type_Faction); addModel (new IdTable (&mRaces), UniversalId::Type_Race); addModel (new IdTable (&mSounds), UniversalId::Type_Sound); addModel (new IdTable (&mScripts), UniversalId::Type_Script); diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index 329aceaf7e..858f826399 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -69,7 +69,7 @@ namespace CSMWorld IdCollection mGmsts; IdCollection mSkills; IdCollection mClasses; - IdCollection mFactions; + NestedIdCollection mFactions; IdCollection mRaces; IdCollection mSounds; IdCollection mScripts; diff --git a/apps/opencs/model/world/idadapterimp.hpp b/apps/opencs/model/world/idadapterimp.hpp index d5a44aea2c..00f7b1831d 100644 --- a/apps/opencs/model/world/idadapterimp.hpp +++ b/apps/opencs/model/world/idadapterimp.hpp @@ -5,6 +5,7 @@ #include #include +#include #include "idadapter.hpp" #include "nestedtablewrapper.hpp" @@ -218,7 +219,12 @@ namespace CSMWorld virtual QVariant getNestedData(const Record& record, int subRowIndex, int subColIndex) const { - ESM::Pathgrid::Edge edge = record.get().mEdges[subRowIndex]; + ESXRecordT pathgrid = record.get(); + + if (subRowIndex < 0 || subRowIndex >= static_cast (pathgrid.mEdges.size())) + throw std::runtime_error ("index out of range"); + + ESM::Pathgrid::Edge edge = pathgrid.mEdges[subRowIndex]; switch (subColIndex) { case 0: return subRowIndex; @@ -233,6 +239,10 @@ namespace CSMWorld int subRowIndex, int subColIndex) const { ESXRecordT pathgrid = record.get(); + + if (subRowIndex < 0 || subRowIndex >= static_cast (pathgrid.mEdges.size())) + throw std::runtime_error ("index out of range"); + ESM::Pathgrid::Edge edge = pathgrid.mEdges[subRowIndex]; switch (subColIndex) { @@ -258,6 +268,126 @@ namespace CSMWorld } }; + template + class FactionReactionsAdapter : public NestedIdAdapter + { + public: + FactionReactionsAdapter () {} + + virtual void addNestedRow(Record& record, int position) const + { + ESXRecordT faction = record.get(); + + std::map& reactions = faction.mReactions; + + // blank row + reactions.insert(std::make_pair("", 0)); + + record.setModified (faction); + } + + virtual void removeNestedRow(Record& record, int rowToRemove) const + { + ESXRecordT faction = record.get(); + + std::map& reactions = faction.mReactions; + + if (rowToRemove < 0 || rowToRemove >= static_cast (reactions.size())) + throw std::runtime_error ("index out of range"); + + // FIXME: how to ensure that the map entries correspond to table indicies? + // WARNING: Assumed that the table view has the same order as std::map + std::map::const_iterator iter = reactions.begin(); + for(int i = 0; i < rowToRemove; ++i) + iter++; + reactions.erase(iter); + + record.setModified (faction); + } + + virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) const + { + record.get().mReactions = + static_cast >&>(nestedTable).mNestedTable; + } + + virtual NestedTableWrapperBase* nestedTable(const Record& record) const + { + // deleted by dtor of NestedTableStoring + return new NestedTableWrapper >(record.get().mReactions); + } + + virtual QVariant getNestedData(const Record& record, int subRowIndex, int subColIndex) const + { + ESXRecordT faction = record.get(); + + std::map& reactions = faction.mReactions; + + if (subRowIndex < 0 || subRowIndex >= static_cast (reactions.size())) + throw std::runtime_error ("index out of range"); + + // FIXME: how to ensure that the map entries correspond to table indicies? + // WARNING: Assumed that the table view has the same order as std::map + std::map::const_iterator iter = reactions.begin(); + for(int i = 0; i < subRowIndex; ++i) + iter++; + switch (subColIndex) + { + case 0: return QString((*iter).first.c_str()); + case 1: return (*iter).second; + default: throw std::runtime_error("Faction reactions subcolumn index out of range"); + } + } + + virtual void setNestedData(Record& record, const QVariant& value, + int subRowIndex, int subColIndex) const + { + ESXRecordT faction = record.get(); + + std::map& reactions = faction.mReactions; + + if (subRowIndex < 0 || subRowIndex >= static_cast (reactions.size())) + throw std::runtime_error ("index out of range"); + + // FIXME: how to ensure that the map entries correspond to table indicies? + // WARNING: Assumed that the table view has the same order as std::map + std::map::const_iterator iter = reactions.begin(); + for(int i = 0; i < subRowIndex; ++i) + iter++; + + std::string factionId = (*iter).first; + int reaction = (*iter).second; + + switch (subColIndex) + { + case 0: + { + reactions.erase(iter); + reactions.insert(std::make_pair(value.toString().toUtf8().constData(), reaction)); + break; + } + case 1: + { + reactions[factionId] = value.toInt(); + break; + } + default: throw std::runtime_error("Faction reactions subcolumn index out of range"); + } + + record.setModified (faction); + } + + virtual int getNestedColumnsCount(const Record& record) const + { + return 2; + } + + virtual int getNestedRowsCount(const Record& record) const + { + return static_cast(record.get().mReactions.size()); + } + }; + template class RegionSoundListAdapter : public NestedIdAdapter { @@ -268,10 +398,10 @@ namespace CSMWorld { ESXRecordT region = record.get(); - std::vector& soundList = region.mSoundList; + std::vector& soundList = region.mSoundList; // blank row - ESXRecordT::SoundRef soundRef; + typename ESXRecordT::SoundRef soundRef; soundRef.mSound.assign(""); soundRef.mChance = 0; @@ -284,7 +414,7 @@ namespace CSMWorld { ESXRecordT region = record.get(); - std::vector& soundList = region.mSoundList; + std::vector& soundList = region.mSoundList; if (rowToRemove < 0 || rowToRemove >= static_cast (soundList.size())) throw std::runtime_error ("index out of range"); @@ -297,18 +427,25 @@ namespace CSMWorld virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) const { record.get().mSoundList = - static_cast >&>(nestedTable).mNestedTable; + static_cast >&>(nestedTable).mNestedTable; } virtual NestedTableWrapperBase* nestedTable(const Record& record) const { // deleted by dtor of NestedTableStoring - return new NestedTableWrapper >(record.get().mSoundList); + return new NestedTableWrapper >(record.get().mSoundList); } virtual QVariant getNestedData(const Record& record, int subRowIndex, int subColIndex) const { - ESXRecordT::SoundRef soundRef = record.get().mSoundList[subRowIndex]; + ESXRecordT region = record.get(); + + std::vector& soundList = region.mSoundList; + + if (subRowIndex < 0 || subRowIndex >= static_cast (soundList.size())) + throw std::runtime_error ("index out of range"); + + typename ESXRecordT::SoundRef soundRef = soundList[subRowIndex]; switch (subColIndex) { case 0: return QString(soundRef.mSound.toString().c_str()); @@ -321,7 +458,13 @@ namespace CSMWorld int subRowIndex, int subColIndex) const { ESXRecordT region = record.get(); - ESXRecordT::SoundRef soundRef = region.mSoundList[subRowIndex]; + + std::vector& soundList = region.mSoundList; + + if (subRowIndex < 0 || subRowIndex >= static_cast (soundList.size())) + throw std::runtime_error ("index out of range"); + + typename ESXRecordT::SoundRef soundRef = soundList[subRowIndex]; switch (subColIndex) { case 0: soundRef.mSound.assign(value.toString().toUtf8().constData()); break; From 9c75dad1acca2d48f26c97123875fc4ed5c60a3c Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 11 Apr 2015 18:21:08 +1000 Subject: [PATCH 117/185] Why is gcc so unkind? --- apps/opencs/model/world/idadapterimp.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/idadapterimp.hpp b/apps/opencs/model/world/idadapterimp.hpp index 00f7b1831d..9c4686f4e5 100644 --- a/apps/opencs/model/world/idadapterimp.hpp +++ b/apps/opencs/model/world/idadapterimp.hpp @@ -297,7 +297,7 @@ namespace CSMWorld // FIXME: how to ensure that the map entries correspond to table indicies? // WARNING: Assumed that the table view has the same order as std::map - std::map::const_iterator iter = reactions.begin(); + std::map::iterator iter = reactions.begin(); for(int i = 0; i < rowToRemove; ++i) iter++; reactions.erase(iter); @@ -351,7 +351,7 @@ namespace CSMWorld // FIXME: how to ensure that the map entries correspond to table indicies? // WARNING: Assumed that the table view has the same order as std::map - std::map::const_iterator iter = reactions.begin(); + std::map::iterator iter = reactions.begin(); for(int i = 0; i < subRowIndex; ++i) iter++; From f939648736ccf09a4d93699b2f8f3d7ea26ed6e7 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 11 Apr 2015 19:05:03 +1000 Subject: [PATCH 118/185] Add race spells table to dialogue subview. --- apps/opencs/model/world/columns.cpp | 2 +- apps/opencs/model/world/columns.hpp | 2 +- apps/opencs/model/world/data.cpp | 13 ++- apps/opencs/model/world/data.hpp | 2 +- apps/opencs/model/world/idadapterimp.hpp | 96 +++++++++++++++++++++ apps/opencs/model/world/refidcollection.cpp | 2 +- 6 files changed, 110 insertions(+), 7 deletions(-) diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index c9155a5ad4..a2843d3e85 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -187,7 +187,7 @@ namespace CSMWorld { ColumnId_MeshType, "Mesh Type" }, { ColumnId_ActorInventory, "Inventory" }, - { ColumnId_ActorSpells, "Spells" }, + { ColumnId_SpellList, "Spells" }, { ColumnId_SpellId, "ID"}, { ColumnId_NpcDestinations, "Destinations" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 531cf9972b..a1dc893932 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -179,7 +179,7 @@ namespace CSMWorld ColumnId_BodyPartType = 164, ColumnId_MeshType = 165, ColumnId_ActorInventory = 166, - ColumnId_ActorSpells = 167, + ColumnId_SpellList = 167, ColumnId_SpellId = 168, ColumnId_NpcDestinations = 169, ColumnId_DestinationCell = 170, diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 3352dd30e5..87ba440010 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -110,7 +110,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mFactions.addColumn (new SkillsColumn (i)); // Faction Reactions NestedParentColumn *reactions = - new NestedParentColumn (Columns::ColumnId_FactionReactions); + new NestedParentColumn (Columns::ColumnId_FactionReactions); mFactions.addColumn (reactions); mFactions.addAdapter (std::make_pair(reactions, new FactionReactionsAdapter ())); mFactions.getNestableColumn(mFactions.getColumns()-1)->addColumn( @@ -129,6 +129,13 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mRaces.addColumn (new WeightHeightColumn (true, false)); mRaces.addColumn (new WeightHeightColumn (false, true)); mRaces.addColumn (new WeightHeightColumn (false, false)); + // Race spells + NestedParentColumn *raceSpells = + new NestedParentColumn (Columns::ColumnId_SpellList); + mRaces.addColumn (raceSpells); + mRaces.addAdapter (std::make_pair(raceSpells, new SpellListAdapter ())); + mRaces.getNestableColumn(mRaces.getColumns()-1)->addColumn( + new NestedStringColumn (Columns::ColumnId_SpellId)); mSounds.addColumn (new StringIdColumn); mSounds.addColumn (new RecordStateColumn); @@ -151,7 +158,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mRegions.addColumn (new SleepListColumn); // Region Sounds NestedParentColumn *soundList = - new NestedParentColumn (Columns::ColumnId_RegionSounds); + new NestedParentColumn (Columns::ColumnId_RegionSounds); mRegions.addColumn (soundList); mRegions.addAdapter (std::make_pair(soundList, new RegionSoundListAdapter ())); mRegions.getNestableColumn(mRegions.getColumns()-1)->addColumn( @@ -354,7 +361,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc addModel (new IdTable (&mSkills), UniversalId::Type_Skill); addModel (new IdTable (&mClasses), UniversalId::Type_Class); addModel (new IdTree (&mFactions, &mFactions), UniversalId::Type_Faction); - addModel (new IdTable (&mRaces), UniversalId::Type_Race); + addModel (new IdTree (&mRaces, &mRaces), UniversalId::Type_Race); addModel (new IdTable (&mSounds), UniversalId::Type_Sound); addModel (new IdTable (&mScripts), UniversalId::Type_Script); addModel (new IdTree (&mRegions, &mRegions), UniversalId::Type_Region); diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index 858f826399..172a194be9 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -70,7 +70,7 @@ namespace CSMWorld IdCollection mSkills; IdCollection mClasses; NestedIdCollection mFactions; - IdCollection mRaces; + NestedIdCollection mRaces; IdCollection mSounds; IdCollection mScripts; NestedIdCollection mRegions; diff --git a/apps/opencs/model/world/idadapterimp.hpp b/apps/opencs/model/world/idadapterimp.hpp index 9c4686f4e5..c49435f1c8 100644 --- a/apps/opencs/model/world/idadapterimp.hpp +++ b/apps/opencs/model/world/idadapterimp.hpp @@ -487,6 +487,102 @@ namespace CSMWorld return static_cast(record.get().mSoundList.size()); } }; + + template + class SpellListAdapter : public NestedIdAdapter + { + public: + SpellListAdapter () {} + + virtual void addNestedRow(Record& record, int position) const + { + ESXRecordT raceOrBthSgn = record.get(); + + std::vector& spells = raceOrBthSgn.mPowers.mList; + + // blank row + std::string spell = ""; + + spells.insert(spells.begin()+position, spell); + + record.setModified (raceOrBthSgn); + } + + virtual void removeNestedRow(Record& record, int rowToRemove) const + { + ESXRecordT raceOrBthSgn = record.get(); + + std::vector& spells = raceOrBthSgn.mPowers.mList; + + if (rowToRemove < 0 || rowToRemove >= static_cast (spells.size())) + throw std::runtime_error ("index out of range"); + + spells.erase(spells.begin()+rowToRemove); + + record.setModified (raceOrBthSgn); + } + + virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) const + { + record.get().mPowers.mList = + static_cast >&>(nestedTable).mNestedTable; + } + + virtual NestedTableWrapperBase* nestedTable(const Record& record) const + { + // deleted by dtor of NestedTableStoring + return new NestedTableWrapper >(record.get().mPowers.mList); + } + + virtual QVariant getNestedData(const Record& record, int subRowIndex, int subColIndex) const + { + ESXRecordT raceOrBthSgn = record.get(); + + std::vector& spells = raceOrBthSgn.mPowers.mList; + + if (subRowIndex < 0 || subRowIndex >= static_cast (spells.size())) + throw std::runtime_error ("index out of range"); + + std::string spell = spells[subRowIndex]; + switch (subColIndex) + { + case 0: return QString(spell.c_str()); + default: throw std::runtime_error("Spells subcolumn index out of range"); + } + } + + virtual void setNestedData(Record& record, const QVariant& value, + int subRowIndex, int subColIndex) const + { + ESXRecordT raceOrBthSgn = record.get(); + + std::vector& spells = raceOrBthSgn.mPowers.mList; + + if (subRowIndex < 0 || subRowIndex >= static_cast (spells.size())) + throw std::runtime_error ("index out of range"); + + std::string spell = spells[subRowIndex]; + switch (subColIndex) + { + case 0: spell = value.toString().toUtf8().constData(); break; + default: throw std::runtime_error("Spells subcolumn index out of range"); + } + + raceOrBthSgn.mPowers.mList[subRowIndex] = spell; + + record.setModified (raceOrBthSgn); + } + + virtual int getNestedColumnsCount(const Record& record) const + { + return 1; + } + + virtual int getNestedRowsCount(const Record& record) const + { + return static_cast(record.get().mPowers.mList.size()); + } + }; } #endif // CSM_WOLRD_IDADAPTERIMP_H diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index b85deef4e6..392a1677e1 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -106,7 +106,7 @@ CSMWorld::RefIdCollection::RefIdCollection() new RefIdColumn (Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer)); // Nested table - mColumns.push_back(RefIdColumn (Columns::ColumnId_ActorSpells, ColumnBase::Display_NestedSpellList, ColumnBase::Flag_Dialogue)); + mColumns.push_back(RefIdColumn (Columns::ColumnId_SpellList, ColumnBase::Display_NestedSpellList, ColumnBase::Flag_Dialogue)); actorsColumns.mSpells = &mColumns.back(); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_SpellId, CSMWorld::ColumnBase::Display_String)); From 49fd5afdf650243a93e0a276fe665b2c7a6272c4 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 11 Apr 2015 19:17:17 +1000 Subject: [PATCH 119/185] Add birthsign spells table to dialogue subview. --- apps/opencs/model/world/data.cpp | 9 ++++++++- apps/opencs/model/world/data.hpp | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 87ba440010..74b418b304 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -172,6 +172,13 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mBirthsigns.addColumn (new NameColumn); mBirthsigns.addColumn (new TextureColumn); mBirthsigns.addColumn (new DescriptionColumn); + // Birthsign spells + NestedParentColumn *birthSpells = + new NestedParentColumn (Columns::ColumnId_SpellList); + mBirthsigns.addColumn (birthSpells); + mBirthsigns.addAdapter (std::make_pair(birthSpells, new SpellListAdapter ())); + mBirthsigns.getNestableColumn(mBirthsigns.getColumns()-1)->addColumn( + new NestedStringColumn (Columns::ColumnId_SpellId)); mSpells.addColumn (new StringIdColumn); mSpells.addColumn (new RecordStateColumn); @@ -365,7 +372,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc addModel (new IdTable (&mSounds), UniversalId::Type_Sound); addModel (new IdTable (&mScripts), UniversalId::Type_Script); addModel (new IdTree (&mRegions, &mRegions), UniversalId::Type_Region); - addModel (new IdTable (&mBirthsigns), UniversalId::Type_Birthsign); + addModel (new IdTree (&mBirthsigns, &mBirthsigns), UniversalId::Type_Birthsign); addModel (new IdTable (&mSpells), UniversalId::Type_Spell); addModel (new IdTable (&mTopics), UniversalId::Type_Topic); addModel (new IdTable (&mJournals), UniversalId::Type_Journal); diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index 172a194be9..2d2fd974c3 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -74,7 +74,7 @@ namespace CSMWorld IdCollection mSounds; IdCollection mScripts; NestedIdCollection mRegions; - IdCollection mBirthsigns; + NestedIdCollection mBirthsigns; IdCollection mSpells; IdCollection mTopics; IdCollection mJournals; From a460409555b1edc0fa7f8b1a8bb2217fea771ecb Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 11 Apr 2015 21:43:25 +1000 Subject: [PATCH 120/185] Add Spells and Enchantment magic effects table to dialogue subview. The numbers are not yet converted to strings. --- apps/opencs/model/world/columnimp.hpp | 98 +------------------ apps/opencs/model/world/columns.cpp | 6 ++ apps/opencs/model/world/columns.hpp | 6 ++ apps/opencs/model/world/data.cpp | 73 +++++++++++--- apps/opencs/model/world/data.hpp | 4 +- apps/opencs/model/world/idadapterimp.hpp | 119 +++++++++++++++++++++++ 6 files changed, 200 insertions(+), 106 deletions(-) diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index 675352d35c..0ab33065b7 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -2265,97 +2265,6 @@ namespace CSMWorld } }; - template - struct PathgridPointListColumn : public Column - { - PathgridPointListColumn () - : Column (Columns::ColumnId_PathgridPoints, - ColumnBase::Display_PathgridPointList, ColumnBase::Flag_Dialogue) - {} - - virtual QVariant get (const Record& record) const - { - return true; // required by IdTree::hasChildren() - } - - virtual bool isEditable() const - { - return true; - } - }; - - struct PathgridIndexColumn : public NestableColumn - { - PathgridIndexColumn() - : NestableColumn (Columns::ColumnId_PathgridIndex, - ColumnBase::Display_Integer, ColumnBase::Flag_Dialogue) - {} - - virtual bool isEditable() const - { - return false; - } - }; - - struct PathgridPointColumn : public NestableColumn - { - PathgridPointColumn(int index) - : NestableColumn (Columns::ColumnId_PathgridPosX+index, - ColumnBase::Display_Integer, ColumnBase::Flag_Dialogue) - {} - - virtual bool isEditable() const - { - return true; - } - }; - - template - struct PathgridEdgeListColumn : public Column - { - PathgridEdgeListColumn () - : Column (Columns::ColumnId_PathgridEdges, - ColumnBase::Display_PathgridEdgeList, ColumnBase::Flag_Dialogue) - {} - - virtual QVariant get (const Record& record) const - { - return true; // required by IdTree::hasChildren() - } - - virtual bool isEditable() const - { - return true; - } - - }; - - struct PathgridEdgeIndexColumn : public NestableColumn - { - PathgridEdgeIndexColumn() - : NestableColumn (Columns::ColumnId_PathgridEdgeIndex, - ColumnBase::Display_Integer, ColumnBase::Flag_Dialogue) - {} - - virtual bool isEditable() const - { - return false; - } - }; - - struct PathgridEdgeColumn : public NestableColumn - { - PathgridEdgeColumn (int index) - : NestableColumn (Columns::ColumnId_PathgridEdge0+index, - ColumnBase::Display_Integer, ColumnBase::Flag_Dialogue) - {} - - virtual bool isEditable() const - { - return true; - } - }; - template struct NestedParentColumn : public Column { @@ -2389,13 +2298,16 @@ namespace CSMWorld struct NestedIntegerColumn : public NestableColumn { - NestedIntegerColumn (Columns::ColumnId id) + bool mIsEditable; + + NestedIntegerColumn (Columns::ColumnId id, bool isEditable = true) : NestableColumn (id, ColumnBase::Display_Integer, ColumnBase::Flag_Dialogue) + , mIsEditable(isEditable) {} virtual bool isEditable() const { - return true; + return mIsEditable; } }; } diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index a2843d3e85..efe9a51167 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -241,6 +241,12 @@ namespace CSMWorld //{ ColumnId_FactionID, "Faction ID"}, { ColumnId_FactionReaction, "Reaction"}, + { ColumnId_EffectList, "Effects"}, + { ColumnId_EffectId, "ID"}, + { ColumnId_EffectAttribute, "Attrib"}, + { ColumnId_EffectRange, "Range"}, + { ColumnId_EffectArea, "Area"}, + { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, { ColumnId_UseValue3, "Use value 3" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index a1dc893932..6b3791042c 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -230,6 +230,12 @@ namespace CSMWorld //ColumnId_FactionID = 212, ColumnId_FactionReaction = 213, + ColumnId_EffectList = 214, + ColumnId_EffectId = 215, + ColumnId_EffectAttribute = 216, + ColumnId_EffectRange = 217, + ColumnId_EffectArea = 218, + // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. ColumnId_UseValue1 = 0x10000, diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 74b418b304..86cf3bb441 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -189,6 +189,27 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mSpells.addColumn (new FlagColumn (Columns::ColumnId_AutoCalc, 0x1)); mSpells.addColumn (new FlagColumn (Columns::ColumnId_StarterSpell, 0x2)); mSpells.addColumn (new FlagColumn (Columns::ColumnId_AlwaysSucceeds, 0x4)); + // Spell effects + NestedParentColumn *spellEffect = + new NestedParentColumn (Columns::ColumnId_EffectList); + mSpells.addColumn (spellEffect); + mSpells.addAdapter (std::make_pair(spellEffect, new EffectsListAdapter ())); + mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( + new NestedIntegerColumn (Columns::ColumnId_EffectId)); + mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( + new NestedIntegerColumn (Columns::ColumnId_Skill)); + mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( + new NestedIntegerColumn (Columns::ColumnId_EffectAttribute)); + mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( + new NestedIntegerColumn (Columns::ColumnId_EffectRange)); + mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( + new NestedIntegerColumn (Columns::ColumnId_EffectArea)); + mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( + new NestedIntegerColumn (Columns::ColumnId_Duration)); // reuse from light + mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( + new NestedIntegerColumn (Columns::ColumnId_MinRange)); // reuse from sound + mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( + new NestedIntegerColumn (Columns::ColumnId_MaxRange)); // reuse from sound mTopics.addColumn (new StringIdColumn); mTopics.addColumn (new RecordStateColumn); @@ -242,6 +263,27 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mEnchantments.addColumn (new CostColumn); mEnchantments.addColumn (new ChargesColumn2); mEnchantments.addColumn (new AutoCalcColumn); + // Enchantment effects + NestedParentColumn *enchantmentEffect = + new NestedParentColumn (Columns::ColumnId_EffectList); + mEnchantments.addColumn (enchantmentEffect); + mEnchantments.addAdapter (std::make_pair(enchantmentEffect, new EffectsListAdapter ())); + mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( + new NestedIntegerColumn (Columns::ColumnId_EffectId)); + mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( + new NestedIntegerColumn (Columns::ColumnId_Skill)); + mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( + new NestedIntegerColumn (Columns::ColumnId_EffectAttribute)); + mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( + new NestedIntegerColumn (Columns::ColumnId_EffectRange)); + mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( + new NestedIntegerColumn (Columns::ColumnId_EffectArea)); + mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( + new NestedIntegerColumn (Columns::ColumnId_Duration)); // reuse from light + mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( + new NestedIntegerColumn (Columns::ColumnId_MinRange)); // reuse from sound + mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( + new NestedIntegerColumn (Columns::ColumnId_MaxRange)); // reuse from sound mBodyParts.addColumn (new StringIdColumn); mBodyParts.addColumn (new RecordStateColumn); @@ -289,23 +331,32 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mPathgrids.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Pathgrid)); // new object deleted in dtor of Collection - PathgridPointListColumn *pointList = new PathgridPointListColumn (); + NestedParentColumn *pointList = + new NestedParentColumn (Columns::ColumnId_PathgridPoints); mPathgrids.addColumn (pointList); // new object deleted in dtor of SubCellCollection mPathgrids.addAdapter (std::make_pair(pointList, new PathgridPointListAdapter ())); // new objects deleted in dtor of NestableColumn // WARNING: The order of the columns below are assumed in PathgridPointListAdapter - mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridIndexColumn ()); - mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridPointColumn (0)); - mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridPointColumn (1)); - mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridPointColumn (2)); + mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn( + new NestedIntegerColumn (Columns::ColumnId_PathgridIndex, false)); + mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn( + new NestedIntegerColumn (Columns::ColumnId_PathgridPosX)); + mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn( + new NestedIntegerColumn (Columns::ColumnId_PathgridPosY)); + mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn( + new NestedIntegerColumn (Columns::ColumnId_PathgridPosZ)); - PathgridEdgeListColumn *edgeList = new PathgridEdgeListColumn (); + NestedParentColumn *edgeList = + new NestedParentColumn (Columns::ColumnId_PathgridEdges); mPathgrids.addColumn (edgeList); mPathgrids.addAdapter (std::make_pair(edgeList, new PathgridEdgeListAdapter ())); - mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridEdgeIndexColumn ()); - mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridEdgeColumn (0)); - mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(new PathgridEdgeColumn (1)); + mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn( + new NestedIntegerColumn (Columns::ColumnId_PathgridEdgeIndex, false)); + mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn( + new NestedIntegerColumn (Columns::ColumnId_PathgridEdge0)); + mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn( + new NestedIntegerColumn (Columns::ColumnId_PathgridEdge1)); mStartScripts.addColumn (new StringIdColumn); mStartScripts.addColumn (new RecordStateColumn); @@ -373,13 +424,13 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc addModel (new IdTable (&mScripts), UniversalId::Type_Script); addModel (new IdTree (&mRegions, &mRegions), UniversalId::Type_Region); addModel (new IdTree (&mBirthsigns, &mBirthsigns), UniversalId::Type_Birthsign); - addModel (new IdTable (&mSpells), UniversalId::Type_Spell); + addModel (new IdTree (&mSpells, &mSpells), UniversalId::Type_Spell); addModel (new IdTable (&mTopics), UniversalId::Type_Topic); addModel (new IdTable (&mJournals), UniversalId::Type_Journal); addModel (new IdTable (&mTopicInfos, IdTable::Feature_ReorderWithinTopic), UniversalId::Type_TopicInfo); addModel (new IdTable (&mJournalInfos, IdTable::Feature_ReorderWithinTopic), UniversalId::Type_JournalInfo); addModel (new IdTable (&mCells, IdTable::Feature_ViewId), UniversalId::Type_Cell); - addModel (new IdTable (&mEnchantments), UniversalId::Type_Enchantment); + addModel (new IdTree (&mEnchantments, &mEnchantments), UniversalId::Type_Enchantment); addModel (new IdTable (&mBodyParts), UniversalId::Type_BodyPart); addModel (new IdTable (&mSoundGens), UniversalId::Type_SoundGen); addModel (new IdTable (&mMagicEffects), UniversalId::Type_MagicEffect); diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index 2d2fd974c3..5ab69ac10d 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -75,10 +75,10 @@ namespace CSMWorld IdCollection mScripts; NestedIdCollection mRegions; NestedIdCollection mBirthsigns; - IdCollection mSpells; + NestedIdCollection mSpells; IdCollection mTopics; IdCollection mJournals; - IdCollection mEnchantments; + NestedIdCollection mEnchantments; IdCollection mBodyParts; IdCollection mMagicEffects; SubCellCollection mPathgrids; diff --git a/apps/opencs/model/world/idadapterimp.hpp b/apps/opencs/model/world/idadapterimp.hpp index c49435f1c8..219032dd3d 100644 --- a/apps/opencs/model/world/idadapterimp.hpp +++ b/apps/opencs/model/world/idadapterimp.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "idadapter.hpp" #include "nestedtablewrapper.hpp" @@ -583,6 +584,124 @@ namespace CSMWorld return static_cast(record.get().mPowers.mList.size()); } }; + + template + class EffectsListAdapter : public NestedIdAdapter + { + public: + EffectsListAdapter () {} + + virtual void addNestedRow(Record& record, int position) const + { + ESXRecordT magic = record.get(); + + std::vector& effectsList = magic.mEffects.mList; + + // blank row + ESM::ENAMstruct effect; + effect.mEffectID = 0; + effect.mSkill = 0; + effect.mAttribute = 0; + effect.mRange = 0; + effect.mArea = 0; + effect.mDuration = 0; + effect.mMagnMin = 0; + effect.mMagnMax = 0; + + effectsList.insert(effectsList.begin()+position, effect); + + record.setModified (magic); + } + + virtual void removeNestedRow(Record& record, int rowToRemove) const + { + ESXRecordT magic = record.get(); + + std::vector& effectsList = magic.mEffects.mList; + + if (rowToRemove < 0 || rowToRemove >= static_cast (effectsList.size())) + throw std::runtime_error ("index out of range"); + + effectsList.erase(effectsList.begin()+rowToRemove); + + record.setModified (magic); + } + + virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) const + { + record.get().mEffects.mList = + static_cast >&>(nestedTable).mNestedTable; + } + + virtual NestedTableWrapperBase* nestedTable(const Record& record) const + { + // deleted by dtor of NestedTableStoring + return new NestedTableWrapper >(record.get().mEffects.mList); + } + + virtual QVariant getNestedData(const Record& record, int subRowIndex, int subColIndex) const + { + ESXRecordT magic = record.get(); + + std::vector& effectsList = magic.mEffects.mList; + + if (subRowIndex < 0 || subRowIndex >= static_cast (effectsList.size())) + throw std::runtime_error ("index out of range"); + + ESM::ENAMstruct effect = effectsList[subRowIndex]; + switch (subColIndex) + { + case 0: return effect.mEffectID; + case 1: return effect.mSkill; + case 2: return effect.mAttribute; + case 3: return effect.mRange; + case 4: return effect.mArea; + case 5: return effect.mDuration; + case 6: return effect.mMagnMin; + case 7: return effect.mMagnMax; + default: throw std::runtime_error("Magic Effects subcolumn index out of range"); + } + } + + virtual void setNestedData(Record& record, const QVariant& value, + int subRowIndex, int subColIndex) const + { + ESXRecordT magic = record.get(); + + std::vector& effectsList = magic.mEffects.mList; + + if (subRowIndex < 0 || subRowIndex >= static_cast (effectsList.size())) + throw std::runtime_error ("index out of range"); + + ESM::ENAMstruct effect = effectsList[subRowIndex]; + switch (subColIndex) + { + case 0: effect.mEffectID = static_cast(value.toInt()); break; + case 1: effect.mSkill = static_cast(value.toInt()); break; + case 2: effect.mAttribute = static_cast(value.toInt()); break; + case 3: effect.mRange = value.toInt(); break; + case 4: effect.mArea = value.toInt(); break; + case 5: effect.mDuration = value.toInt(); break; + case 6: effect.mMagnMin = value.toInt(); break; + case 7: effect.mMagnMax = value.toInt(); break; + default: throw std::runtime_error("Magic Effects subcolumn index out of range"); + } + + magic.mEffects.mList[subRowIndex] = effect; + + record.setModified (magic); + } + + virtual int getNestedColumnsCount(const Record& record) const + { + return 8; + } + + virtual int getNestedRowsCount(const Record& record) const + { + return static_cast(record.get().mEffects.mList.size()); + } + }; } #endif // CSM_WOLRD_IDADAPTERIMP_H From 8dab2f9b14f93509f9c54d1572bb983f372c0546 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sun, 12 Apr 2015 07:46:32 +1000 Subject: [PATCH 121/185] Use human friendly strings in magic effects subtable. --- apps/opencs/model/world/columnimp.hpp | 7 +- apps/opencs/model/world/columns.cpp | 4 +- apps/opencs/model/world/columns.hpp | 2 +- apps/opencs/model/world/data.cpp | 16 +-- apps/opencs/model/world/idadapterimp.hpp | 143 +++++++++++++++++++++-- 5 files changed, 151 insertions(+), 21 deletions(-) diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index 0ab33065b7..210d638036 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -2286,13 +2286,16 @@ namespace CSMWorld struct NestedStringColumn : public NestableColumn { - NestedStringColumn (Columns::ColumnId id) + bool mIsEditable; + + NestedStringColumn (Columns::ColumnId id, bool isEditable = true) : NestableColumn (id, ColumnBase::Display_String, ColumnBase::Flag_Dialogue) + , mIsEditable(isEditable) {} virtual bool isEditable() const { - return true; + return mIsEditable; } }; diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index efe9a51167..fca16ec0b5 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -242,8 +242,8 @@ namespace CSMWorld { ColumnId_FactionReaction, "Reaction"}, { ColumnId_EffectList, "Effects"}, - { ColumnId_EffectId, "ID"}, - { ColumnId_EffectAttribute, "Attrib"}, + { ColumnId_EffectId, "Effect"}, + //{ ColumnId_EffectAttribute, "Attrib"}, { ColumnId_EffectRange, "Range"}, { ColumnId_EffectArea, "Area"}, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 6b3791042c..4f77ee23a0 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -232,7 +232,7 @@ namespace CSMWorld ColumnId_EffectList = 214, ColumnId_EffectId = 215, - ColumnId_EffectAttribute = 216, + //ColumnId_EffectAttribute = 216, ColumnId_EffectRange = 217, ColumnId_EffectArea = 218, diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 86cf3bb441..538b240dc1 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -195,15 +195,15 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mSpells.addColumn (spellEffect); mSpells.addAdapter (std::make_pair(spellEffect, new EffectsListAdapter ())); mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_EffectId)); + new NestedStringColumn (Columns::ColumnId_EffectId/*, false*/)); // false means no edit mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_Skill)); + new NestedStringColumn (Columns::ColumnId_Skill)); mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_EffectAttribute)); + new NestedStringColumn (Columns::ColumnId_Attribute)); // reuse attribute mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( new NestedIntegerColumn (Columns::ColumnId_EffectRange)); mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_EffectArea)); + new NestedStringColumn (Columns::ColumnId_EffectArea)); mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( new NestedIntegerColumn (Columns::ColumnId_Duration)); // reuse from light mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( @@ -269,15 +269,15 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mEnchantments.addColumn (enchantmentEffect); mEnchantments.addAdapter (std::make_pair(enchantmentEffect, new EffectsListAdapter ())); mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_EffectId)); + new NestedStringColumn (Columns::ColumnId_EffectId/*, false*/)); mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_Skill)); + new NestedStringColumn (Columns::ColumnId_Skill)); mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_EffectAttribute)); + new NestedStringColumn (Columns::ColumnId_Attribute)); // reuse attribute mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( new NestedIntegerColumn (Columns::ColumnId_EffectRange)); mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_EffectArea)); + new NestedStringColumn (Columns::ColumnId_EffectArea)); mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( new NestedIntegerColumn (Columns::ColumnId_Duration)); // reuse from light mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( diff --git a/apps/opencs/model/world/idadapterimp.hpp b/apps/opencs/model/world/idadapterimp.hpp index 219032dd3d..d5bf83a2d9 100644 --- a/apps/opencs/model/world/idadapterimp.hpp +++ b/apps/opencs/model/world/idadapterimp.hpp @@ -7,6 +7,9 @@ #include #include #include +#include // for converting magic effect id to string & back +#include // for converting skill names +#include // for converting attributes #include "idadapter.hpp" #include "nestedtablewrapper.hpp" @@ -651,10 +654,82 @@ namespace CSMWorld ESM::ENAMstruct effect = effectsList[subRowIndex]; switch (subColIndex) { - case 0: return effect.mEffectID; - case 1: return effect.mSkill; - case 2: return effect.mAttribute; - case 3: return effect.mRange; + case 0: + { + // indexToId() prepends "#d+" hence not so user friendly + QString effectId(ESM::MagicEffect::effectIdToString(effect.mEffectID).c_str()); + return effectId.remove(0, 7); // 7 == sizeof("sEffect") - 1 + } + case 1: + { + switch (effect.mSkill) + { + // see ESM::Skill::SkillEnum in + case ESM::Skill::Block: + case ESM::Skill::Armorer: + case ESM::Skill::MediumArmor: + case ESM::Skill::HeavyArmor: + case ESM::Skill::BluntWeapon: + case ESM::Skill::LongBlade: + case ESM::Skill::Axe: + case ESM::Skill::Spear: + case ESM::Skill::Athletics: + case ESM::Skill::Enchant: + case ESM::Skill::Destruction: + case ESM::Skill::Alteration: + case ESM::Skill::Illusion: + case ESM::Skill::Conjuration: + case ESM::Skill::Mysticism: + case ESM::Skill::Restoration: + case ESM::Skill::Alchemy: + case ESM::Skill::Unarmored: + case ESM::Skill::Security: + case ESM::Skill::Sneak: + case ESM::Skill::Acrobatics: + case ESM::Skill::LightArmor: + case ESM::Skill::ShortBlade: + case ESM::Skill::Marksman: + case ESM::Skill::Mercantile: + case ESM::Skill::Speechcraft: + case ESM::Skill::HandToHand: + { + return QString(ESM::Skill::sSkillNames[effect.mSkill].c_str()); + } + case -1: return QString("N/A"); + default: return QVariant(); + } + } + case 2: + { + switch (effect.mAttribute) + { + // see ESM::Attribute::AttributeID in + case ESM::Attribute::Strength: + case ESM::Attribute::Intelligence: + case ESM::Attribute::Willpower: + case ESM::Attribute::Agility: + case ESM::Attribute::Speed: + case ESM::Attribute::Endurance: + case ESM::Attribute::Personality: + case ESM::Attribute::Luck: + { + return QString(ESM::Attribute::sAttributeNames[effect.mAttribute].c_str()); + } + case -1: return QString("N/A"); + default: return QVariant(); + } + } + case 3: + { + switch (effect.mRange) + { + // see ESM::RangeType in + case ESM::RT_Self: return QString("Self"); + case ESM::RT_Touch: return QString("Touch"); + case ESM::RT_Target: return QString("Target"); + default: return QVariant(); + } + } case 4: return effect.mArea; case 5: return effect.mDuration; case 6: return effect.mMagnMin; @@ -676,10 +751,62 @@ namespace CSMWorld ESM::ENAMstruct effect = effectsList[subRowIndex]; switch (subColIndex) { - case 0: effect.mEffectID = static_cast(value.toInt()); break; - case 1: effect.mSkill = static_cast(value.toInt()); break; - case 2: effect.mAttribute = static_cast(value.toInt()); break; - case 3: effect.mRange = value.toInt(); break; + case 0: + { + effect.mEffectID = + ESM::MagicEffect::effectStringToId("sEffect"+value.toString().toStdString()); + break; + } + case 1: + { + std::string skillName = value.toString().toStdString(); + if ("N/A" == skillName) + { + effect.mSkill = -1; + break; + } + + for (unsigned int i = 0; i < ESM::Skill::Length; ++i) + { + if (ESM::Skill::sSkillNames[i] == skillName) + { + effect.mSkill = static_cast(i); + break; + } + } + break; + } + case 2: + { + std::string attr = value.toString().toStdString(); + if ("N/A" == attr) + { + effect.mAttribute = -1; + break; + } + + for (unsigned int i = 0; i < ESM::Attribute::Length; ++i) + { + if (ESM::Attribute::sAttributeNames[i] == attr) + { + effect.mAttribute = static_cast(i); + break; + } + } + break; + } + case 3: + { + std::string effectId = value.toString().toStdString(); + if (effectId == "Self") + effect.mRange = ESM::RT_Self; + else if (effectId == "Touch") + effect.mRange = ESM::RT_Touch; + else if (effectId == "Target") + effect.mRange = ESM::RT_Target; + // else leave unchanged + break; + } case 4: effect.mArea = value.toInt(); break; case 5: effect.mDuration = value.toInt(); break; case 6: effect.mMagnMin = value.toInt(); break; From 4b9c9bf09510b89aff9926522037252daafa9c28 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sun, 12 Apr 2015 08:52:09 +1000 Subject: [PATCH 122/185] Simplify and relocate nested column definitions. --- apps/opencs/model/world/columnbase.cpp | 15 +++++-- apps/opencs/model/world/columnbase.hpp | 27 ++++++++++++ apps/opencs/model/world/columnimp.hpp | 49 ---------------------- apps/opencs/model/world/data.cpp | 58 +++++++++++++------------- 4 files changed, 68 insertions(+), 81 deletions(-) diff --git a/apps/opencs/model/world/columnbase.cpp b/apps/opencs/model/world/columnbase.cpp index 8d1985ff27..0d9eb16646 100644 --- a/apps/opencs/model/world/columnbase.cpp +++ b/apps/opencs/model/world/columnbase.cpp @@ -3,7 +3,7 @@ #include "columns.hpp" CSMWorld::ColumnBase::ColumnBase (int columnId, Display displayType, int flags) -: mColumnId (columnId), mDisplayType (displayType), mFlags (flags) + : mColumnId (columnId), mDisplayType (displayType), mFlags (flags) {} CSMWorld::ColumnBase::~ColumnBase() {} @@ -39,8 +39,7 @@ const CSMWorld::ColumnBase& CSMWorld::NestableColumn::nestedColumn(int subColumn CSMWorld::NestableColumn::NestableColumn(int columnId, CSMWorld::ColumnBase::Display displayType, int flag) : CSMWorld::ColumnBase(columnId, displayType, flag) -{ -} +{} CSMWorld::NestableColumn::~NestableColumn() { @@ -54,3 +53,13 @@ bool CSMWorld::NestableColumn::hasChildren() const { return !mNestedColumns.empty(); } + +CSMWorld::NestedChildColumn::NestedChildColumn (int id, + CSMWorld::ColumnBase::Display display, bool isEditable) + : NestableColumn (id, display, CSMWorld::ColumnBase::Flag_Dialogue) , mIsEditable(isEditable) +{} + +bool CSMWorld::NestedChildColumn::isEditable () const +{ + return mIsEditable; +} diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index c994ced156..dc3aae11a5 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -165,6 +165,33 @@ namespace CSMWorld throw std::logic_error ("Column " + getTitle() + " is not editable"); } }; + + template + struct NestedParentColumn : public Column + { + NestedParentColumn (int id) : Column (id, Display_NestedHeader, Flag_Dialogue) + {} + + virtual QVariant get (const Record& record) const + { + return true; // required by IdTree::hasChildren() + } + + virtual bool isEditable() const + { + return true; + } + }; + + struct NestedChildColumn : public NestableColumn + { + NestedChildColumn (int id, Display display, bool isEditable = true); + + virtual bool isEditable() const; + + private: + bool mIsEditable; + }; } #endif diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index 210d638036..68e7dd7b59 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -2264,55 +2264,6 @@ namespace CSMWorld return true; } }; - - template - struct NestedParentColumn : public Column - { - NestedParentColumn (Columns::ColumnId id) - : Column (id, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue) - {} - - virtual QVariant get (const Record& record) const - { - return true; // required by IdTree::hasChildren() - } - - virtual bool isEditable() const - { - return true; - } - - }; - - struct NestedStringColumn : public NestableColumn - { - bool mIsEditable; - - NestedStringColumn (Columns::ColumnId id, bool isEditable = true) - : NestableColumn (id, ColumnBase::Display_String, ColumnBase::Flag_Dialogue) - , mIsEditable(isEditable) - {} - - virtual bool isEditable() const - { - return mIsEditable; - } - }; - - struct NestedIntegerColumn : public NestableColumn - { - bool mIsEditable; - - NestedIntegerColumn (Columns::ColumnId id, bool isEditable = true) - : NestableColumn (id, ColumnBase::Display_Integer, ColumnBase::Flag_Dialogue) - , mIsEditable(isEditable) - {} - - virtual bool isEditable() const - { - return mIsEditable; - } - }; } #endif diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 538b240dc1..69e2b5aa8a 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -114,9 +114,9 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mFactions.addColumn (reactions); mFactions.addAdapter (std::make_pair(reactions, new FactionReactionsAdapter ())); mFactions.getNestableColumn(mFactions.getColumns()-1)->addColumn( - new NestedStringColumn (Columns::ColumnId_Faction)); + new NestedChildColumn (Columns::ColumnId_Faction, ColumnBase::Display_String)); mFactions.getNestableColumn(mFactions.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_FactionReaction)); + new NestedChildColumn (Columns::ColumnId_FactionReaction, ColumnBase::Display_Integer)); mRaces.addColumn (new StringIdColumn); mRaces.addColumn (new RecordStateColumn); @@ -135,7 +135,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mRaces.addColumn (raceSpells); mRaces.addAdapter (std::make_pair(raceSpells, new SpellListAdapter ())); mRaces.getNestableColumn(mRaces.getColumns()-1)->addColumn( - new NestedStringColumn (Columns::ColumnId_SpellId)); + new NestedChildColumn (Columns::ColumnId_SpellId, ColumnBase::Display_String)); mSounds.addColumn (new StringIdColumn); mSounds.addColumn (new RecordStateColumn); @@ -162,9 +162,9 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mRegions.addColumn (soundList); mRegions.addAdapter (std::make_pair(soundList, new RegionSoundListAdapter ())); mRegions.getNestableColumn(mRegions.getColumns()-1)->addColumn( - new NestedStringColumn (Columns::ColumnId_SoundName)); + new NestedChildColumn (Columns::ColumnId_SoundName, ColumnBase::Display_String)); mRegions.getNestableColumn(mRegions.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_SoundChance)); + new NestedChildColumn (Columns::ColumnId_SoundChance, ColumnBase::Display_Integer)); mBirthsigns.addColumn (new StringIdColumn); mBirthsigns.addColumn (new RecordStateColumn); @@ -178,7 +178,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mBirthsigns.addColumn (birthSpells); mBirthsigns.addAdapter (std::make_pair(birthSpells, new SpellListAdapter ())); mBirthsigns.getNestableColumn(mBirthsigns.getColumns()-1)->addColumn( - new NestedStringColumn (Columns::ColumnId_SpellId)); + new NestedChildColumn (Columns::ColumnId_SpellId, ColumnBase::Display_String)); mSpells.addColumn (new StringIdColumn); mSpells.addColumn (new RecordStateColumn); @@ -195,21 +195,21 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mSpells.addColumn (spellEffect); mSpells.addAdapter (std::make_pair(spellEffect, new EffectsListAdapter ())); mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( - new NestedStringColumn (Columns::ColumnId_EffectId/*, false*/)); // false means no edit + new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_String/*, false*/)); // false means no edit mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( - new NestedStringColumn (Columns::ColumnId_Skill)); + new NestedChildColumn (Columns::ColumnId_Skill, ColumnBase::Display_String)); mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( - new NestedStringColumn (Columns::ColumnId_Attribute)); // reuse attribute + new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_String)); // reuse attribute mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_EffectRange)); + new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_Integer)); mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( - new NestedStringColumn (Columns::ColumnId_EffectArea)); + new NestedChildColumn (Columns::ColumnId_EffectArea, ColumnBase::Display_String)); mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_Duration)); // reuse from light + new NestedChildColumn (Columns::ColumnId_Duration, ColumnBase::Display_Integer)); // reuse from light mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_MinRange)); // reuse from sound + new NestedChildColumn (Columns::ColumnId_MinRange, ColumnBase::Display_Integer)); // reuse from sound mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_MaxRange)); // reuse from sound + new NestedChildColumn (Columns::ColumnId_MaxRange, ColumnBase::Display_Integer)); // reuse from sound mTopics.addColumn (new StringIdColumn); mTopics.addColumn (new RecordStateColumn); @@ -269,21 +269,21 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mEnchantments.addColumn (enchantmentEffect); mEnchantments.addAdapter (std::make_pair(enchantmentEffect, new EffectsListAdapter ())); mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( - new NestedStringColumn (Columns::ColumnId_EffectId/*, false*/)); + new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_String/*, false*/)); mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( - new NestedStringColumn (Columns::ColumnId_Skill)); + new NestedChildColumn (Columns::ColumnId_Skill, ColumnBase::Display_String)); mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( - new NestedStringColumn (Columns::ColumnId_Attribute)); // reuse attribute + new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_String)); // reuse attribute mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_EffectRange)); + new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_Integer)); mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( - new NestedStringColumn (Columns::ColumnId_EffectArea)); + new NestedChildColumn (Columns::ColumnId_EffectArea, ColumnBase::Display_String)); mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_Duration)); // reuse from light + new NestedChildColumn (Columns::ColumnId_Duration, ColumnBase::Display_Integer)); // reuse from light mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_MinRange)); // reuse from sound + new NestedChildColumn (Columns::ColumnId_MinRange, ColumnBase::Display_Integer)); // reuse from sound mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_MaxRange)); // reuse from sound + new NestedChildColumn (Columns::ColumnId_MaxRange, ColumnBase::Display_Integer)); // reuse from sound mBodyParts.addColumn (new StringIdColumn); mBodyParts.addColumn (new RecordStateColumn); @@ -339,24 +339,24 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc // new objects deleted in dtor of NestableColumn // WARNING: The order of the columns below are assumed in PathgridPointListAdapter mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_PathgridIndex, false)); + new NestedChildColumn (Columns::ColumnId_PathgridIndex, ColumnBase::Display_Integer, false)); mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_PathgridPosX)); + new NestedChildColumn (Columns::ColumnId_PathgridPosX, ColumnBase::Display_Integer)); mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_PathgridPosY)); + new NestedChildColumn (Columns::ColumnId_PathgridPosY, ColumnBase::Display_Integer)); mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_PathgridPosZ)); + new NestedChildColumn (Columns::ColumnId_PathgridPosZ, ColumnBase::Display_Integer)); NestedParentColumn *edgeList = new NestedParentColumn (Columns::ColumnId_PathgridEdges); mPathgrids.addColumn (edgeList); mPathgrids.addAdapter (std::make_pair(edgeList, new PathgridEdgeListAdapter ())); mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_PathgridEdgeIndex, false)); + new NestedChildColumn (Columns::ColumnId_PathgridEdgeIndex, ColumnBase::Display_Integer, false)); mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_PathgridEdge0)); + new NestedChildColumn (Columns::ColumnId_PathgridEdge0, ColumnBase::Display_Integer)); mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn( - new NestedIntegerColumn (Columns::ColumnId_PathgridEdge1)); + new NestedChildColumn (Columns::ColumnId_PathgridEdge1, ColumnBase::Display_Integer)); mStartScripts.addColumn (new StringIdColumn); mStartScripts.addColumn (new RecordStateColumn); From 41b368a759ca70405ed7f7d4bdf9e6112393699b Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sun, 12 Apr 2015 10:52:01 +1000 Subject: [PATCH 123/185] Moved templated code around a bit. --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/world/columnbase.hpp | 3 +- apps/opencs/model/world/data.cpp | 8 +- apps/opencs/model/world/idadapterimp.cpp | 457 +++++++++++++++++++++ apps/opencs/model/world/idadapterimp.hpp | 499 ++++------------------- 5 files changed, 536 insertions(+), 433 deletions(-) create mode 100644 apps/opencs/model/world/idadapterimp.cpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 8cf37da1d2..bc0b964ae7 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -25,7 +25,7 @@ opencs_units (model/world opencs_units_noqt (model/world universalid record commands columnbase scriptcontext cell refidcollection refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope - pathgrid landtexture land nestedtablewrapper nestedadapters nestedcollection + pathgrid landtexture land nestedtablewrapper nestedadapters nestedcollection idadapterimp ) opencs_hdrs_noqt (model/world diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index dc3aae11a5..c7c8d3cd8b 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -169,7 +169,8 @@ namespace CSMWorld template struct NestedParentColumn : public Column { - NestedParentColumn (int id) : Column (id, Display_NestedHeader, Flag_Dialogue) + NestedParentColumn (int id) : Column (id, + ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue) {} virtual QVariant get (const Record& record) const diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 69e2b5aa8a..db644affa6 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -112,7 +112,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc NestedParentColumn *reactions = new NestedParentColumn (Columns::ColumnId_FactionReactions); mFactions.addColumn (reactions); - mFactions.addAdapter (std::make_pair(reactions, new FactionReactionsAdapter ())); + mFactions.addAdapter (std::make_pair(reactions, new FactionReactionsAdapter ())); mFactions.getNestableColumn(mFactions.getColumns()-1)->addColumn( new NestedChildColumn (Columns::ColumnId_Faction, ColumnBase::Display_String)); mFactions.getNestableColumn(mFactions.getColumns()-1)->addColumn( @@ -160,7 +160,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc NestedParentColumn *soundList = new NestedParentColumn (Columns::ColumnId_RegionSounds); mRegions.addColumn (soundList); - mRegions.addAdapter (std::make_pair(soundList, new RegionSoundListAdapter ())); + mRegions.addAdapter (std::make_pair(soundList, new RegionSoundListAdapter ())); mRegions.getNestableColumn(mRegions.getColumns()-1)->addColumn( new NestedChildColumn (Columns::ColumnId_SoundName, ColumnBase::Display_String)); mRegions.getNestableColumn(mRegions.getColumns()-1)->addColumn( @@ -335,7 +335,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc new NestedParentColumn (Columns::ColumnId_PathgridPoints); mPathgrids.addColumn (pointList); // new object deleted in dtor of SubCellCollection - mPathgrids.addAdapter (std::make_pair(pointList, new PathgridPointListAdapter ())); + mPathgrids.addAdapter (std::make_pair(pointList, new PathgridPointListAdapter ())); // new objects deleted in dtor of NestableColumn // WARNING: The order of the columns below are assumed in PathgridPointListAdapter mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn( @@ -350,7 +350,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc NestedParentColumn *edgeList = new NestedParentColumn (Columns::ColumnId_PathgridEdges); mPathgrids.addColumn (edgeList); - mPathgrids.addAdapter (std::make_pair(edgeList, new PathgridEdgeListAdapter ())); + mPathgrids.addAdapter (std::make_pair(edgeList, new PathgridEdgeListAdapter ())); mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn( new NestedChildColumn (Columns::ColumnId_PathgridEdgeIndex, ColumnBase::Display_Integer, false)); mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn( diff --git a/apps/opencs/model/world/idadapterimp.cpp b/apps/opencs/model/world/idadapterimp.cpp new file mode 100644 index 0000000000..95e68e09ed --- /dev/null +++ b/apps/opencs/model/world/idadapterimp.cpp @@ -0,0 +1,457 @@ +#include "idadapterimp.hpp" + +#include +#include + +#include "idcollection.hpp" +#include "pathgrid.hpp" + +namespace CSMWorld +{ + PathgridPointListAdapter::PathgridPointListAdapter () {} + + void PathgridPointListAdapter::addNestedRow(Record& record, int position) const + { + Pathgrid pathgrid = record.get(); + + ESM::Pathgrid::PointList& points = pathgrid.mPoints; + + // blank row + ESM::Pathgrid::Point point; + point.mX = 0; + point.mY = 0; + point.mZ = 0; + point.mAutogenerated = 0; + point.mConnectionNum = 0; + point.mUnknown = 0; + + // inserting a point should trigger re-indexing of the edges + // + // FIXME: does not auto refresh edges table view + std::vector::iterator iter = pathgrid.mEdges.begin(); + for (;iter != pathgrid.mEdges.end(); ++iter) + { + if ((*iter).mV0 >= position) + (*iter).mV0++; + if ((*iter).mV1 >= position) + (*iter).mV1++; + } + + points.insert(points.begin()+position, point); + pathgrid.mData.mS2 += 1; // increment the number of points + + record.setModified (pathgrid); + } + + void PathgridPointListAdapter::removeNestedRow(Record& record, int rowToRemove) const + { + Pathgrid pathgrid = record.get(); + + ESM::Pathgrid::PointList& points = pathgrid.mPoints; + + if (rowToRemove < 0 || rowToRemove >= static_cast (points.size())) + throw std::runtime_error ("index out of range"); + + // deleting a point should trigger re-indexing of the edges + // dangling edges are not allowed and hence removed + // + // FIXME: does not auto refresh edges table view + std::vector::iterator iter = pathgrid.mEdges.begin(); + for (; iter != pathgrid.mEdges.end();) + { + if (((*iter).mV0 == rowToRemove) || ((*iter).mV1 == rowToRemove)) + iter = pathgrid.mEdges.erase(iter); + else + { + if ((*iter).mV0 > rowToRemove) + (*iter).mV0--; + + if ((*iter).mV1 > rowToRemove) + (*iter).mV1--; + + ++iter; + } + } + points.erase(points.begin()+rowToRemove); + pathgrid.mData.mS2 -= 1; // decrement the number of points + + record.setModified (pathgrid); + } + + void PathgridPointListAdapter::setNestedTable(Record& record, + const NestedTableWrapperBase& nestedTable) const + { + record.get().mPoints = + static_cast(nestedTable).mRecord.mPoints; + record.get().mData.mS2 = + static_cast(nestedTable).mRecord.mData.mS2; + // also update edges in case points were added/removed + record.get().mEdges = + static_cast(nestedTable).mRecord.mEdges; + } + + NestedTableWrapperBase* PathgridPointListAdapter::nestedTable(const Record& record) const + { + // deleted by dtor of NestedTableStoring + return new PathgridPointsWrap(record.get()); + } + + QVariant PathgridPointListAdapter::getNestedData(const Record& record, + int subRowIndex, int subColIndex) const + { + ESM::Pathgrid::Point point = record.get().mPoints[subRowIndex]; + switch (subColIndex) + { + case 0: return subRowIndex; + case 1: return point.mX; + case 2: return point.mY; + case 3: return point.mZ; + default: throw std::runtime_error("Pathgrid point subcolumn index out of range"); + } + } + + void PathgridPointListAdapter::setNestedData(Record& record, + const QVariant& value, int subRowIndex, int subColIndex) const + { + Pathgrid pathgrid = record.get(); + ESM::Pathgrid::Point point = pathgrid.mPoints[subRowIndex]; + switch (subColIndex) + { + case 0: break; + case 1: point.mX = value.toInt(); break; + case 2: point.mY = value.toInt(); break; + case 3: point.mZ = value.toInt(); break; + default: throw std::runtime_error("Pathgrid point subcolumn index out of range"); + } + + pathgrid.mPoints[subRowIndex] = point; + + record.setModified (pathgrid); + } + + int PathgridPointListAdapter::getNestedColumnsCount(const Record& record) const + { + return 4; + } + + int PathgridPointListAdapter::getNestedRowsCount(const Record& record) const + { + return static_cast(record.get().mPoints.size()); + } + + PathgridEdgeListAdapter::PathgridEdgeListAdapter () {} + + // ToDo: seems to be auto-sorted in the dialog table display after insertion + void PathgridEdgeListAdapter::addNestedRow(Record& record, int position) const + { + Pathgrid pathgrid = record.get(); + + ESM::Pathgrid::EdgeList& edges = pathgrid.mEdges; + + // blank row + ESM::Pathgrid::Edge edge; + edge.mV0 = 0; + edge.mV1 = 0; + + // NOTE: inserting a blank edge does not really make sense, perhaps this should be a + // logic_error exception + // + // Currently the code assumes that the end user to know what he/she is doing. + // e.g. Edges come in pairs, from points a->b and b->a + edges.insert(edges.begin()+position, edge); + + record.setModified (pathgrid); + } + + void PathgridEdgeListAdapter::removeNestedRow(Record& record, int rowToRemove) const + { + Pathgrid pathgrid = record.get(); + + ESM::Pathgrid::EdgeList& edges = pathgrid.mEdges; + + if (rowToRemove < 0 || rowToRemove >= static_cast (edges.size())) + throw std::runtime_error ("index out of range"); + + edges.erase(edges.begin()+rowToRemove); + + record.setModified (pathgrid); + } + + void PathgridEdgeListAdapter::setNestedTable(Record& record, + const NestedTableWrapperBase& nestedTable) const + { + record.get().mEdges = + static_cast &>(nestedTable).mNestedTable; + } + + NestedTableWrapperBase* PathgridEdgeListAdapter::nestedTable(const Record& record) const + { + // deleted by dtor of NestedTableStoring + return new NestedTableWrapper(record.get().mEdges); + } + + QVariant PathgridEdgeListAdapter::getNestedData(const Record& record, + int subRowIndex, int subColIndex) const + { + Pathgrid pathgrid = record.get(); + + if (subRowIndex < 0 || subRowIndex >= static_cast (pathgrid.mEdges.size())) + throw std::runtime_error ("index out of range"); + + ESM::Pathgrid::Edge edge = pathgrid.mEdges[subRowIndex]; + switch (subColIndex) + { + case 0: return subRowIndex; + case 1: return edge.mV0; + case 2: return edge.mV1; + default: throw std::runtime_error("Pathgrid edge subcolumn index out of range"); + } + } + + // ToDo: detect duplicates in mEdges + void PathgridEdgeListAdapter::setNestedData(Record& record, + const QVariant& value, int subRowIndex, int subColIndex) const + { + Pathgrid pathgrid = record.get(); + + if (subRowIndex < 0 || subRowIndex >= static_cast (pathgrid.mEdges.size())) + throw std::runtime_error ("index out of range"); + + ESM::Pathgrid::Edge edge = pathgrid.mEdges[subRowIndex]; + switch (subColIndex) + { + case 0: break; + case 1: edge.mV0 = value.toInt(); break; + case 2: edge.mV1 = value.toInt(); break; + default: throw std::runtime_error("Pathgrid edge subcolumn index out of range"); + } + + pathgrid.mEdges[subRowIndex] = edge; + + record.setModified (pathgrid); + } + + int PathgridEdgeListAdapter::getNestedColumnsCount(const Record& record) const + { + return 3; + } + + int PathgridEdgeListAdapter::getNestedRowsCount(const Record& record) const + { + return static_cast(record.get().mEdges.size()); + } + + FactionReactionsAdapter::FactionReactionsAdapter () {} + + void FactionReactionsAdapter::addNestedRow(Record& record, int position) const + { + ESM::Faction faction = record.get(); + + std::map& reactions = faction.mReactions; + + // blank row + reactions.insert(std::make_pair("", 0)); + + record.setModified (faction); + } + + void FactionReactionsAdapter::removeNestedRow(Record& record, int rowToRemove) const + { + ESM::Faction faction = record.get(); + + std::map& reactions = faction.mReactions; + + if (rowToRemove < 0 || rowToRemove >= static_cast (reactions.size())) + throw std::runtime_error ("index out of range"); + + // FIXME: how to ensure that the map entries correspond to table indicies? + // WARNING: Assumed that the table view has the same order as std::map + std::map::iterator iter = reactions.begin(); + for(int i = 0; i < rowToRemove; ++i) + iter++; + reactions.erase(iter); + + record.setModified (faction); + } + + void FactionReactionsAdapter::setNestedTable(Record& record, + const NestedTableWrapperBase& nestedTable) const + { + record.get().mReactions = + static_cast >&>(nestedTable).mNestedTable; + } + + NestedTableWrapperBase* FactionReactionsAdapter::nestedTable(const Record& record) const + { + // deleted by dtor of NestedTableStoring + return new NestedTableWrapper >(record.get().mReactions); + } + + QVariant FactionReactionsAdapter::getNestedData(const Record& record, + int subRowIndex, int subColIndex) const + { + ESM::Faction faction = record.get(); + + std::map& reactions = faction.mReactions; + + if (subRowIndex < 0 || subRowIndex >= static_cast (reactions.size())) + throw std::runtime_error ("index out of range"); + + // FIXME: how to ensure that the map entries correspond to table indicies? + // WARNING: Assumed that the table view has the same order as std::map + std::map::const_iterator iter = reactions.begin(); + for(int i = 0; i < subRowIndex; ++i) + iter++; + switch (subColIndex) + { + case 0: return QString((*iter).first.c_str()); + case 1: return (*iter).second; + default: throw std::runtime_error("Faction reactions subcolumn index out of range"); + } + } + + void FactionReactionsAdapter::setNestedData(Record& record, + const QVariant& value, int subRowIndex, int subColIndex) const + { + ESM::Faction faction = record.get(); + + std::map& reactions = faction.mReactions; + + if (subRowIndex < 0 || subRowIndex >= static_cast (reactions.size())) + throw std::runtime_error ("index out of range"); + + // FIXME: how to ensure that the map entries correspond to table indicies? + // WARNING: Assumed that the table view has the same order as std::map + std::map::iterator iter = reactions.begin(); + for(int i = 0; i < subRowIndex; ++i) + iter++; + + std::string factionId = (*iter).first; + int reaction = (*iter).second; + + switch (subColIndex) + { + case 0: + { + reactions.erase(iter); + reactions.insert(std::make_pair(value.toString().toUtf8().constData(), reaction)); + break; + } + case 1: + { + reactions[factionId] = value.toInt(); + break; + } + default: throw std::runtime_error("Faction reactions subcolumn index out of range"); + } + + record.setModified (faction); + } + + int FactionReactionsAdapter::getNestedColumnsCount(const Record& record) const + { + return 2; + } + + int FactionReactionsAdapter::getNestedRowsCount(const Record& record) const + { + return static_cast(record.get().mReactions.size()); + } + + RegionSoundListAdapter::RegionSoundListAdapter () {} + + void RegionSoundListAdapter::addNestedRow(Record& record, int position) const + { + ESM::Region region = record.get(); + + std::vector& soundList = region.mSoundList; + + // blank row + ESM::Region::SoundRef soundRef; + soundRef.mSound.assign(""); + soundRef.mChance = 0; + + soundList.insert(soundList.begin()+position, soundRef); + + record.setModified (region); + } + + void RegionSoundListAdapter::removeNestedRow(Record& record, int rowToRemove) const + { + ESM::Region region = record.get(); + + std::vector& soundList = region.mSoundList; + + if (rowToRemove < 0 || rowToRemove >= static_cast (soundList.size())) + throw std::runtime_error ("index out of range"); + + soundList.erase(soundList.begin()+rowToRemove); + + record.setModified (region); + } + + void RegionSoundListAdapter::setNestedTable(Record& record, + const NestedTableWrapperBase& nestedTable) const + { + record.get().mSoundList = + static_cast >&>(nestedTable).mNestedTable; + } + + NestedTableWrapperBase* RegionSoundListAdapter::nestedTable(const Record& record) const + { + // deleted by dtor of NestedTableStoring + return new NestedTableWrapper >(record.get().mSoundList); + } + + QVariant RegionSoundListAdapter::getNestedData(const Record& record, + int subRowIndex, int subColIndex) const + { + ESM::Region region = record.get(); + + std::vector& soundList = region.mSoundList; + + if (subRowIndex < 0 || subRowIndex >= static_cast (soundList.size())) + throw std::runtime_error ("index out of range"); + + ESM::Region::SoundRef soundRef = soundList[subRowIndex]; + switch (subColIndex) + { + case 0: return QString(soundRef.mSound.toString().c_str()); + case 1: return soundRef.mChance; + default: throw std::runtime_error("Region sounds subcolumn index out of range"); + } + } + + void RegionSoundListAdapter::setNestedData(Record& record, + const QVariant& value, int subRowIndex, int subColIndex) const + { + ESM::Region region = record.get(); + + std::vector& soundList = region.mSoundList; + + if (subRowIndex < 0 || subRowIndex >= static_cast (soundList.size())) + throw std::runtime_error ("index out of range"); + + ESM::Region::SoundRef soundRef = soundList[subRowIndex]; + switch (subColIndex) + { + case 0: soundRef.mSound.assign(value.toString().toUtf8().constData()); break; + case 1: soundRef.mChance = static_cast(value.toInt()); break; + default: throw std::runtime_error("Region sounds subcolumn index out of range"); + } + + region.mSoundList[subRowIndex] = soundRef; + + record.setModified (region); + } + + int RegionSoundListAdapter::getNestedColumnsCount(const Record& record) const + { + return 2; + } + + int RegionSoundListAdapter::getNestedRowsCount(const Record& record) const + { + return static_cast(record.get().mSoundList.size()); + } +} diff --git a/apps/opencs/model/world/idadapterimp.hpp b/apps/opencs/model/world/idadapterimp.hpp index d5bf83a2d9..effa0011c3 100644 --- a/apps/opencs/model/world/idadapterimp.hpp +++ b/apps/opencs/model/world/idadapterimp.hpp @@ -4,8 +4,6 @@ #include #include -#include -#include #include #include // for converting magic effect id to string & back #include // for converting skill names @@ -14,482 +12,129 @@ #include "idadapter.hpp" #include "nestedtablewrapper.hpp" +namespace ESM +{ + struct Faction; + struct Region; +} + namespace CSMWorld { - template - class PathgridPointListAdapter : public NestedIdAdapter + struct Pathgrid; + + struct PathgridPointsWrap : public NestedTableWrapperBase { - public: - PathgridPointListAdapter () {} + ESM::Pathgrid mRecord; - virtual void addNestedRow(Record& record, int position) const + PathgridPointsWrap(ESM::Pathgrid pathgrid) + : mRecord(pathgrid) {} + + virtual ~PathgridPointsWrap() {} + + virtual int size() const { - ESXRecordT pathgrid = record.get(); - - ESM::Pathgrid::PointList& points = pathgrid.mPoints; - - // blank row - ESM::Pathgrid::Point point; - point.mX = 0; - point.mY = 0; - point.mZ = 0; - point.mAutogenerated = 0; - point.mConnectionNum = 0; - point.mUnknown = 0; - - // inserting a point should trigger re-indexing of the edges - // - // FIXME: undo does not restore edges table view - // FIXME: does not auto refresh edges table view - std::vector::iterator iter = pathgrid.mEdges.begin(); - for (;iter != pathgrid.mEdges.end(); ++iter) - { - if ((*iter).mV0 >= position) - (*iter).mV0++; - if ((*iter).mV1 >= position) - (*iter).mV1++; - } - - points.insert(points.begin()+position, point); - pathgrid.mData.mS2 += 1; // increment the number of points - - record.setModified (pathgrid); - } - - virtual void removeNestedRow(Record& record, int rowToRemove) const - { - ESXRecordT pathgrid = record.get(); - - ESM::Pathgrid::PointList& points = pathgrid.mPoints; - - if (rowToRemove < 0 || rowToRemove >= static_cast (points.size())) - throw std::runtime_error ("index out of range"); - - // deleting a point should trigger re-indexing of the edges - // dangling edges are not allowed and hence removed - // - // FIXME: undo does not restore edges table view - // FIXME: does not auto refresh edges table view - std::vector::iterator iter = pathgrid.mEdges.begin(); - for (; iter != pathgrid.mEdges.end();) - { - if (((*iter).mV0 == rowToRemove) || ((*iter).mV1 == rowToRemove)) - iter = pathgrid.mEdges.erase(iter); - else - { - if ((*iter).mV0 > rowToRemove) - (*iter).mV0--; - - if ((*iter).mV1 > rowToRemove) - (*iter).mV1--; - - ++iter; - } - } - points.erase(points.begin()+rowToRemove); - pathgrid.mData.mS2 -= 1; // decrement the number of points - - record.setModified (pathgrid); - } - - struct PathgridPointsWrap : public NestedTableWrapperBase - { - ESM::Pathgrid mRecord; - - PathgridPointsWrap(ESM::Pathgrid pathgrid) - : mRecord(pathgrid) {} - - virtual ~PathgridPointsWrap() {} - - virtual int size() const - { - return mRecord.mPoints.size(); // used in IdTree::setNestedTable() - } - }; - - virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) const - { - record.get().mPoints = - static_cast(nestedTable).mRecord.mPoints; - record.get().mData.mS2 = - static_cast(nestedTable).mRecord.mData.mS2; - // also update edges in case points were added/removed - record.get().mEdges = - static_cast(nestedTable).mRecord.mEdges; - } - - virtual NestedTableWrapperBase* nestedTable(const Record& record) const - { - // deleted by dtor of NestedTableStoring - return new PathgridPointsWrap(record.get()); - } - - virtual QVariant getNestedData(const Record& record, int subRowIndex, int subColIndex) const - { - ESM::Pathgrid::Point point = record.get().mPoints[subRowIndex]; - switch (subColIndex) - { - case 0: return subRowIndex; - case 1: return point.mX; - case 2: return point.mY; - case 3: return point.mZ; - default: throw std::runtime_error("Pathgrid point subcolumn index out of range"); - } - } - - virtual void setNestedData(Record& record, const QVariant& value, - int subRowIndex, int subColIndex) const - { - ESXRecordT pathgrid = record.get(); - ESM::Pathgrid::Point point = pathgrid.mPoints[subRowIndex]; - switch (subColIndex) - { - case 0: break; - case 1: point.mX = value.toInt(); break; - case 2: point.mY = value.toInt(); break; - case 3: point.mZ = value.toInt(); break; - default: throw std::runtime_error("Pathgrid point subcolumn index out of range"); - } - - pathgrid.mPoints[subRowIndex] = point; - - record.setModified (pathgrid); - } - - virtual int getNestedColumnsCount(const Record& record) const - { - return 4; - } - - virtual int getNestedRowsCount(const Record& record) const - { - return static_cast(record.get().mPoints.size()); + return mRecord.mPoints.size(); // used in IdTree::setNestedTable() } }; - template - class PathgridEdgeListAdapter : public NestedIdAdapter + class PathgridPointListAdapter : public NestedIdAdapter { public: - PathgridEdgeListAdapter () {} + PathgridPointListAdapter (); - // FIXME: seems to be auto-sorted in the dialog table display after insertion - virtual void addNestedRow(Record& record, int position) const - { - ESXRecordT pathgrid = record.get(); + virtual void addNestedRow(Record& record, int position) const; - ESM::Pathgrid::EdgeList& edges = pathgrid.mEdges; + virtual void removeNestedRow(Record& record, int rowToRemove) const; - // blank row - ESM::Pathgrid::Edge edge; - edge.mV0 = 0; - edge.mV1 = 0; + virtual void setNestedTable(Record& record, + const NestedTableWrapperBase& nestedTable) const; - // NOTE: inserting a blank edge does not really make sense, perhaps this should be a - // logic_error exception - // - // Currently the code assumes that the end user to know what he/she is doing. - // e.g. Edges come in pairs, from points a->b and b->a - edges.insert(edges.begin()+position, edge); + virtual NestedTableWrapperBase* nestedTable(const Record& record) const; - record.setModified (pathgrid); - } + virtual QVariant getNestedData(const Record& record, + int subRowIndex, int subColIndex) const; - virtual void removeNestedRow(Record& record, int rowToRemove) const - { - ESXRecordT pathgrid = record.get(); + virtual void setNestedData(Record& record, + const QVariant& value, int subRowIndex, int subColIndex) const; - ESM::Pathgrid::EdgeList& edges = pathgrid.mEdges; + virtual int getNestedColumnsCount(const Record& record) const; - if (rowToRemove < 0 || rowToRemove >= static_cast (edges.size())) - throw std::runtime_error ("index out of range"); - - edges.erase(edges.begin()+rowToRemove); - - record.setModified (pathgrid); - } - - virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) const - { - record.get().mEdges = - static_cast &>(nestedTable).mNestedTable; - } - - virtual NestedTableWrapperBase* nestedTable(const Record& record) const - { - // deleted by dtor of NestedTableStoring - return new NestedTableWrapper(record.get().mEdges); - } - - virtual QVariant getNestedData(const Record& record, int subRowIndex, int subColIndex) const - { - ESXRecordT pathgrid = record.get(); - - if (subRowIndex < 0 || subRowIndex >= static_cast (pathgrid.mEdges.size())) - throw std::runtime_error ("index out of range"); - - ESM::Pathgrid::Edge edge = pathgrid.mEdges[subRowIndex]; - switch (subColIndex) - { - case 0: return subRowIndex; - case 1: return edge.mV0; - case 2: return edge.mV1; - default: throw std::runtime_error("Pathgrid edge subcolumn index out of range"); - } - } - - // FIXME: detect duplicates in mEdges - virtual void setNestedData(Record& record, const QVariant& value, - int subRowIndex, int subColIndex) const - { - ESXRecordT pathgrid = record.get(); - - if (subRowIndex < 0 || subRowIndex >= static_cast (pathgrid.mEdges.size())) - throw std::runtime_error ("index out of range"); - - ESM::Pathgrid::Edge edge = pathgrid.mEdges[subRowIndex]; - switch (subColIndex) - { - case 0: break; - case 1: edge.mV0 = value.toInt(); break; - case 2: edge.mV1 = value.toInt(); break; - default: throw std::runtime_error("Pathgrid edge subcolumn index out of range"); - } - - pathgrid.mEdges[subRowIndex] = edge; - - record.setModified (pathgrid); - } - - virtual int getNestedColumnsCount(const Record& record) const - { - return 3; - } - - virtual int getNestedRowsCount(const Record& record) const - { - return static_cast(record.get().mEdges.size()); - } + virtual int getNestedRowsCount(const Record& record) const; }; - template - class FactionReactionsAdapter : public NestedIdAdapter + class PathgridEdgeListAdapter : public NestedIdAdapter { public: - FactionReactionsAdapter () {} + PathgridEdgeListAdapter (); - virtual void addNestedRow(Record& record, int position) const - { - ESXRecordT faction = record.get(); + virtual void addNestedRow(Record& record, int position) const; - std::map& reactions = faction.mReactions; + virtual void removeNestedRow(Record& record, int rowToRemove) const; - // blank row - reactions.insert(std::make_pair("", 0)); + virtual void setNestedTable(Record& record, + const NestedTableWrapperBase& nestedTable) const; - record.setModified (faction); - } + virtual NestedTableWrapperBase* nestedTable(const Record& record) const; - virtual void removeNestedRow(Record& record, int rowToRemove) const - { - ESXRecordT faction = record.get(); + virtual QVariant getNestedData(const Record& record, + int subRowIndex, int subColIndex) const; - std::map& reactions = faction.mReactions; + virtual void setNestedData(Record& record, + const QVariant& value, int subRowIndex, int subColIndex) const; - if (rowToRemove < 0 || rowToRemove >= static_cast (reactions.size())) - throw std::runtime_error ("index out of range"); + virtual int getNestedColumnsCount(const Record& record) const; - // FIXME: how to ensure that the map entries correspond to table indicies? - // WARNING: Assumed that the table view has the same order as std::map - std::map::iterator iter = reactions.begin(); - for(int i = 0; i < rowToRemove; ++i) - iter++; - reactions.erase(iter); - - record.setModified (faction); - } - - virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) const - { - record.get().mReactions = - static_cast >&>(nestedTable).mNestedTable; - } - - virtual NestedTableWrapperBase* nestedTable(const Record& record) const - { - // deleted by dtor of NestedTableStoring - return new NestedTableWrapper >(record.get().mReactions); - } - - virtual QVariant getNestedData(const Record& record, int subRowIndex, int subColIndex) const - { - ESXRecordT faction = record.get(); - - std::map& reactions = faction.mReactions; - - if (subRowIndex < 0 || subRowIndex >= static_cast (reactions.size())) - throw std::runtime_error ("index out of range"); - - // FIXME: how to ensure that the map entries correspond to table indicies? - // WARNING: Assumed that the table view has the same order as std::map - std::map::const_iterator iter = reactions.begin(); - for(int i = 0; i < subRowIndex; ++i) - iter++; - switch (subColIndex) - { - case 0: return QString((*iter).first.c_str()); - case 1: return (*iter).second; - default: throw std::runtime_error("Faction reactions subcolumn index out of range"); - } - } - - virtual void setNestedData(Record& record, const QVariant& value, - int subRowIndex, int subColIndex) const - { - ESXRecordT faction = record.get(); - - std::map& reactions = faction.mReactions; - - if (subRowIndex < 0 || subRowIndex >= static_cast (reactions.size())) - throw std::runtime_error ("index out of range"); - - // FIXME: how to ensure that the map entries correspond to table indicies? - // WARNING: Assumed that the table view has the same order as std::map - std::map::iterator iter = reactions.begin(); - for(int i = 0; i < subRowIndex; ++i) - iter++; - - std::string factionId = (*iter).first; - int reaction = (*iter).second; - - switch (subColIndex) - { - case 0: - { - reactions.erase(iter); - reactions.insert(std::make_pair(value.toString().toUtf8().constData(), reaction)); - break; - } - case 1: - { - reactions[factionId] = value.toInt(); - break; - } - default: throw std::runtime_error("Faction reactions subcolumn index out of range"); - } - - record.setModified (faction); - } - - virtual int getNestedColumnsCount(const Record& record) const - { - return 2; - } - - virtual int getNestedRowsCount(const Record& record) const - { - return static_cast(record.get().mReactions.size()); - } + virtual int getNestedRowsCount(const Record& record) const; }; - template - class RegionSoundListAdapter : public NestedIdAdapter + class FactionReactionsAdapter : public NestedIdAdapter { public: - RegionSoundListAdapter () {} + FactionReactionsAdapter (); - virtual void addNestedRow(Record& record, int position) const - { - ESXRecordT region = record.get(); + virtual void addNestedRow(Record& record, int position) const; - std::vector& soundList = region.mSoundList; + virtual void removeNestedRow(Record& record, int rowToRemove) const; - // blank row - typename ESXRecordT::SoundRef soundRef; - soundRef.mSound.assign(""); - soundRef.mChance = 0; + virtual void setNestedTable(Record& record, + const NestedTableWrapperBase& nestedTable) const; - soundList.insert(soundList.begin()+position, soundRef); + virtual NestedTableWrapperBase* nestedTable(const Record& record) const; - record.setModified (region); - } + virtual QVariant getNestedData(const Record& record, + int subRowIndex, int subColIndex) const; - virtual void removeNestedRow(Record& record, int rowToRemove) const - { - ESXRecordT region = record.get(); + virtual void setNestedData(Record& record, + const QVariant& value, int subRowIndex, int subColIndex) const; - std::vector& soundList = region.mSoundList; + virtual int getNestedColumnsCount(const Record& record) const; - if (rowToRemove < 0 || rowToRemove >= static_cast (soundList.size())) - throw std::runtime_error ("index out of range"); + virtual int getNestedRowsCount(const Record& record) const; + }; - soundList.erase(soundList.begin()+rowToRemove); + class RegionSoundListAdapter : public NestedIdAdapter + { + public: + RegionSoundListAdapter (); - record.setModified (region); - } + virtual void addNestedRow(Record& record, int position) const; - virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) const - { - record.get().mSoundList = - static_cast >&>(nestedTable).mNestedTable; - } + virtual void removeNestedRow(Record& record, int rowToRemove) const; - virtual NestedTableWrapperBase* nestedTable(const Record& record) const - { - // deleted by dtor of NestedTableStoring - return new NestedTableWrapper >(record.get().mSoundList); - } + virtual void setNestedTable(Record& record, + const NestedTableWrapperBase& nestedTable) const; - virtual QVariant getNestedData(const Record& record, int subRowIndex, int subColIndex) const - { - ESXRecordT region = record.get(); + virtual NestedTableWrapperBase* nestedTable(const Record& record) const; - std::vector& soundList = region.mSoundList; + virtual QVariant getNestedData(const Record& record, + int subRowIndex, int subColIndex) const; - if (subRowIndex < 0 || subRowIndex >= static_cast (soundList.size())) - throw std::runtime_error ("index out of range"); + virtual void setNestedData(Record& record, + const QVariant& value, int subRowIndex, int subColIndex) const; - typename ESXRecordT::SoundRef soundRef = soundList[subRowIndex]; - switch (subColIndex) - { - case 0: return QString(soundRef.mSound.toString().c_str()); - case 1: return soundRef.mChance; - default: throw std::runtime_error("Region sounds subcolumn index out of range"); - } - } + virtual int getNestedColumnsCount(const Record& record) const; - virtual void setNestedData(Record& record, const QVariant& value, - int subRowIndex, int subColIndex) const - { - ESXRecordT region = record.get(); - - std::vector& soundList = region.mSoundList; - - if (subRowIndex < 0 || subRowIndex >= static_cast (soundList.size())) - throw std::runtime_error ("index out of range"); - - typename ESXRecordT::SoundRef soundRef = soundList[subRowIndex]; - switch (subColIndex) - { - case 0: soundRef.mSound.assign(value.toString().toUtf8().constData()); break; - case 1: soundRef.mChance = static_cast(value.toInt()); break; - default: throw std::runtime_error("Region sounds subcolumn index out of range"); - } - - region.mSoundList[subRowIndex] = soundRef; - - record.setModified (region); - } - - virtual int getNestedColumnsCount(const Record& record) const - { - return 2; - } - - virtual int getNestedRowsCount(const Record& record) const - { - return static_cast(record.get().mSoundList.size()); - } + virtual int getNestedRowsCount(const Record& record) const; }; template From ef84e553beb94cd6ee56ff270dca6a182cc34331 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sun, 12 Apr 2015 13:48:23 +1000 Subject: [PATCH 124/185] Renamed some stuff. --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/world/data.cpp | 166 +++++++++--------- ...adapterimp.cpp => nestedcoladapterimp.cpp} | 2 +- ...adapterimp.hpp => nestedcoladapterimp.hpp} | 20 +-- ...{idadapter.hpp => nestedcolumnadapter.hpp} | 17 +- .../opencs/model/world/nestedidcollection.hpp | 21 ++- 6 files changed, 114 insertions(+), 114 deletions(-) rename apps/opencs/model/world/{idadapterimp.cpp => nestedcoladapterimp.cpp} (99%) rename apps/opencs/model/world/{idadapterimp.hpp => nestedcoladapterimp.hpp} (96%) rename apps/opencs/model/world/{idadapter.hpp => nestedcolumnadapter.hpp} (77%) diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index bc0b964ae7..babd3363fe 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -25,7 +25,7 @@ opencs_units (model/world opencs_units_noqt (model/world universalid record commands columnbase scriptcontext cell refidcollection refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope - pathgrid landtexture land nestedtablewrapper nestedadapters nestedcollection idadapterimp + pathgrid landtexture land nestedtablewrapper nestedadapters nestedcollection nestedcoladapterimp ) opencs_hdrs_noqt (model/world diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index db644affa6..d7280e354b 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -18,7 +18,7 @@ #include "columns.hpp" #include "resourcesmanager.hpp" #include "resourcetable.hpp" -#include "idadapterimp.hpp" +#include "nestedcoladapterimp.hpp" void CSMWorld::Data::addModel (QAbstractItemModel *model, UniversalId::Type type, bool update) { @@ -64,6 +64,8 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc : mEncoder (encoding), mPathgrids (mCells), mRefs (mCells), mResourcesManager (resourcesManager), mReader (0), mDialogue (0), mReaderIndex(0) { + int index = 0; + mGlobals.addColumn (new StringIdColumn); mGlobals.addColumn (new RecordStateColumn); mGlobals.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Global)); @@ -109,14 +111,13 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc for (int i=0; i<7; ++i) mFactions.addColumn (new SkillsColumn (i)); // Faction Reactions - NestedParentColumn *reactions = - new NestedParentColumn (Columns::ColumnId_FactionReactions); - mFactions.addColumn (reactions); - mFactions.addAdapter (std::make_pair(reactions, new FactionReactionsAdapter ())); - mFactions.getNestableColumn(mFactions.getColumns()-1)->addColumn( - new NestedChildColumn (Columns::ColumnId_Faction, ColumnBase::Display_String)); - mFactions.getNestableColumn(mFactions.getColumns()-1)->addColumn( - new NestedChildColumn (Columns::ColumnId_FactionReaction, ColumnBase::Display_Integer)); + mFactions.addColumn (new NestedParentColumn (Columns::ColumnId_FactionReactions)); + index = mFactions.getColumns()-1; + mFactions.addAdapter (std::make_pair(&mFactions.getColumn(index), new FactionReactionsAdapter ())); + mFactions.getNestableColumn(index)->addColumn( + new NestedChildColumn (Columns::ColumnId_Faction, ColumnBase::Display_String)); + mFactions.getNestableColumn(index)->addColumn( + new NestedChildColumn (Columns::ColumnId_FactionReaction, ColumnBase::Display_Integer)); mRaces.addColumn (new StringIdColumn); mRaces.addColumn (new RecordStateColumn); @@ -130,12 +131,11 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mRaces.addColumn (new WeightHeightColumn (false, true)); mRaces.addColumn (new WeightHeightColumn (false, false)); // Race spells - NestedParentColumn *raceSpells = - new NestedParentColumn (Columns::ColumnId_SpellList); - mRaces.addColumn (raceSpells); - mRaces.addAdapter (std::make_pair(raceSpells, new SpellListAdapter ())); - mRaces.getNestableColumn(mRaces.getColumns()-1)->addColumn( - new NestedChildColumn (Columns::ColumnId_SpellId, ColumnBase::Display_String)); + mRaces.addColumn (new NestedParentColumn (Columns::ColumnId_SpellList)); + index = mRaces.getColumns()-1; + mRaces.addAdapter (std::make_pair(&mRaces.getColumn(index), new SpellListAdapter ())); + mRaces.getNestableColumn(index)->addColumn( + new NestedChildColumn (Columns::ColumnId_SpellId, ColumnBase::Display_String)); mSounds.addColumn (new StringIdColumn); mSounds.addColumn (new RecordStateColumn); @@ -157,14 +157,13 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mRegions.addColumn (new MapColourColumn); mRegions.addColumn (new SleepListColumn); // Region Sounds - NestedParentColumn *soundList = - new NestedParentColumn (Columns::ColumnId_RegionSounds); - mRegions.addColumn (soundList); - mRegions.addAdapter (std::make_pair(soundList, new RegionSoundListAdapter ())); - mRegions.getNestableColumn(mRegions.getColumns()-1)->addColumn( - new NestedChildColumn (Columns::ColumnId_SoundName, ColumnBase::Display_String)); - mRegions.getNestableColumn(mRegions.getColumns()-1)->addColumn( - new NestedChildColumn (Columns::ColumnId_SoundChance, ColumnBase::Display_Integer)); + mRegions.addColumn (new NestedParentColumn (Columns::ColumnId_RegionSounds)); + index = mRegions.getColumns()-1; + mRegions.addAdapter (std::make_pair(&mRegions.getColumn(index), new RegionSoundListAdapter ())); + mRegions.getNestableColumn(index)->addColumn( + new NestedChildColumn (Columns::ColumnId_SoundName, ColumnBase::Display_String)); + mRegions.getNestableColumn(index)->addColumn( + new NestedChildColumn (Columns::ColumnId_SoundChance, ColumnBase::Display_Integer)); mBirthsigns.addColumn (new StringIdColumn); mBirthsigns.addColumn (new RecordStateColumn); @@ -173,12 +172,12 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mBirthsigns.addColumn (new TextureColumn); mBirthsigns.addColumn (new DescriptionColumn); // Birthsign spells - NestedParentColumn *birthSpells = - new NestedParentColumn (Columns::ColumnId_SpellList); - mBirthsigns.addColumn (birthSpells); - mBirthsigns.addAdapter (std::make_pair(birthSpells, new SpellListAdapter ())); - mBirthsigns.getNestableColumn(mBirthsigns.getColumns()-1)->addColumn( - new NestedChildColumn (Columns::ColumnId_SpellId, ColumnBase::Display_String)); + mBirthsigns.addColumn (new NestedParentColumn (Columns::ColumnId_SpellList)); + index = mBirthsigns.getColumns()-1; + mBirthsigns.addAdapter (std::make_pair(&mBirthsigns.getColumn(index), + new SpellListAdapter ())); + mBirthsigns.getNestableColumn(index)->addColumn( + new NestedChildColumn (Columns::ColumnId_SpellId, ColumnBase::Display_String)); mSpells.addColumn (new StringIdColumn); mSpells.addColumn (new RecordStateColumn); @@ -190,26 +189,25 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mSpells.addColumn (new FlagColumn (Columns::ColumnId_StarterSpell, 0x2)); mSpells.addColumn (new FlagColumn (Columns::ColumnId_AlwaysSucceeds, 0x4)); // Spell effects - NestedParentColumn *spellEffect = - new NestedParentColumn (Columns::ColumnId_EffectList); - mSpells.addColumn (spellEffect); - mSpells.addAdapter (std::make_pair(spellEffect, new EffectsListAdapter ())); - mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( - new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_String/*, false*/)); // false means no edit - mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( - new NestedChildColumn (Columns::ColumnId_Skill, ColumnBase::Display_String)); - mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( - new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_String)); // reuse attribute - mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( - new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_Integer)); - mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( - new NestedChildColumn (Columns::ColumnId_EffectArea, ColumnBase::Display_String)); - mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( - new NestedChildColumn (Columns::ColumnId_Duration, ColumnBase::Display_Integer)); // reuse from light - mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( - new NestedChildColumn (Columns::ColumnId_MinRange, ColumnBase::Display_Integer)); // reuse from sound - mSpells.getNestableColumn(mSpells.getColumns()-1)->addColumn( - new NestedChildColumn (Columns::ColumnId_MaxRange, ColumnBase::Display_Integer)); // reuse from sound + mSpells.addColumn (new NestedParentColumn (Columns::ColumnId_EffectList)); + index = mSpells.getColumns()-1; + mSpells.addAdapter (std::make_pair(&mSpells.getColumn(index), new EffectsListAdapter ())); + mSpells.getNestableColumn(index)->addColumn( + new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_String/*, false*/)); // false means no edit + mSpells.getNestableColumn(index)->addColumn( + new NestedChildColumn (Columns::ColumnId_Skill, ColumnBase::Display_String)); + mSpells.getNestableColumn(index)->addColumn( + new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_String)); // reuse attribute + mSpells.getNestableColumn(index)->addColumn( + new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_Integer)); + mSpells.getNestableColumn(index)->addColumn( + new NestedChildColumn (Columns::ColumnId_EffectArea, ColumnBase::Display_String)); + mSpells.getNestableColumn(index)->addColumn( + new NestedChildColumn (Columns::ColumnId_Duration, ColumnBase::Display_Integer)); // reuse from light + mSpells.getNestableColumn(index)->addColumn( + new NestedChildColumn (Columns::ColumnId_MinRange, ColumnBase::Display_Integer)); // reuse from sound + mSpells.getNestableColumn(index)->addColumn( + new NestedChildColumn (Columns::ColumnId_MaxRange, ColumnBase::Display_Integer)); // reuse from sound mTopics.addColumn (new StringIdColumn); mTopics.addColumn (new RecordStateColumn); @@ -264,26 +262,26 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mEnchantments.addColumn (new ChargesColumn2); mEnchantments.addColumn (new AutoCalcColumn); // Enchantment effects - NestedParentColumn *enchantmentEffect = - new NestedParentColumn (Columns::ColumnId_EffectList); - mEnchantments.addColumn (enchantmentEffect); - mEnchantments.addAdapter (std::make_pair(enchantmentEffect, new EffectsListAdapter ())); - mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( - new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_String/*, false*/)); - mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( - new NestedChildColumn (Columns::ColumnId_Skill, ColumnBase::Display_String)); - mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( - new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_String)); // reuse attribute - mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( - new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_Integer)); - mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( - new NestedChildColumn (Columns::ColumnId_EffectArea, ColumnBase::Display_String)); - mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( - new NestedChildColumn (Columns::ColumnId_Duration, ColumnBase::Display_Integer)); // reuse from light - mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( - new NestedChildColumn (Columns::ColumnId_MinRange, ColumnBase::Display_Integer)); // reuse from sound - mEnchantments.getNestableColumn(mEnchantments.getColumns()-1)->addColumn( - new NestedChildColumn (Columns::ColumnId_MaxRange, ColumnBase::Display_Integer)); // reuse from sound + mEnchantments.addColumn (new NestedParentColumn (Columns::ColumnId_EffectList)); + index = mEnchantments.getColumns()-1; + mEnchantments.addAdapter (std::make_pair(&mEnchantments.getColumn(index), + new EffectsListAdapter ())); + mEnchantments.getNestableColumn(index)->addColumn( + new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_String/*, false*/)); + mEnchantments.getNestableColumn(index)->addColumn( + new NestedChildColumn (Columns::ColumnId_Skill, ColumnBase::Display_String)); + mEnchantments.getNestableColumn(index)->addColumn( + new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_String)); // reuse attribute + mEnchantments.getNestableColumn(index)->addColumn( + new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_Integer)); + mEnchantments.getNestableColumn(index)->addColumn( + new NestedChildColumn (Columns::ColumnId_EffectArea, ColumnBase::Display_String)); + mEnchantments.getNestableColumn(index)->addColumn( + new NestedChildColumn (Columns::ColumnId_Duration, ColumnBase::Display_Integer)); // reuse from light + mEnchantments.getNestableColumn(index)->addColumn( + new NestedChildColumn (Columns::ColumnId_MinRange, ColumnBase::Display_Integer)); // reuse from sound + mEnchantments.getNestableColumn(index)->addColumn( + new NestedChildColumn (Columns::ColumnId_MaxRange, ColumnBase::Display_Integer)); // reuse from sound mBodyParts.addColumn (new StringIdColumn); mBodyParts.addColumn (new RecordStateColumn); @@ -331,31 +329,29 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mPathgrids.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Pathgrid)); // new object deleted in dtor of Collection - NestedParentColumn *pointList = - new NestedParentColumn (Columns::ColumnId_PathgridPoints); - mPathgrids.addColumn (pointList); - // new object deleted in dtor of SubCellCollection - mPathgrids.addAdapter (std::make_pair(pointList, new PathgridPointListAdapter ())); + mPathgrids.addColumn (new NestedParentColumn (Columns::ColumnId_PathgridPoints)); + index = mPathgrids.getColumns()-1; + // new object deleted in dtor of NestedCollection + mPathgrids.addAdapter (std::make_pair(&mPathgrids.getColumn(index), new PathgridPointListAdapter ())); // new objects deleted in dtor of NestableColumn // WARNING: The order of the columns below are assumed in PathgridPointListAdapter - mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn( + mPathgrids.getNestableColumn(index)->addColumn( new NestedChildColumn (Columns::ColumnId_PathgridIndex, ColumnBase::Display_Integer, false)); - mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn( + mPathgrids.getNestableColumn(index)->addColumn( new NestedChildColumn (Columns::ColumnId_PathgridPosX, ColumnBase::Display_Integer)); - mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn( + mPathgrids.getNestableColumn(index)->addColumn( new NestedChildColumn (Columns::ColumnId_PathgridPosY, ColumnBase::Display_Integer)); - mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn( + mPathgrids.getNestableColumn(index)->addColumn( new NestedChildColumn (Columns::ColumnId_PathgridPosZ, ColumnBase::Display_Integer)); - NestedParentColumn *edgeList = - new NestedParentColumn (Columns::ColumnId_PathgridEdges); - mPathgrids.addColumn (edgeList); - mPathgrids.addAdapter (std::make_pair(edgeList, new PathgridEdgeListAdapter ())); - mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn( + mPathgrids.addColumn (new NestedParentColumn (Columns::ColumnId_PathgridEdges)); + index = mPathgrids.getColumns()-1; + mPathgrids.addAdapter (std::make_pair(&mPathgrids.getColumn(index), new PathgridEdgeListAdapter ())); + mPathgrids.getNestableColumn(index)->addColumn( new NestedChildColumn (Columns::ColumnId_PathgridEdgeIndex, ColumnBase::Display_Integer, false)); - mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn( + mPathgrids.getNestableColumn(index)->addColumn( new NestedChildColumn (Columns::ColumnId_PathgridEdge0, ColumnBase::Display_Integer)); - mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn( + mPathgrids.getNestableColumn(index)->addColumn( new NestedChildColumn (Columns::ColumnId_PathgridEdge1, ColumnBase::Display_Integer)); mStartScripts.addColumn (new StringIdColumn); diff --git a/apps/opencs/model/world/idadapterimp.cpp b/apps/opencs/model/world/nestedcoladapterimp.cpp similarity index 99% rename from apps/opencs/model/world/idadapterimp.cpp rename to apps/opencs/model/world/nestedcoladapterimp.cpp index 95e68e09ed..2bf1ffadd1 100644 --- a/apps/opencs/model/world/idadapterimp.cpp +++ b/apps/opencs/model/world/nestedcoladapterimp.cpp @@ -1,4 +1,4 @@ -#include "idadapterimp.hpp" +#include "nestedcoladapterimp.hpp" #include #include diff --git a/apps/opencs/model/world/idadapterimp.hpp b/apps/opencs/model/world/nestedcoladapterimp.hpp similarity index 96% rename from apps/opencs/model/world/idadapterimp.hpp rename to apps/opencs/model/world/nestedcoladapterimp.hpp index effa0011c3..7fed74868c 100644 --- a/apps/opencs/model/world/idadapterimp.hpp +++ b/apps/opencs/model/world/nestedcoladapterimp.hpp @@ -1,5 +1,5 @@ -#ifndef CSM_WOLRD_IDADAPTERIMP_H -#define CSM_WOLRD_IDADAPTERIMP_H +#ifndef CSM_WOLRD_NESTEDCOLADAPTERIMP_H +#define CSM_WOLRD_NESTEDCOLADAPTERIMP_H #include @@ -9,7 +9,7 @@ #include // for converting skill names #include // for converting attributes -#include "idadapter.hpp" +#include "nestedcolumnadapter.hpp" #include "nestedtablewrapper.hpp" namespace ESM @@ -37,7 +37,7 @@ namespace CSMWorld } }; - class PathgridPointListAdapter : public NestedIdAdapter + class PathgridPointListAdapter : public NestedColumnAdapter { public: PathgridPointListAdapter (); @@ -62,7 +62,7 @@ namespace CSMWorld virtual int getNestedRowsCount(const Record& record) const; }; - class PathgridEdgeListAdapter : public NestedIdAdapter + class PathgridEdgeListAdapter : public NestedColumnAdapter { public: PathgridEdgeListAdapter (); @@ -87,7 +87,7 @@ namespace CSMWorld virtual int getNestedRowsCount(const Record& record) const; }; - class FactionReactionsAdapter : public NestedIdAdapter + class FactionReactionsAdapter : public NestedColumnAdapter { public: FactionReactionsAdapter (); @@ -112,7 +112,7 @@ namespace CSMWorld virtual int getNestedRowsCount(const Record& record) const; }; - class RegionSoundListAdapter : public NestedIdAdapter + class RegionSoundListAdapter : public NestedColumnAdapter { public: RegionSoundListAdapter (); @@ -138,7 +138,7 @@ namespace CSMWorld }; template - class SpellListAdapter : public NestedIdAdapter + class SpellListAdapter : public NestedColumnAdapter { public: SpellListAdapter () {} @@ -234,7 +234,7 @@ namespace CSMWorld }; template - class EffectsListAdapter : public NestedIdAdapter + class EffectsListAdapter : public NestedColumnAdapter { public: EffectsListAdapter () {} @@ -476,4 +476,4 @@ namespace CSMWorld }; } -#endif // CSM_WOLRD_IDADAPTERIMP_H +#endif // CSM_WOLRD_NESTEDCOLADAPTERIMP_H diff --git a/apps/opencs/model/world/idadapter.hpp b/apps/opencs/model/world/nestedcolumnadapter.hpp similarity index 77% rename from apps/opencs/model/world/idadapter.hpp rename to apps/opencs/model/world/nestedcolumnadapter.hpp index 84ef2d1f81..e7e66ed4d4 100644 --- a/apps/opencs/model/world/idadapter.hpp +++ b/apps/opencs/model/world/nestedcolumnadapter.hpp @@ -1,7 +1,5 @@ -#ifndef CSM_WOLRD_IDADAPTER_H -#define CSM_WOLRD_IDADAPTER_H - -#include "record.hpp" +#ifndef CSM_WOLRD_NESTEDCOLUMNADAPTER_H +#define CSM_WOLRD_NESTEDCOLUMNADAPTER_H class QVariant; @@ -9,14 +7,17 @@ namespace CSMWorld { struct NestedTableWrapperBase; + template + struct Record; + template - class NestedIdAdapter + class NestedColumnAdapter { public: - NestedIdAdapter() {} + NestedColumnAdapter() {} - virtual ~NestedIdAdapter() {} + virtual ~NestedColumnAdapter() {} virtual void addNestedRow(Record& record, int position) const = 0; @@ -36,4 +37,4 @@ namespace CSMWorld }; } -#endif // CSM_WOLRD_IDADAPTER_H +#endif // CSM_WOLRD_NESTEDCOLUMNADAPTER_H diff --git a/apps/opencs/model/world/nestedidcollection.hpp b/apps/opencs/model/world/nestedidcollection.hpp index c7e840955b..0cf51b9d89 100644 --- a/apps/opencs/model/world/nestedidcollection.hpp +++ b/apps/opencs/model/world/nestedidcollection.hpp @@ -5,7 +5,7 @@ #include #include "nestedcollection.hpp" -#include "idadapterimp.hpp" +#include "nestedcoladapterimp.hpp" namespace ESM { @@ -23,9 +23,9 @@ namespace CSMWorld template > class NestedIdCollection : public IdCollection, public NestedCollection { - std::map* > mAdapters; + std::map* > mAdapters; - const NestedIdAdapter& getAdapter(const ColumnBase &column) const; + const NestedColumnAdapter& getAdapter(const ColumnBase &column) const; public: @@ -51,7 +51,7 @@ namespace CSMWorld // this method is inherited from NestedCollection, not from Collection virtual NestableColumn *getNestableColumn(int column); - void addAdapter(std::pair* > adapter); + void addAdapter(std::pair* > adapter); }; template @@ -61,21 +61,24 @@ namespace CSMWorld template NestedIdCollection::~NestedIdCollection() { - for (typename std::map* >::iterator iter (mAdapters.begin()); - iter!=mAdapters.end(); ++iter) + for (typename std::map* >::iterator + iter (mAdapters.begin()); iter!=mAdapters.end(); ++iter) + { delete (*iter).second; + } } template - void NestedIdCollection::addAdapter(std::pair* > adapter) + void NestedIdCollection::addAdapter(std::pair* > adapter) { mAdapters.insert(adapter); } template - const NestedIdAdapter& NestedIdCollection::getAdapter(const ColumnBase &column) const + const NestedColumnAdapter& NestedIdCollection::getAdapter(const ColumnBase &column) const { - typename std::map* >::const_iterator iter = + typename std::map* >::const_iterator iter = mAdapters.find (&column); if (iter==mAdapters.end()) From 25261a60e58557c8beb749550008bda42edcad1a Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sun, 12 Apr 2015 18:29:42 +1000 Subject: [PATCH 125/185] Add potion magic effects table to dialogue subview. Integration of the adapters to RefIdCollection is incomplete. --- apps/opencs/model/world/refidadapter.hpp | 22 +++-- apps/opencs/model/world/refidadapterimp.cpp | 10 ++- apps/opencs/model/world/refidadapterimp.hpp | 93 +++++++++++++++++++- apps/opencs/model/world/refidcollection.cpp | 95 ++++++++++++++++++++- apps/opencs/model/world/refidcollection.hpp | 6 ++ 5 files changed, 213 insertions(+), 13 deletions(-) diff --git a/apps/opencs/model/world/refidadapter.hpp b/apps/opencs/model/world/refidadapter.hpp index 1a3f2700e3..f80ce7ab38 100644 --- a/apps/opencs/model/world/refidadapter.hpp +++ b/apps/opencs/model/world/refidadapter.hpp @@ -45,7 +45,7 @@ namespace CSMWorld virtual std::string getId (const RecordBase& record) const = 0; - virtual void setId(RecordBase& record, const std::string& id) = 0; // FIXME: used by RefIdCollection::cloneRecord() + virtual void setId(RecordBase& record, const std::string& id) = 0; // used by RefIdCollection::cloneRecord() }; class NestedRefIdAdapterBase @@ -55,23 +55,27 @@ namespace CSMWorld virtual ~NestedRefIdAdapterBase(); - virtual void setNestedData (const RefIdColumn *column, RefIdData& data, int row, - const QVariant& value, int subRowIndex, int subColIndex) const = 0; + virtual void setNestedData (const RefIdColumn *column, + RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const = 0; - virtual QVariant getNestedData (const RefIdColumn *column, const RefIdData& data, - int index, int subRowIndex, int subColIndex) const = 0; + virtual QVariant getNestedData (const RefIdColumn *column, + const RefIdData& data, int index, int subRowIndex, int subColIndex) const = 0; virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const = 0; virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const = 0; - virtual void removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, int rowToRemove) const = 0; + virtual void removeNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int rowToRemove) const = 0; - virtual void addNestedRow (const RefIdColumn *column, RefIdData& data, int index, int position) const = 0; + virtual void addNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int position) const = 0; - virtual void setNestedTable (const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const = 0; + virtual void setNestedTable (const RefIdColumn* column, + RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const = 0; - virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, const RefIdData& data, int index) const = 0; + virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, + const RefIdData& data, int index) const = 0; }; class NestedRefIdAdapter : public NestedRefIdAdapterBase diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index b2a08e71c8..426bfe3d1e 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -7,10 +7,13 @@ #include #include "nestedtablewrapper.hpp" -CSMWorld::PotionRefIdAdapter::PotionRefIdAdapter (const InventoryColumns& columns, +CSMWorld::PotionColumns::PotionColumns (const InventoryColumns& columns) +: InventoryColumns (columns) {} + +CSMWorld::PotionRefIdAdapter::PotionRefIdAdapter (const PotionColumns& columns, const RefIdColumn *autoCalc) : InventoryRefIdAdapter (UniversalId::Type_Potion, columns), - mAutoCalc (autoCalc) + mAutoCalc (autoCalc), mColumns(columns) {} QVariant CSMWorld::PotionRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, @@ -22,6 +25,9 @@ QVariant CSMWorld::PotionRefIdAdapter::getData (const RefIdColumn *column, const if (column==mAutoCalc) return record.get().mData.mAutoCalc!=0; + if (column==mColumns.mEffects) + return true; // Required to show nested tables in dialogue subview + return InventoryRefIdAdapter::getData (column, data, index); } diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 7296b6c682..b12d0cb6f0 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -6,6 +6,7 @@ #include #include +#include #include #include "record.hpp" @@ -315,13 +316,21 @@ namespace CSMWorld record.setModified(record2); } + struct PotionColumns : public InventoryColumns + { + const RefIdColumn *mEffects; + + PotionColumns (const InventoryColumns& columns); + }; + class PotionRefIdAdapter : public InventoryRefIdAdapter { + PotionColumns mColumns; const RefIdColumn *mAutoCalc; public: - PotionRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *autoCalc); + PotionRefIdAdapter (const PotionColumns& columns, const RefIdColumn *autoCalc); virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) const; @@ -828,6 +837,88 @@ namespace CSMWorld const QVariant& value) const; ///< If the data type does not match an exception is thrown. }; + + class NestedRefIdAdapterBase; + + template + class EffectsListAdapter; + + template + class EffectsRefIdAdapter : public EffectsListAdapter, public NestedRefIdAdapterBase + { + UniversalId::Type mType; + + // not implemented + EffectsRefIdAdapter (const EffectsRefIdAdapter&); + EffectsRefIdAdapter& operator= (const EffectsRefIdAdapter&); + + public: + + EffectsRefIdAdapter(UniversalId::Type type) :mType(type) {} + + virtual ~EffectsRefIdAdapter() {} + + virtual void addNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int position) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + EffectsListAdapter::addNestedRow(record, position); + } + + virtual void removeNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int rowToRemove) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + EffectsListAdapter::removeNestedRow(record, rowToRemove); + } + + virtual void setNestedTable (const RefIdColumn* column, + RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + EffectsListAdapter::setNestedTable(record, nestedTable); + } + + virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, + const RefIdData& data, int index) const + { + const Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + return EffectsListAdapter::nestedTable(record); + } + + virtual QVariant getNestedData (const RefIdColumn *column, + const RefIdData& data, int index, int subRowIndex, int subColIndex) const + { + const Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + return EffectsListAdapter::getNestedData(record, subRowIndex, subColIndex); + } + + virtual void setNestedData (const RefIdColumn *column, + RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); + EffectsListAdapter::setNestedData(record, value, subRowIndex, subColIndex); + } + + virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const + { + const Record record; + return EffectsListAdapter::getNestedColumnsCount(record); + } + + virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const + { + const Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + return EffectsListAdapter::getNestedRowsCount(record); + } + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 392a1677e1..929a3b245e 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -9,6 +9,7 @@ #include "refidadapterimp.hpp" #include "columns.hpp" #include "nestedtablewrapper.hpp" +#include "nestedcoladapterimp.hpp" CSMWorld::RefIdColumn::RefIdColumn (int columnId, Display displayType, int flag, bool editable, bool userEditable) @@ -70,6 +71,29 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn (Columns::ColumnId_CoinValue, ColumnBase::Display_Integer)); inventoryColumns.mValue = &mColumns.back(); + // nested table + PotionColumns potionColumns (inventoryColumns); + mColumns.push_back (RefIdColumn (Columns::ColumnId_EffectList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); + potionColumns.mEffects = &mColumns.back(); // see refidadapterimp.hpp + mNestedAdapters.insert (std::make_pair(&mColumns.back(), + new EffectsRefIdAdapter (UniversalId::Type_Potion))); + mColumns.back().addColumn( + new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_String/*, false*/)); + mColumns.back().addColumn( + new NestedChildColumn (Columns::ColumnId_Skill, ColumnBase::Display_String)); + mColumns.back().addColumn( + new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_String)); // reuse attribute + mColumns.back().addColumn( + new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_Integer)); + mColumns.back().addColumn( + new NestedChildColumn (Columns::ColumnId_EffectArea, ColumnBase::Display_String)); + mColumns.back().addColumn( + new NestedChildColumn (Columns::ColumnId_Duration, ColumnBase::Display_Integer)); // reuse from light + mColumns.back().addColumn( + new NestedChildColumn (Columns::ColumnId_MinRange, ColumnBase::Display_Integer)); // reuse from sound + mColumns.back().addColumn( + new NestedChildColumn (Columns::ColumnId_MaxRange, ColumnBase::Display_Integer)); // reuse from sound + EnchantableColumns enchantableColumns (inventoryColumns); mColumns.push_back (RefIdColumn (Columns::ColumnId_Enchantment, ColumnBase::Display_String)); @@ -385,7 +409,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, - new PotionRefIdAdapter (inventoryColumns, autoCalc))); + new PotionRefIdAdapter (potionColumns, autoCalc))); mAdapters.insert (std::make_pair (UniversalId::Type_Apparatus, new ApparatusRefIdAdapter (inventoryColumns, apparatusType, toolsColumns.mQuality))); mAdapters.insert (std::make_pair (UniversalId::Type_Armor, @@ -430,6 +454,10 @@ CSMWorld::RefIdCollection::~RefIdCollection() for (std::map::iterator iter (mAdapters.begin()); iter!=mAdapters.end(); ++iter) delete iter->second; + + for (std::map::iterator iter (mNestedAdapters.begin()); + iter!=mNestedAdapters.end(); ++iter) + delete iter->second; } int CSMWorld::RefIdCollection::getSize() const @@ -475,6 +503,12 @@ QVariant CSMWorld::RefIdCollection::getNestedData (int row, int column, int subR { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(row); + const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column)); + if (nestedAdapter) + { + return nestedAdapter->getNestedData(&mColumns.at (column), mData, localIndex.first, subRow, subColumn); + } + const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdapter (localIndex.second)); return adaptor.getNestedData (&mColumns.at (column), mData, localIndex.first, subRow, subColumn); @@ -493,6 +527,13 @@ void CSMWorld::RefIdCollection::setNestedData(int row, int column, const QVarian { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column)); + if (nestedAdapter) + { + nestedAdapter->setNestedData(&mColumns.at (column), mData, localIndex.first, data, subRow, subColumn); + return; + } + const RefIdAdapter& adaptor = findAdapter (localIndex.second); dynamic_cast(adaptor).setNestedData (&mColumns.at (column), mData, localIndex.first, data, subRow, subColumn); @@ -507,6 +548,13 @@ void CSMWorld::RefIdCollection::removeNestedRows(int row, int column, int subRow { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column)); + if (nestedAdapter) + { + nestedAdapter->removeNestedRow(&mColumns.at (column), mData, localIndex.first, subRow); + return; + } + const RefIdAdapter& adaptor = findAdapter (localIndex.second); dynamic_cast(adaptor).removeNestedRow(&mColumns.at (column), mData, localIndex.first, subRow); @@ -651,6 +699,12 @@ int CSMWorld::RefIdCollection::getNestedRowsCount(int row, int column) const { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column)); + if (nestedAdapter) + { + return nestedAdapter->getNestedRowsCount(&mColumns.at(column), mData, localIndex.first); + } + const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdapter (localIndex.second)); return adaptor.getNestedRowsCount(&mColumns.at(column), mData, localIndex.first); @@ -660,6 +714,12 @@ int CSMWorld::RefIdCollection::getNestedColumnsCount(int row, int column) const { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column)); + if (nestedAdapter) + { + return nestedAdapter->getNestedColumnsCount(&mColumns.at(column), mData); + } + const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdapter (localIndex.second)); return adaptor.getNestedColumnsCount(&mColumns.at(column), mData); @@ -674,6 +734,13 @@ void CSMWorld::RefIdCollection::addNestedRow(int row, int col, int position) { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(col)); + if (nestedAdapter) + { + nestedAdapter->addNestedRow(&mColumns.at(col), mData, localIndex.first, position); + return; + } + const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdapter (localIndex.second)); adaptor.addNestedRow(&mColumns.at(col), mData, localIndex.first, position); @@ -683,6 +750,13 @@ void CSMWorld::RefIdCollection::setNestedTable(int row, int column, const CSMWor { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column)); + if (nestedAdapter) + { + nestedAdapter->setNestedTable(&mColumns.at(column), mData, localIndex.first, nestedTable); + return; + } + const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdapter (localIndex.second)); adaptor.setNestedTable(&mColumns.at(column), mData, localIndex.first, nestedTable); @@ -692,7 +766,26 @@ CSMWorld::NestedTableWrapperBase* CSMWorld::RefIdCollection::nestedTable(int row { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column)); + if (nestedAdapter) + { + return nestedAdapter->nestedTable(&mColumns.at(column), mData, localIndex.first); + } + const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdapter (localIndex.second)); return adaptor.nestedTable(&mColumns.at(column), mData, localIndex.first); } + +const CSMWorld::NestedRefIdAdapterBase* CSMWorld::RefIdCollection::getNestedAdapter(const CSMWorld::ColumnBase &column) const +{ + std::map::const_iterator iter = + mNestedAdapters.find (&column); + + if (iter==mNestedAdapters.end()) + return 0; // FIXME: testing only + //throw std::runtime_error("No such column in the nestedadapters"); + + //return *iter->second; + return iter->second; +} diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index 3315212c18..70651b78d5 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -19,6 +19,7 @@ namespace CSMWorld { class RefIdAdapter; struct NestedTableWrapperBase; + class NestedRefIdAdapterBase; class RefIdColumn : public NestableColumn { @@ -44,11 +45,16 @@ namespace CSMWorld std::deque mColumns; std::map mAdapters; + std::map mNestedAdapters; + private: const RefIdAdapter& findAdapter (UniversalId::Type) const; ///< Throws an exception if no adaptor for \a Type can be found. + //const NestedRefIdAdapterBase& getNestedAdapter(const ColumnBase &column) const; + const NestedRefIdAdapterBase* getNestedAdapter(const ColumnBase &column) const; + public: RefIdCollection(); From 7ccf53e750781476e256cdb0ed1e6919edc6e9be Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sun, 12 Apr 2015 20:03:55 +1000 Subject: [PATCH 126/185] Changed over inventory adapters. Fixed a few places where modified records were not set properly. --- .../model/world/nestedcoladapterimp.cpp | 28 +++- .../model/world/nestedcoladapterimp.hpp | 12 +- apps/opencs/model/world/refidadapterimp.cpp | 6 +- apps/opencs/model/world/refidadapterimp.hpp | 147 +++++++++++++++++- apps/opencs/model/world/refidcollection.cpp | 8 +- 5 files changed, 186 insertions(+), 15 deletions(-) diff --git a/apps/opencs/model/world/nestedcoladapterimp.cpp b/apps/opencs/model/world/nestedcoladapterimp.cpp index 2bf1ffadd1..785817d337 100644 --- a/apps/opencs/model/world/nestedcoladapterimp.cpp +++ b/apps/opencs/model/world/nestedcoladapterimp.cpp @@ -81,13 +81,17 @@ namespace CSMWorld void PathgridPointListAdapter::setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) const { - record.get().mPoints = + Pathgrid pathgrid = record.get(); + + pathgrid.mPoints = static_cast(nestedTable).mRecord.mPoints; - record.get().mData.mS2 = + pathgrid.mData.mS2 = static_cast(nestedTable).mRecord.mData.mS2; // also update edges in case points were added/removed - record.get().mEdges = + pathgrid.mEdges = static_cast(nestedTable).mRecord.mEdges; + + record.setModified (pathgrid); } NestedTableWrapperBase* PathgridPointListAdapter::nestedTable(const Record& record) const @@ -180,8 +184,12 @@ namespace CSMWorld void PathgridEdgeListAdapter::setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) const { - record.get().mEdges = + Pathgrid pathgrid = record.get(); + + pathgrid.mEdges = static_cast &>(nestedTable).mNestedTable; + + record.setModified (pathgrid); } NestedTableWrapperBase* PathgridEdgeListAdapter::nestedTable(const Record& record) const @@ -277,8 +285,12 @@ namespace CSMWorld void FactionReactionsAdapter::setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) const { - record.get().mReactions = + ESM::Faction faction = record.get(); + + faction.mReactions = static_cast >&>(nestedTable).mNestedTable; + + record.setModified (faction); } NestedTableWrapperBase* FactionReactionsAdapter::nestedTable(const Record& record) const @@ -393,8 +405,12 @@ namespace CSMWorld void RegionSoundListAdapter::setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) const { - record.get().mSoundList = + ESM::Region region = record.get(); + + region.mSoundList = static_cast >&>(nestedTable).mNestedTable; + + record.setModified (region); } NestedTableWrapperBase* RegionSoundListAdapter::nestedTable(const Record& record) const diff --git a/apps/opencs/model/world/nestedcoladapterimp.hpp b/apps/opencs/model/world/nestedcoladapterimp.hpp index 7fed74868c..387b07e5cc 100644 --- a/apps/opencs/model/world/nestedcoladapterimp.hpp +++ b/apps/opencs/model/world/nestedcoladapterimp.hpp @@ -173,8 +173,12 @@ namespace CSMWorld virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) const { - record.get().mPowers.mList = + ESXRecordT raceOrBthSgn = record.get(); + + raceOrBthSgn.mPowers.mList = static_cast >&>(nestedTable).mNestedTable; + + record.setModified (raceOrBthSgn); } virtual NestedTableWrapperBase* nestedTable(const Record& record) const @@ -277,8 +281,12 @@ namespace CSMWorld virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) const { - record.get().mEffects.mList = + ESXRecordT magic = record.get(); + + magic.mEffects.mList = static_cast >&>(nestedTable).mNestedTable; + + record.setModified (magic); } virtual NestedTableWrapperBase* nestedTable(const Record& record) const diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 426bfe3d1e..42d1aa52e9 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -26,7 +26,7 @@ QVariant CSMWorld::PotionRefIdAdapter::getData (const RefIdColumn *column, const return record.get().mData.mAutoCalc!=0; if (column==mColumns.mEffects) - return true; // Required to show nested tables in dialogue subview + return true; // to show nested tables in dialogue subview, see IdTree::hasChildren() return InventoryRefIdAdapter::getData (column, data, index); } @@ -213,7 +213,7 @@ QVariant CSMWorld::ContainerRefIdAdapter::getData (const RefIdColumn *column, return (record.get().mFlags & ESM::Container::Respawn)!=0; if (column==mContent) - return true; // required by IdTree::hasChildren() + return true; // Required to show nested tables in dialogue subview return NameRefIdAdapter::getData (column, data, index); } @@ -497,7 +497,7 @@ QVariant CSMWorld::NpcRefIdAdapter::getData (const RefIdColumn *column, const Re return QString::fromUtf8 (record.get().mHead.c_str()); if (column==mColumns.mDestinations) - return true; // required by IdTree::hasChildren() + return true; // to show nested tables in dialogue subview, see IdTree::hasChildren() std::map::const_iterator iter = mColumns.mFlags.find (column); diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index b12d0cb6f0..08e2e74938 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -8,6 +8,9 @@ #include #include #include +#include +#include +#include #include "record.hpp" #include "refiddata.hpp" @@ -545,10 +548,10 @@ namespace CSMWorld return record.get().mAiData.mAlarm; if (column==mActors.mInventory) - return true; // required by IdTree::hasChildren() + return true; // to show nested tables in dialogue subview, see IdTree::hasChildren() if (column==mActors.mSpells) - return true; // required by IdTree::hasChildren() + return true; // to show nested tables in dialogue subview, see IdTree::hasChildren() std::map::const_iterator iter = mActors.mServices.find (column); @@ -908,7 +911,7 @@ namespace CSMWorld virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const { - const Record record; + const Record record; // not used, just a dummy return EffectsListAdapter::getNestedColumnsCount(record); } @@ -919,6 +922,144 @@ namespace CSMWorld return EffectsListAdapter::getNestedRowsCount(record); } }; + + template + class NestedInventoryRefIdAdapter : public NestedRefIdAdapterBase + { + UniversalId::Type mType; + + // not implemented + NestedInventoryRefIdAdapter (const NestedInventoryRefIdAdapter&); + NestedInventoryRefIdAdapter& operator= (const NestedInventoryRefIdAdapter&); + + public: + + NestedInventoryRefIdAdapter(UniversalId::Type type) :mType(type) {} + + virtual ~NestedInventoryRefIdAdapter() {} + + virtual void addNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int position) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + ESXRecordT container = record.get(); + + std::vector& list = container.mInventory.mList; + + ESM::ContItem newRow = {0, {""}}; + + if (position >= (int)list.size()) + list.push_back(newRow); + else + list.insert(list.begin()+position, newRow); + + record.setModified (container); + } + + virtual void removeNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int rowToRemove) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + ESXRecordT container = record.get(); + + std::vector& list = container.mInventory.mList; + + if (rowToRemove < 0 || rowToRemove >= static_cast (list.size())) + throw std::runtime_error ("index out of range"); + + list.erase (list.begin () + rowToRemove); + + record.setModified (container); + } + + virtual void setNestedTable (const RefIdColumn* column, + RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + ESXRecordT container = record.get(); + + container.mInventory.mList = + static_cast >&>(nestedTable).mNestedTable; + + record.setModified (container); + } + + virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, + const RefIdData& data, int index) const + { + const Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + + // deleted by dtor of NestedTableStoring + return new NestedTableWrapper >(record.get().mInventory.mList); + } + + virtual QVariant getNestedData (const RefIdColumn *column, + const RefIdData& data, int index, int subRowIndex, int subColIndex) const + { + const Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + + const std::vector& list = record.get().mInventory.mList; + + if (subRowIndex < 0 || subRowIndex >= static_cast (list.size())) + throw std::runtime_error ("index out of range"); + + const ESM::ContItem& content = list.at(subRowIndex); + + switch (subColIndex) + { + case 0: return QString::fromUtf8(content.mItem.toString().c_str()); + case 1: return content.mCount; + default: + throw std::runtime_error("Trying to access non-existing column in the nested table!"); + } + } + + virtual void setNestedData (const RefIdColumn *column, + RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); + ESXRecordT container = record.get(); + std::vector& list = container.mInventory.mList; + + if (subRowIndex < 0 || subRowIndex >= static_cast (list.size())) + throw std::runtime_error ("index out of range"); + + switch(subColIndex) + { + case 0: + list.at(subRowIndex).mItem.assign(std::string(value.toString().toUtf8().constData())); + break; + + case 1: + list.at(subRowIndex).mCount = value.toInt(); + break; + + default: + throw std::runtime_error("Trying to access non-existing column in the nested table!"); + } + + record.setModified (container); + } + + virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const + { + return 2; + } + + virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const + { + const Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + + return static_cast(record.get().mInventory.mList.size()); + } + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 929a3b245e..755a1f56f4 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -76,7 +76,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn (Columns::ColumnId_EffectList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); potionColumns.mEffects = &mColumns.back(); // see refidadapterimp.hpp mNestedAdapters.insert (std::make_pair(&mColumns.back(), - new EffectsRefIdAdapter (UniversalId::Type_Potion))); + new EffectsRefIdAdapter (UniversalId::Type_Potion))); mColumns.back().addColumn( new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_String/*, false*/)); mColumns.back().addColumn( @@ -124,6 +124,10 @@ CSMWorld::RefIdCollection::RefIdCollection() // Nested table mColumns.push_back(RefIdColumn (Columns::ColumnId_ActorInventory, ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue)); actorsColumns.mInventory = &mColumns.back(); + mNestedAdapters.insert (std::make_pair(&mColumns.back(), + new NestedInventoryRefIdAdapter (UniversalId::Type_Npc))); + mNestedAdapters.insert (std::make_pair(&mColumns.back(), + new NestedInventoryRefIdAdapter (UniversalId::Type_Creature))); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String)); mColumns.back().addColumn( @@ -205,6 +209,8 @@ CSMWorld::RefIdCollection::RefIdCollection() // Nested table mColumns.push_back(RefIdColumn (Columns::ColumnId_ContainerContent, ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue)); const RefIdColumn *content = &mColumns.back(); + mNestedAdapters.insert (std::make_pair(&mColumns.back(), + new NestedInventoryRefIdAdapter (UniversalId::Type_Container))); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String)); mColumns.back().addColumn( From a976dca27bb7d0c0b3a8a6e476501d4dc4a649c8 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 13 Apr 2015 06:39:38 +1000 Subject: [PATCH 127/185] Changed over the remaining RefId adapters. Fixed issue where map entries were overwriting the same key... --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/world/nestedadapters.cpp | 8 - apps/opencs/model/world/nestedadapters.hpp | 420 -------------------- apps/opencs/model/world/refidadapter.cpp | 85 ---- apps/opencs/model/world/refidadapter.hpp | 43 -- apps/opencs/model/world/refidadapterimp.cpp | 15 +- apps/opencs/model/world/refidadapterimp.hpp | 332 +++++++++++++++- apps/opencs/model/world/refidcollection.cpp | 181 +++++---- apps/opencs/model/world/refidcollection.hpp | 5 +- 9 files changed, 422 insertions(+), 669 deletions(-) delete mode 100644 apps/opencs/model/world/nestedadapters.cpp delete mode 100644 apps/opencs/model/world/nestedadapters.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index babd3363fe..cfe084e2cf 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -25,7 +25,7 @@ opencs_units (model/world opencs_units_noqt (model/world universalid record commands columnbase scriptcontext cell refidcollection refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope - pathgrid landtexture land nestedtablewrapper nestedadapters nestedcollection nestedcoladapterimp + pathgrid landtexture land nestedtablewrapper nestedcollection nestedcoladapterimp ) opencs_hdrs_noqt (model/world diff --git a/apps/opencs/model/world/nestedadapters.cpp b/apps/opencs/model/world/nestedadapters.cpp deleted file mode 100644 index 1c8b1eff18..0000000000 --- a/apps/opencs/model/world/nestedadapters.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "nestedadapters.hpp" - -CSMWorld::HelperBase::HelperBase(CSMWorld::UniversalId::Type type) - : mType(type) -{} - -CSMWorld::HelperBase::~HelperBase() -{} diff --git a/apps/opencs/model/world/nestedadapters.hpp b/apps/opencs/model/world/nestedadapters.hpp deleted file mode 100644 index 97046276f0..0000000000 --- a/apps/opencs/model/world/nestedadapters.hpp +++ /dev/null @@ -1,420 +0,0 @@ -#ifndef CSM_WORLD_NESTEDADAPTERS_H -#define CSM_WORLD_NESTEDADAPTERS_H - -#include -#include -#include - -#include "universalid.hpp" -#include "nestedtablewrapper.hpp" -#include "record.hpp" -#include "refiddata.hpp" -#include "refidadapter.hpp" -#include -#include -#include -#include -#include -#include - -#include - -/*! \brief - * Nested adapter redirects responsibility to the helper class. Helper classes are polymorhpic (vide HelperBase and CastableHelper) and most likely templates. - */ - -namespace CSMWorld -{ - class RefIdColumn; - - class HelperBase - { - protected: - const CSMWorld::UniversalId::Type mType; - - public: - HelperBase(CSMWorld::UniversalId::Type type); - - virtual ~HelperBase(); - - virtual void setNestedTable(RefIdData& data, - int index, - const NestedTableWrapperBase& nestedTable) = 0; - - virtual NestedTableWrapperBase* nestedTable(const RefIdData& data, - int index) const = 0; - - virtual QVariant getNestedData(const CSMWorld::RefIdData& data, - int index, - int subRowIndex, - int subColIndex) const = 0; - - virtual void removeNestedRow (RefIdData& data, - int index, - int rowToRemove) const = 0; - - virtual void setNestedData (RefIdData& data, - int index, - const QVariant& value, - int subRowIndex, - int subColIndex) const = 0; - - virtual void addNestedRow (RefIdData& data, - int index, - int position) const = 0; - - virtual int getNestedColumnsCount(const RefIdData& data) const = 0; - - virtual int getNestedRowsCount(const RefIdData& data, - int index) const = 0; - }; - - template - class CastableHelper : public HelperBase - { - - public: - CastableHelper(CSMWorld::UniversalId::Type type) - : HelperBase(type) {} - - protected: - const Record& getRecord(const RefIdData& data, int index) const - { - return dynamic_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, mType))); - } - - Record& getRecord(RefIdData& data, int index) const - { - return dynamic_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, mType))); - } - }; - - template - class SpellsHelper : public CastableHelper - { - public: - - SpellsHelper(CSMWorld::UniversalId::Type type) - : CastableHelper(type) {} - - virtual void setNestedTable(RefIdData& data, - int index, - const NestedTableWrapperBase& nestedTable) - { - CastableHelper::getRecord(data, index).get().mSpells.mList = - (static_cast >&>(nestedTable)).mNestedTable; - } - - virtual NestedTableWrapperBase* nestedTable(const RefIdData& data, - int index) const - { - return new NestedTableWrapper >(CastableHelper::getRecord(data, index).get().mSpells.mList); - } - - virtual QVariant getNestedData(const CSMWorld::RefIdData& data, - int index, - int subRowIndex, - int subColIndex) const - { - const std::string& content = CastableHelper::getRecord(data, index).get().mSpells.mList.at(subRowIndex); - - if (subColIndex == 0) - { - return QString::fromUtf8(content.c_str()); - } - - throw std::logic_error("Trying to access non-existing column in the nested table!"); - } - - virtual void removeNestedRow (RefIdData& data, int index, int rowToRemove) const - { - std::vector& list = CastableHelper::getRecord(data, index).get().mSpells.mList; - - list.erase (list.begin () + rowToRemove); - } - - void setNestedData (RefIdData& data, - int index, - const QVariant& value, - int subRowIndex, - int subColIndex) const - { - if (subColIndex == 0) - { - CastableHelper::getRecord(data, index).get().mSpells.mList.at(subRowIndex) = std::string(value.toString().toUtf8()); - } - else - throw std::logic_error("Trying to access non-existing column in the nested table!"); - } - - virtual void addNestedRow (RefIdData& data, int index, int position) const - { - std::vector& list = CastableHelper::getRecord(data, index).get().mSpells.mList; - - std::string newString; - if (position >= (int)list.size()) - { - list.push_back(newString); - return; - } - - list.insert(list.begin()+position, newString); - } - - virtual int getNestedColumnsCount(const RefIdData& data) const - { - return 1; - } - - - virtual int getNestedRowsCount(const RefIdData& data, - int index) const - { - return CastableHelper::getRecord(data, index).get().mSpells.mList.size(); - } - - }; - - template - class DestinationsHelper : public CastableHelper - { - public: - - DestinationsHelper(CSMWorld::UniversalId::Type type) - : CastableHelper(type) {} - - virtual void setNestedTable(RefIdData& data, - int index, - const NestedTableWrapperBase& nestedTable) - { - CastableHelper::getRecord(data, index).get().mTransport.mList = - (static_cast >&>(nestedTable)).mNestedTable; - } - - virtual NestedTableWrapperBase* nestedTable(const RefIdData& data, - int index) const - { - return new NestedTableWrapper >(CastableHelper::getRecord(data, index).get().mTransport.mList); - } - - virtual QVariant getNestedData(const CSMWorld::RefIdData& data, - int index, - int subRowIndex, - int subColIndex) const - { - const ESM::Transport::Dest& content = CastableHelper::getRecord(data, index).get().mTransport.mList.at(subRowIndex); - - switch (subColIndex) - { - case 0: - return QString::fromUtf8(content.mCellName.c_str()); - - case 1: - return content.mPos.pos[0]; - - case 2: - return content.mPos.pos[1]; - - case 3: - return content.mPos.pos[2]; - - case 4: - return content.mPos.rot[0]; - - case 5: - return content.mPos.rot[1]; - - case 6: - return content.mPos.rot[2]; - - default: - throw std::logic_error("Trying to access non-existing column in the nested table!"); - } - } - - virtual void removeNestedRow (RefIdData& data, int index, int rowToRemove) const - { - std::vector& list = CastableHelper::getRecord(data, index).get().mTransport.mList; - - list.erase (list.begin () + rowToRemove); - } - - void setNestedData (RefIdData& data, - int index, - const QVariant& value, - int subRowIndex, - int subColIndex) const - { - switch(subColIndex) - { - case 0: - CastableHelper::getRecord(data, index).get().mTransport.mList.at(subRowIndex).mCellName = std::string(value.toString().toUtf8().constData()); - break; - - case 1: - CastableHelper::getRecord(data, index).get().mTransport.mList.at(subRowIndex).mPos.pos[0] = value.toFloat(); - break; - - case 2: - CastableHelper::getRecord(data, index).get().mTransport.mList.at(subRowIndex).mPos.pos[1] = value.toFloat(); - break; - - case 3: - CastableHelper::getRecord(data, index).get().mTransport.mList.at(subRowIndex).mPos.pos[2] = value.toFloat(); - break; - - case 4: - CastableHelper::getRecord(data, index).get().mTransport.mList.at(subRowIndex).mPos.rot[0] = value.toFloat(); - break; - - case 5: - CastableHelper::getRecord(data, index).get().mTransport.mList.at(subRowIndex).mPos.rot[1] = value.toFloat(); - break; - - case 6: - CastableHelper::getRecord(data, index).get().mTransport.mList.at(subRowIndex).mPos.rot[2] = value.toFloat(); - break; - - default: - throw std::logic_error("Trying to access non-existing column in the nested table!"); - } - } - - virtual void addNestedRow (RefIdData& data, int index, int position) const - { - std::vector& list = CastableHelper::getRecord(data, index).get().mTransport.mList; - - ESM::Position newPos; - for (unsigned i = 0; i < 3; ++i) - { - newPos.pos[i] = 0; - newPos.rot[i] = 0; - } - - ESM::Transport::Dest newRow; - newRow.mPos = newPos; - newRow.mCellName = ""; - - if (position >= (int)list.size()) - { - list.push_back(newRow); - return; - } - - list.insert(list.begin()+position, newRow); - } - - virtual int getNestedColumnsCount(const RefIdData& data) const - { - return 7; - } - - virtual int getNestedRowsCount(const RefIdData& data, - int index) const - { - return CastableHelper::getRecord(data, index).get().mTransport.mList.size(); - } - - }; - - template - class InventoryHelper : public CastableHelper - { - public: - - InventoryHelper(CSMWorld::UniversalId::Type type) - : CastableHelper(type) {} - - virtual void setNestedTable(RefIdData& data, - int index, - const NestedTableWrapperBase& nestedTable) - { - CastableHelper::getRecord(data, index).get().mInventory.mList = - (static_cast >&>(nestedTable)).mNestedTable; - } - - virtual NestedTableWrapperBase* nestedTable(const RefIdData& data, - int index) const - { - return new NestedTableWrapper >(CastableHelper::getRecord(data, index).get().mInventory.mList); - } - - virtual QVariant getNestedData(const CSMWorld::RefIdData& data, - int index, - int subRowIndex, - int subColIndex) const - { - const ESM::ContItem& content = CastableHelper::getRecord(data, index).get().mInventory.mList.at(subRowIndex); - - switch (subColIndex) - { - case 0: - return QString::fromUtf8(content.mItem.toString().c_str()); - - case 1: - return content.mCount; - - default: - throw std::logic_error("Trying to access non-existing column in the nested table!"); - } - } - - virtual void removeNestedRow (RefIdData& data, int index, int rowToRemove) const - { - std::vector& list = CastableHelper::getRecord(data, index).get().mInventory.mList; - - list.erase (list.begin () + rowToRemove); - } - - void setNestedData (RefIdData& data, - int index, - const QVariant& value, - int subRowIndex, - int subColIndex) const - { - switch(subColIndex) - { - case 0: - CastableHelper::getRecord(data, index).get().mInventory.mList.at(subRowIndex).mItem.assign(std::string(value.toString().toUtf8().constData())); - break; - - case 1: - CastableHelper::getRecord(data, index).get().mInventory.mList.at(subRowIndex).mCount = value.toInt(); - break; - - default: - throw std::logic_error("Trying to access non-existing column in the nested table!"); - } - } - - virtual void addNestedRow (RefIdData& data, int index, int position) const - { - std::vector& list = CastableHelper::getRecord(data, index).get().mInventory.mList; - - ESM::ContItem newRow = {0, {""}}; - if (position >= (int)list.size()) - { - list.push_back(newRow); - return; - } - - list.insert(list.begin()+position, newRow); - } - - virtual int getNestedColumnsCount(const RefIdData& data) const - { - return 2; - } - - virtual int getNestedRowsCount(const RefIdData& data, - int index) const - { - return CastableHelper::getRecord(data, index).get().mInventory.mList.size(); - } - - }; -} - -#endif diff --git a/apps/opencs/model/world/refidadapter.cpp b/apps/opencs/model/world/refidadapter.cpp index a12a95196c..37cb67bca3 100644 --- a/apps/opencs/model/world/refidadapter.cpp +++ b/apps/opencs/model/world/refidadapter.cpp @@ -1,9 +1,5 @@ #include "refidadapter.hpp" -#include "nestedtablewrapper.hpp" - -#include - CSMWorld::RefIdAdapter::RefIdAdapter() {} CSMWorld::RefIdAdapter::~RefIdAdapter() {} @@ -11,84 +7,3 @@ CSMWorld::RefIdAdapter::~RefIdAdapter() {} CSMWorld::NestedRefIdAdapterBase::NestedRefIdAdapterBase() {} CSMWorld::NestedRefIdAdapterBase::~NestedRefIdAdapterBase() {} - -CSMWorld::NestedRefIdAdapter::NestedRefIdAdapter() -{} - -CSMWorld::NestedRefIdAdapter::~NestedRefIdAdapter() -{ - for (unsigned i = 0; i < mAssociatedColumns.size(); ++i) - { - delete mAssociatedColumns[i].second; - } -} - -void CSMWorld::NestedRefIdAdapter::setNestedData (const RefIdColumn *column, RefIdData& data, int row, - const QVariant& value, int subRowIndex, int subColIndex) const -{ - getHelper(column)->setNestedData(data, row, value, subRowIndex, subColIndex); -} - -QVariant CSMWorld::NestedRefIdAdapter::getNestedData(const RefIdColumn *column, const RefIdData& data, - int index, int subRowIndex, int subColIndex) const -{ - return getHelper(column)->getNestedData(data, index, subRowIndex, subColIndex); -} - -int CSMWorld::NestedRefIdAdapter::getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const -{ - return getHelper(column)->getNestedColumnsCount(data); -} - - -int CSMWorld::NestedRefIdAdapter::getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const -{ - return getHelper(column)->getNestedRowsCount(data, index); -} - - -void CSMWorld::NestedRefIdAdapter::removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, int rowToRemove) const -{ - getHelper(column)->removeNestedRow(data, index, rowToRemove); -} - -void CSMWorld::NestedRefIdAdapter::addNestedRow (const RefIdColumn *column, RefIdData& data, int index, int position) const -{ - getHelper(column)->addNestedRow(data, index, position); //This code grows more boring and boring. I would love some macros. -} - -void CSMWorld::NestedRefIdAdapter::setNestedTable (const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const -{ - getHelper(column)->setNestedTable(data, index, nestedTable); -} - - -CSMWorld::NestedTableWrapperBase* CSMWorld::NestedRefIdAdapter::nestedTable (const RefIdColumn* column, const RefIdData& data, int index) const -{ - return getHelper(column)->nestedTable(data, index); -} - -CSMWorld::HelperBase* CSMWorld::NestedRefIdAdapter::getHelper(const RefIdColumn *column) const -{ - for (unsigned i = 0; i < mAssociatedColumns.size(); ++i) - { - if (mAssociatedColumns[i].first == column) - { - return mAssociatedColumns[i].second; - } - } - - throw std::logic_error("No such column in the nestedrefidadapter"); - - return NULL; -} - -void CSMWorld::NestedRefIdAdapter::setAssocColumns(const std::vector >& assocColumns) -{ - mAssociatedColumns = assocColumns; -} - -void CSMWorld::NestedRefIdAdapter::addAssocColumn(const std::pair & assocColumn) -{ - mAssociatedColumns.push_back(assocColumn); -} diff --git a/apps/opencs/model/world/refidadapter.hpp b/apps/opencs/model/world/refidadapter.hpp index f80ce7ab38..ba9da577de 100644 --- a/apps/opencs/model/world/refidadapter.hpp +++ b/apps/opencs/model/world/refidadapter.hpp @@ -4,8 +4,6 @@ #include #include -#include "nestedadapters.hpp" - /*! \brief * Adapters acts as indirection layer, abstracting details of the record types (in the wrappers) from the higher levels of model. * Please notice that nested adaptor uses helper classes for actually performing any actions. Different record types require different helpers (needs to be created in the subclass and then fetched via member function). @@ -77,47 +75,6 @@ namespace CSMWorld virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, const RefIdData& data, int index) const = 0; }; - - class NestedRefIdAdapter : public NestedRefIdAdapterBase - { - std::vector > mAssociatedColumns; //basically, i wanted a map, but with pointer key - - public: - NestedRefIdAdapter(); - - virtual ~NestedRefIdAdapter(); - - virtual void setNestedData (const RefIdColumn *column, RefIdData& data, int row, - const QVariant& value, int subRowIndex, int subColIndex) const; - - virtual QVariant getNestedData (const RefIdColumn *column, const RefIdData& data, - int index, int subRowIndex, int subColIndex) const; - - virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const; - - virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const; - - virtual void removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, int rowToRemove) const; - - virtual void addNestedRow (const RefIdColumn *column, RefIdData& data, int index, int position) const; - - virtual void setNestedTable (const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const; - - virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, const RefIdData& data, int index) const; - - protected: - void setAssocColumns(const std::vector >& assocColumns); - ///The ownership of the Helper pointers is transfered. - ///The ownership of the column pointers it not transfered (it is not surprising, since columns are created by collection). - ///You MUST call this method to setup the nested adaptor! - - void addAssocColumn(const std::pair & assocColumn); - ///Like setAssocColumn, when it is impossible to set all columns at once - - private: - - HelperBase* getHelper(const RefIdColumn *column) const; - }; } #endif diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 42d1aa52e9..cd3a203271 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -188,13 +188,7 @@ CSMWorld::ContainerRefIdAdapter::ContainerRefIdAdapter (const NameColumns& colum const RefIdColumn *weight, const RefIdColumn *organic, const RefIdColumn *respawn, const RefIdColumn *content) : NameRefIdAdapter (UniversalId::Type_Container, columns), mWeight (weight), mOrganic (organic), mRespawn (respawn), mContent(content) -{ - std::vector > assoCol; - - assoCol.push_back(std::make_pair(content, new InventoryHelper(UniversalId::Type_Container))); - - setAssocColumns(assoCol); -} +{} QVariant CSMWorld::ContainerRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, @@ -471,9 +465,7 @@ CSMWorld::NpcColumns::NpcColumns (const ActorColumns& actorColumns) CSMWorld::NpcRefIdAdapter::NpcRefIdAdapter (const NpcColumns& columns) : ActorRefIdAdapter (UniversalId::Type_Npc, columns), mColumns (columns) -{ - NestedRefIdAdapter::addAssocColumn(std::make_pair(columns.mDestinations, new DestinationsHelper(UniversalId::Type_Npc))); -} +{} QVariant CSMWorld::NpcRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, int index) const @@ -496,9 +488,6 @@ QVariant CSMWorld::NpcRefIdAdapter::getData (const RefIdColumn *column, const Re if (column==mColumns.mHead) return QString::fromUtf8 (record.get().mHead.c_str()); - if (column==mColumns.mDestinations) - return true; // to show nested tables in dialogue subview, see IdTree::hasChildren() - std::map::const_iterator iter = mColumns.mFlags.find (column); diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 08e2e74938..32e9148c73 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -11,12 +11,12 @@ #include #include #include +#include #include "record.hpp" #include "refiddata.hpp" #include "universalid.hpp" #include "refidadapter.hpp" -#include "nestedadapters.hpp" namespace CSMWorld { @@ -489,6 +489,7 @@ namespace CSMWorld const RefIdColumn *mAlarm; const RefIdColumn *mInventory; const RefIdColumn *mSpells; + const RefIdColumn *mDestinations; std::map mServices; ActorColumns (const NameColumns& base) : NameColumns (base) {} @@ -496,7 +497,7 @@ namespace CSMWorld /// \brief Adapter for actor IDs (handles common AI functionality) template - class ActorRefIdAdapter : public NameRefIdAdapter, public NestedRefIdAdapter + class ActorRefIdAdapter : public NameRefIdAdapter { ActorColumns mActors; @@ -516,14 +517,7 @@ namespace CSMWorld ActorRefIdAdapter::ActorRefIdAdapter (UniversalId::Type type, const ActorColumns& columns) : NameRefIdAdapter (type, columns), mActors (columns) - { - std::vector > assoCol; - - assoCol.push_back(std::make_pair(mActors.mInventory, new InventoryHelper(type))); - assoCol.push_back(std::make_pair(mActors.mSpells, new SpellsHelper(type))); - - setAssocColumns(assoCol); - } + {} template QVariant ActorRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, @@ -553,6 +547,9 @@ namespace CSMWorld if (column==mActors.mSpells) return true; // to show nested tables in dialogue subview, see IdTree::hasChildren() + if (column==mActors.mDestinations) + return true; // to show nested tables in dialogue subview, see IdTree::hasChildren() + std::map::const_iterator iter = mActors.mServices.find (column); @@ -672,7 +669,7 @@ namespace CSMWorld ///< If the data type does not match an exception is thrown. }; - class ContainerRefIdAdapter : public NameRefIdAdapter, public NestedRefIdAdapter + class ContainerRefIdAdapter : public NameRefIdAdapter { const RefIdColumn *mWeight; const RefIdColumn *mOrganic; @@ -790,7 +787,6 @@ namespace CSMWorld const RefIdColumn *mFaction; const RefIdColumn *mHair; const RefIdColumn *mHead; - const RefIdColumn *mDestinations; NpcColumns (const ActorColumns& actorColumns); }; @@ -1060,6 +1056,318 @@ namespace CSMWorld return static_cast(record.get().mInventory.mList.size()); } }; + + template + class NestedSpellRefIdAdapter : public NestedRefIdAdapterBase + { + UniversalId::Type mType; + + // not implemented + NestedSpellRefIdAdapter (const NestedSpellRefIdAdapter&); + NestedSpellRefIdAdapter& operator= (const NestedSpellRefIdAdapter&); + + public: + + NestedSpellRefIdAdapter(UniversalId::Type type) :mType(type) {} + + virtual ~NestedSpellRefIdAdapter() {} + + virtual void addNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int position) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + ESXRecordT caster = record.get(); + + std::vector& list = caster.mSpells.mList; + + std::string newString; + + if (position >= (int)list.size()) + list.push_back(newString); + else + list.insert(list.begin()+position, newString); + + record.setModified (caster); + } + + virtual void removeNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int rowToRemove) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + ESXRecordT caster = record.get(); + + std::vector& list = caster.mSpells.mList; + + if (rowToRemove < 0 || rowToRemove >= static_cast (list.size())) + throw std::runtime_error ("index out of range"); + + list.erase (list.begin () + rowToRemove); + + record.setModified (caster); + } + + virtual void setNestedTable (const RefIdColumn* column, + RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + ESXRecordT caster = record.get(); + + caster.mSpells.mList = + static_cast >&>(nestedTable).mNestedTable; + + record.setModified (caster); + } + + virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, + const RefIdData& data, int index) const + { + const Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + + // deleted by dtor of NestedTableStoring + return new NestedTableWrapper >(record.get().mSpells.mList); + } + + virtual QVariant getNestedData (const RefIdColumn *column, + const RefIdData& data, int index, int subRowIndex, int subColIndex) const + { + const Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + + const std::vector& list = record.get().mSpells.mList; + + if (subRowIndex < 0 || subRowIndex >= static_cast (list.size())) + throw std::runtime_error ("index out of range"); + + const std::string& content = list.at(subRowIndex); + + if (subColIndex == 0) + return QString::fromUtf8(content.c_str()); + else + throw std::runtime_error("Trying to access non-existing column in the nested table!"); + } + + virtual void setNestedData (const RefIdColumn *column, + RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); + ESXRecordT caster = record.get(); + std::vector& list = caster.mSpells.mList; + + if (subRowIndex < 0 || subRowIndex >= static_cast (list.size())) + throw std::runtime_error ("index out of range"); + + if (subColIndex == 0) + list.at(subRowIndex) = std::string(value.toString().toUtf8()); + else + throw std::runtime_error("Trying to access non-existing column in the nested table!"); + + record.setModified (caster); + } + + virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const + { + return 1; + } + + virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const + { + const Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + + return static_cast(record.get().mSpells.mList.size()); + } + }; + + template + class NestedTravelRefIdAdapter : public NestedRefIdAdapterBase + { + UniversalId::Type mType; + + // not implemented + NestedTravelRefIdAdapter (const NestedTravelRefIdAdapter&); + NestedTravelRefIdAdapter& operator= (const NestedTravelRefIdAdapter&); + + public: + + NestedTravelRefIdAdapter(UniversalId::Type type) :mType(type) {} + + virtual ~NestedTravelRefIdAdapter() {} + + virtual void addNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int position) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + ESXRecordT traveller = record.get(); + + std::vector& list = traveller.mTransport.mList; + + ESM::Position newPos; + for (unsigned i = 0; i < 3; ++i) + { + newPos.pos[i] = 0; + newPos.rot[i] = 0; + } + + ESM::Transport::Dest newRow; + newRow.mPos = newPos; + newRow.mCellName = ""; + + if (position >= (int)list.size()) + list.push_back(newRow); + else + list.insert(list.begin()+position, newRow); + + record.setModified (traveller); + } + + virtual void removeNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int rowToRemove) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + ESXRecordT traveller = record.get(); + + std::vector& list = traveller.mTransport.mList; + + if (rowToRemove < 0 || rowToRemove >= static_cast (list.size())) + throw std::runtime_error ("index out of range"); + + list.erase (list.begin () + rowToRemove); + + record.setModified (traveller); + } + + virtual void setNestedTable (const RefIdColumn* column, + RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + ESXRecordT traveller = record.get(); + + traveller.mTransport.mList = + static_cast >&>(nestedTable).mNestedTable; + + record.setModified (traveller); + } + + virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, + const RefIdData& data, int index) const + { + const Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + + // deleted by dtor of NestedTableStoring + return new NestedTableWrapper >(record.get().mTransport.mList); + } + + virtual QVariant getNestedData (const RefIdColumn *column, + const RefIdData& data, int index, int subRowIndex, int subColIndex) const + { + const Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + + const std::vector& list = record.get().mTransport.mList; + + if (subRowIndex < 0 || subRowIndex >= static_cast (list.size())) + throw std::runtime_error ("index out of range"); + + const ESM::Transport::Dest& content = list.at(subRowIndex); + + switch (subColIndex) + { + case 0: + return QString::fromUtf8(content.mCellName.c_str()); + + case 1: + return content.mPos.pos[0]; + + case 2: + return content.mPos.pos[1]; + + case 3: + return content.mPos.pos[2]; + + case 4: + return content.mPos.rot[0]; + + case 5: + return content.mPos.rot[1]; + + case 6: + return content.mPos.rot[2]; + + default: + throw std::runtime_error("Trying to access non-existing column in the nested table!"); + } + } + + virtual void setNestedData (const RefIdColumn *column, + RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); + ESXRecordT traveller = record.get(); + std::vector& list = traveller.mTransport.mList; + + if (subRowIndex < 0 || subRowIndex >= static_cast (list.size())) + throw std::runtime_error ("index out of range"); + + switch(subColIndex) + { + case 0: + list.at(subRowIndex).mCellName = std::string(value.toString().toUtf8().constData()); + break; + + case 1: + list.at(subRowIndex).mPos.pos[0] = value.toFloat(); + break; + + case 2: + list.at(subRowIndex).mPos.pos[1] = value.toFloat(); + break; + + case 3: + list.at(subRowIndex).mPos.pos[2] = value.toFloat(); + break; + + case 4: + list.at(subRowIndex).mPos.rot[0] = value.toFloat(); + break; + + case 5: + list.at(subRowIndex).mPos.rot[1] = value.toFloat(); + break; + + case 6: + list.at(subRowIndex).mPos.rot[2] = value.toFloat(); + break; + + default: + throw std::runtime_error("Trying to access non-existing column in the nested table!"); + } + + record.setModified (traveller); + } + + virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const + { + return 7; + } + + virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const + { + const Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + + return static_cast(record.get().mTransport.mList.size()); + } + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 755a1f56f4..92cd37d0d3 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -75,8 +75,12 @@ CSMWorld::RefIdCollection::RefIdCollection() PotionColumns potionColumns (inventoryColumns); mColumns.push_back (RefIdColumn (Columns::ColumnId_EffectList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); potionColumns.mEffects = &mColumns.back(); // see refidadapterimp.hpp - mNestedAdapters.insert (std::make_pair(&mColumns.back(), - new EffectsRefIdAdapter (UniversalId::Type_Potion))); + + std::map effectsMap; + effectsMap.insert( + std::make_pair(UniversalId::Type_Potion, new EffectsRefIdAdapter (UniversalId::Type_Potion))); + mNestedAdapters.push_back (std::make_pair(&mColumns.back(), effectsMap)); + mColumns.back().addColumn( new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_String/*, false*/)); mColumns.back().addColumn( @@ -124,10 +128,14 @@ CSMWorld::RefIdCollection::RefIdCollection() // Nested table mColumns.push_back(RefIdColumn (Columns::ColumnId_ActorInventory, ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue)); actorsColumns.mInventory = &mColumns.back(); - mNestedAdapters.insert (std::make_pair(&mColumns.back(), - new NestedInventoryRefIdAdapter (UniversalId::Type_Npc))); - mNestedAdapters.insert (std::make_pair(&mColumns.back(), - new NestedInventoryRefIdAdapter (UniversalId::Type_Creature))); + + std::map inventoryMap; + inventoryMap.insert( + std::make_pair(UniversalId::Type_Npc, new NestedInventoryRefIdAdapter (UniversalId::Type_Npc))); + inventoryMap.insert( + std::make_pair(UniversalId::Type_Creature, new NestedInventoryRefIdAdapter (UniversalId::Type_Creature))); + + mNestedAdapters.push_back (std::make_pair(&mColumns.back(), inventoryMap)); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String)); mColumns.back().addColumn( @@ -136,9 +144,42 @@ CSMWorld::RefIdCollection::RefIdCollection() // Nested table mColumns.push_back(RefIdColumn (Columns::ColumnId_SpellList, ColumnBase::Display_NestedSpellList, ColumnBase::Flag_Dialogue)); actorsColumns.mSpells = &mColumns.back(); + + std::map spellsMap; + spellsMap.insert( + std::make_pair(UniversalId::Type_Npc, new NestedSpellRefIdAdapter (UniversalId::Type_Npc))); + spellsMap.insert( + std::make_pair(UniversalId::Type_Creature, new NestedSpellRefIdAdapter (UniversalId::Type_Creature))); + + mNestedAdapters.push_back (std::make_pair(&mColumns.back(), spellsMap)); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_SpellId, CSMWorld::ColumnBase::Display_String)); + // Nested table + mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcDestinations, ColumnBase::Display_NestedDestinationsList, ColumnBase::Flag_Dialogue)); + actorsColumns.mDestinations = &mColumns.back(); + + std::map destMap; + destMap.insert( + std::make_pair(UniversalId::Type_Npc, new NestedTravelRefIdAdapter (UniversalId::Type_Npc))); + destMap.insert( + std::make_pair(UniversalId::Type_Creature, new NestedTravelRefIdAdapter (UniversalId::Type_Creature))); + mNestedAdapters.push_back (std::make_pair(&mColumns.back(), destMap)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_DestinationCell, CSMWorld::ColumnBase::Display_String)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_PosX, CSMWorld::ColumnBase::Display_Float)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_PosY, CSMWorld::ColumnBase::Display_Float)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_PosZ, CSMWorld::ColumnBase::Display_Float)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_RotX, CSMWorld::ColumnBase::Display_Float)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_RotY, CSMWorld::ColumnBase::Display_Float)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_RotZ, CSMWorld::ColumnBase::Display_Float)); + static const struct { int mName; @@ -209,8 +250,12 @@ CSMWorld::RefIdCollection::RefIdCollection() // Nested table mColumns.push_back(RefIdColumn (Columns::ColumnId_ContainerContent, ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue)); const RefIdColumn *content = &mColumns.back(); - mNestedAdapters.insert (std::make_pair(&mColumns.back(), - new NestedInventoryRefIdAdapter (UniversalId::Type_Container))); + + std::map contMap; + contMap.insert( + std::make_pair(UniversalId::Type_Container, new NestedInventoryRefIdAdapter (UniversalId::Type_Container))); + mNestedAdapters.push_back (std::make_pair(&mColumns.back(), contMap)); + mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String)); mColumns.back().addColumn( @@ -351,24 +396,6 @@ CSMWorld::RefIdCollection::RefIdCollection() npcColumns.mFlags.insert (std::make_pair (metalBlood, ESM::NPC::Metal)); - // Nested table - mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcDestinations, ColumnBase::Display_NestedDestinationsList, ColumnBase::Flag_Dialogue)); - npcColumns.mDestinations = &mColumns.back(); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_DestinationCell, CSMWorld::ColumnBase::Display_String)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_PosX, CSMWorld::ColumnBase::Display_Float)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_PosY, CSMWorld::ColumnBase::Display_Float)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_PosZ, CSMWorld::ColumnBase::Display_Float)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_RotX, CSMWorld::ColumnBase::Display_Float)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_RotY, CSMWorld::ColumnBase::Display_Float)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_RotZ, CSMWorld::ColumnBase::Display_Float)); - WeaponColumns weaponColumns (enchantableColumns); mColumns.push_back (RefIdColumn (Columns::ColumnId_WeaponType, ColumnBase::Display_WeaponType)); @@ -461,9 +488,13 @@ CSMWorld::RefIdCollection::~RefIdCollection() iter!=mAdapters.end(); ++iter) delete iter->second; - for (std::map::iterator iter (mNestedAdapters.begin()); + for (std::vector > >::iterator iter (mNestedAdapters.begin()); iter!=mNestedAdapters.end(); ++iter) - delete iter->second; + { + for (std::map::iterator it ((iter->second).begin()); + it!=(iter->second).end(); ++it) + delete it->second; + } } int CSMWorld::RefIdCollection::getSize() const @@ -509,15 +540,11 @@ QVariant CSMWorld::RefIdCollection::getNestedData (int row, int column, int subR { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(row); - const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column)); + const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); if (nestedAdapter) - { return nestedAdapter->getNestedData(&mColumns.at (column), mData, localIndex.first, subRow, subColumn); - } - - const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdapter (localIndex.second)); - - return adaptor.getNestedData (&mColumns.at (column), mData, localIndex.first, subRow, subColumn); + else + throw std::runtime_error("Could not find a nestedadapter"); } void CSMWorld::RefIdCollection::setData (int index, int column, const QVariant& data) @@ -533,16 +560,14 @@ void CSMWorld::RefIdCollection::setNestedData(int row, int column, const QVarian { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); - const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column)); + const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); if (nestedAdapter) { nestedAdapter->setNestedData(&mColumns.at (column), mData, localIndex.first, data, subRow, subColumn); return; } - - const RefIdAdapter& adaptor = findAdapter (localIndex.second); - - dynamic_cast(adaptor).setNestedData (&mColumns.at (column), mData, localIndex.first, data, subRow, subColumn); + else + throw std::runtime_error("Could not find a nestedadapter"); } void CSMWorld::RefIdCollection::removeRows (int index, int count) @@ -554,16 +579,14 @@ void CSMWorld::RefIdCollection::removeNestedRows(int row, int column, int subRow { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); - const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column)); + const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); if (nestedAdapter) { nestedAdapter->removeNestedRow(&mColumns.at (column), mData, localIndex.first, subRow); return; } - - const RefIdAdapter& adaptor = findAdapter (localIndex.second); - - dynamic_cast(adaptor).removeNestedRow(&mColumns.at (column), mData, localIndex.first, subRow); + else + throw std::runtime_error("Could not find a nestedadapter"); } void CSMWorld::RefIdCollection::appendBlankRecord (const std::string& id, UniversalId::Type type) @@ -705,30 +728,22 @@ int CSMWorld::RefIdCollection::getNestedRowsCount(int row, int column) const { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); - const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column)); + const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); if (nestedAdapter) - { return nestedAdapter->getNestedRowsCount(&mColumns.at(column), mData, localIndex.first); - } - - const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdapter (localIndex.second)); - - return adaptor.getNestedRowsCount(&mColumns.at(column), mData, localIndex.first); + else + throw std::runtime_error("Could not find a nestedadapter"); } int CSMWorld::RefIdCollection::getNestedColumnsCount(int row, int column) const { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); - const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column)); + const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); if (nestedAdapter) - { return nestedAdapter->getNestedColumnsCount(&mColumns.at(column), mData); - } - - const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdapter (localIndex.second)); - - return adaptor.getNestedColumnsCount(&mColumns.at(column), mData); + else + throw std::runtime_error("Could not find a nestedadapter"); } CSMWorld::NestableColumn *CSMWorld::RefIdCollection::getNestableColumn(int column) @@ -740,58 +755,56 @@ void CSMWorld::RefIdCollection::addNestedRow(int row, int col, int position) { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); - const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(col)); + const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(col), localIndex.second); if (nestedAdapter) { nestedAdapter->addNestedRow(&mColumns.at(col), mData, localIndex.first, position); return; } - - const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdapter (localIndex.second)); - - adaptor.addNestedRow(&mColumns.at(col), mData, localIndex.first, position); + else + throw std::runtime_error("Could not find a nestedadapter"); } void CSMWorld::RefIdCollection::setNestedTable(int row, int column, const CSMWorld::NestedTableWrapperBase& nestedTable) { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); - const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column)); + const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); if (nestedAdapter) { nestedAdapter->setNestedTable(&mColumns.at(column), mData, localIndex.first, nestedTable); return; } - - const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdapter (localIndex.second)); - - adaptor.setNestedTable(&mColumns.at(column), mData, localIndex.first, nestedTable); + else + throw std::runtime_error("Could not find a nestedadapter"); } CSMWorld::NestedTableWrapperBase* CSMWorld::RefIdCollection::nestedTable(int row, int column) const { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); - const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column)); + const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); if (nestedAdapter) - { return nestedAdapter->nestedTable(&mColumns.at(column), mData, localIndex.first); - } - - const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast(findAdapter (localIndex.second)); - - return adaptor.nestedTable(&mColumns.at(column), mData, localIndex.first); + else + throw std::runtime_error("Could not find a nestedadapter"); } -const CSMWorld::NestedRefIdAdapterBase* CSMWorld::RefIdCollection::getNestedAdapter(const CSMWorld::ColumnBase &column) const +const CSMWorld::NestedRefIdAdapterBase* CSMWorld::RefIdCollection::getNestedAdapter(const CSMWorld::ColumnBase &column, UniversalId::Type type) const { - std::map::const_iterator iter = - mNestedAdapters.find (&column); + for (std::vector > >::const_iterator iter (mNestedAdapters.begin()); + iter!=mNestedAdapters.end(); ++iter) + { + if ((iter->first) == &column) + { + std::map::const_iterator it = + (iter->second).find(type); - if (iter==mNestedAdapters.end()) - return 0; // FIXME: testing only - //throw std::runtime_error("No such column in the nestedadapters"); + if (it == (iter->second).end()) + throw std::runtime_error("No such type in the nestedadapters"); - //return *iter->second; - return iter->second; + return it->second; + } + } + throw std::runtime_error("No such column in the nestedadapters"); } diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index 70651b78d5..f183dc7a0e 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -45,15 +45,14 @@ namespace CSMWorld std::deque mColumns; std::map mAdapters; - std::map mNestedAdapters; + std::vector > > mNestedAdapters; private: const RefIdAdapter& findAdapter (UniversalId::Type) const; ///< Throws an exception if no adaptor for \a Type can be found. - //const NestedRefIdAdapterBase& getNestedAdapter(const ColumnBase &column) const; - const NestedRefIdAdapterBase* getNestedAdapter(const ColumnBase &column) const; + const NestedRefIdAdapterBase* getNestedAdapter(const ColumnBase &column, UniversalId::Type type) const; public: From 221c57adee071d63f79ca86cda55e5974d335be3 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 13 Apr 2015 07:05:06 +1000 Subject: [PATCH 128/185] Fix template syntax and travis warnings. --- apps/opencs/model/world/refidadapterimp.hpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 32e9148c73..2599dc9609 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -17,11 +17,10 @@ #include "refiddata.hpp" #include "universalid.hpp" #include "refidadapter.hpp" +#include "nestedtablewrapper.hpp" namespace CSMWorld { - struct NestedTableWrapperBase; - struct BaseColumns { const RefIdColumn *mId; @@ -857,6 +856,7 @@ namespace CSMWorld virtual ~EffectsRefIdAdapter() {} + using NestedRefIdAdapterBase::addNestedRow; virtual void addNestedRow (const RefIdColumn *column, RefIdData& data, int index, int position) const { @@ -865,6 +865,7 @@ namespace CSMWorld EffectsListAdapter::addNestedRow(record, position); } + using NestedRefIdAdapterBase::removeNestedRow; virtual void removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, int rowToRemove) const { @@ -873,6 +874,7 @@ namespace CSMWorld EffectsListAdapter::removeNestedRow(record, rowToRemove); } + using NestedRefIdAdapterBase::setNestedTable; virtual void setNestedTable (const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const { @@ -881,6 +883,7 @@ namespace CSMWorld EffectsListAdapter::setNestedTable(record, nestedTable); } + using NestedRefIdAdapterBase::nestedTable; virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, const RefIdData& data, int index) const { @@ -889,6 +892,7 @@ namespace CSMWorld return EffectsListAdapter::nestedTable(record); } + using NestedRefIdAdapterBase::getNestedData; virtual QVariant getNestedData (const RefIdColumn *column, const RefIdData& data, int index, int subRowIndex, int subColIndex) const { @@ -897,6 +901,7 @@ namespace CSMWorld return EffectsListAdapter::getNestedData(record, subRowIndex, subColIndex); } + using NestedRefIdAdapterBase::setNestedData; virtual void setNestedData (const RefIdColumn *column, RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const { @@ -905,12 +910,14 @@ namespace CSMWorld EffectsListAdapter::setNestedData(record, value, subRowIndex, subColIndex); } + using NestedRefIdAdapterBase::getNestedColumnsCount; virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const { const Record record; // not used, just a dummy return EffectsListAdapter::getNestedColumnsCount(record); } + using NestedRefIdAdapterBase::getNestedRowsCount; virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const { const Record& record = @@ -978,7 +985,7 @@ namespace CSMWorld ESXRecordT container = record.get(); container.mInventory.mList = - static_cast >&>(nestedTable).mNestedTable; + static_cast >&>(nestedTable).mNestedTable; record.setModified (container); } @@ -1116,7 +1123,7 @@ namespace CSMWorld ESXRecordT caster = record.get(); caster.mSpells.mList = - static_cast >&>(nestedTable).mNestedTable; + static_cast >&>(nestedTable).mNestedTable; record.setModified (caster); } @@ -1128,7 +1135,7 @@ namespace CSMWorld static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); // deleted by dtor of NestedTableStoring - return new NestedTableWrapper >(record.get().mSpells.mList); + return new NestedTableWrapper >(record.get().mSpells.mList); } virtual QVariant getNestedData (const RefIdColumn *column, @@ -1251,7 +1258,7 @@ namespace CSMWorld ESXRecordT traveller = record.get(); traveller.mTransport.mList = - static_cast >&>(nestedTable).mNestedTable; + static_cast >&>(nestedTable).mNestedTable; record.setModified (traveller); } @@ -1263,7 +1270,7 @@ namespace CSMWorld static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); // deleted by dtor of NestedTableStoring - return new NestedTableWrapper >(record.get().mTransport.mList); + return new NestedTableWrapper >(record.get().mTransport.mList); } virtual QVariant getNestedData (const RefIdColumn *column, From 60e5ff8811e84951a9bd160a4a2969fc50b55a92 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 13 Apr 2015 08:03:30 +1000 Subject: [PATCH 129/185] Remove duplicated checks and exceptions. --- apps/opencs/model/world/refidadapterimp.hpp | 2 +- apps/opencs/model/world/refidcollection.cpp | 76 ++++++--------------- apps/opencs/model/world/refidcollection.hpp | 2 +- 3 files changed, 24 insertions(+), 56 deletions(-) diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 2599dc9609..a3007d4154 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -997,7 +997,7 @@ namespace CSMWorld static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); // deleted by dtor of NestedTableStoring - return new NestedTableWrapper >(record.get().mInventory.mList); + return new NestedTableWrapper >(record.get().mInventory.mList); } virtual QVariant getNestedData (const RefIdColumn *column, diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 92cd37d0d3..3f14ba4ac0 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -539,12 +539,9 @@ QVariant CSMWorld::RefIdCollection::getData (int index, int column) const QVariant CSMWorld::RefIdCollection::getNestedData (int row, int column, int subRow, int subColumn) const { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(row); + const CSMWorld::NestedRefIdAdapterBase& nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); - const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); - if (nestedAdapter) - return nestedAdapter->getNestedData(&mColumns.at (column), mData, localIndex.first, subRow, subColumn); - else - throw std::runtime_error("Could not find a nestedadapter"); + return nestedAdapter.getNestedData(&mColumns.at (column), mData, localIndex.first, subRow, subColumn); } void CSMWorld::RefIdCollection::setData (int index, int column, const QVariant& data) @@ -559,15 +556,10 @@ void CSMWorld::RefIdCollection::setData (int index, int column, const QVariant& void CSMWorld::RefIdCollection::setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn) { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + const CSMWorld::NestedRefIdAdapterBase& nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); - const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); - if (nestedAdapter) - { - nestedAdapter->setNestedData(&mColumns.at (column), mData, localIndex.first, data, subRow, subColumn); - return; - } - else - throw std::runtime_error("Could not find a nestedadapter"); + nestedAdapter.setNestedData(&mColumns.at (column), mData, localIndex.first, data, subRow, subColumn); + return; } void CSMWorld::RefIdCollection::removeRows (int index, int count) @@ -578,15 +570,10 @@ void CSMWorld::RefIdCollection::removeRows (int index, int count) void CSMWorld::RefIdCollection::removeNestedRows(int row, int column, int subRow) { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + const CSMWorld::NestedRefIdAdapterBase& nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); - const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); - if (nestedAdapter) - { - nestedAdapter->removeNestedRow(&mColumns.at (column), mData, localIndex.first, subRow); - return; - } - else - throw std::runtime_error("Could not find a nestedadapter"); + nestedAdapter.removeNestedRow(&mColumns.at (column), mData, localIndex.first, subRow); + return; } void CSMWorld::RefIdCollection::appendBlankRecord (const std::string& id, UniversalId::Type type) @@ -727,23 +714,17 @@ const CSMWorld::RefIdData& CSMWorld::RefIdCollection::getDataSet() const int CSMWorld::RefIdCollection::getNestedRowsCount(int row, int column) const { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + const CSMWorld::NestedRefIdAdapterBase& nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); - const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); - if (nestedAdapter) - return nestedAdapter->getNestedRowsCount(&mColumns.at(column), mData, localIndex.first); - else - throw std::runtime_error("Could not find a nestedadapter"); + return nestedAdapter.getNestedRowsCount(&mColumns.at(column), mData, localIndex.first); } int CSMWorld::RefIdCollection::getNestedColumnsCount(int row, int column) const { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + const CSMWorld::NestedRefIdAdapterBase& nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); - const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); - if (nestedAdapter) - return nestedAdapter->getNestedColumnsCount(&mColumns.at(column), mData); - else - throw std::runtime_error("Could not find a nestedadapter"); + return nestedAdapter.getNestedColumnsCount(&mColumns.at(column), mData); } CSMWorld::NestableColumn *CSMWorld::RefIdCollection::getNestableColumn(int column) @@ -754,43 +735,30 @@ CSMWorld::NestableColumn *CSMWorld::RefIdCollection::getNestableColumn(int colum void CSMWorld::RefIdCollection::addNestedRow(int row, int col, int position) { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + const CSMWorld::NestedRefIdAdapterBase& nestedAdapter = getNestedAdapter(mColumns.at(col), localIndex.second); - const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(col), localIndex.second); - if (nestedAdapter) - { - nestedAdapter->addNestedRow(&mColumns.at(col), mData, localIndex.first, position); - return; - } - else - throw std::runtime_error("Could not find a nestedadapter"); + nestedAdapter.addNestedRow(&mColumns.at(col), mData, localIndex.first, position); + return; } void CSMWorld::RefIdCollection::setNestedTable(int row, int column, const CSMWorld::NestedTableWrapperBase& nestedTable) { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + const CSMWorld::NestedRefIdAdapterBase& nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); - const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); - if (nestedAdapter) - { - nestedAdapter->setNestedTable(&mColumns.at(column), mData, localIndex.first, nestedTable); - return; - } - else - throw std::runtime_error("Could not find a nestedadapter"); + nestedAdapter.setNestedTable(&mColumns.at(column), mData, localIndex.first, nestedTable); + return; } CSMWorld::NestedTableWrapperBase* CSMWorld::RefIdCollection::nestedTable(int row, int column) const { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + const CSMWorld::NestedRefIdAdapterBase& nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); - const CSMWorld::NestedRefIdAdapterBase* nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); - if (nestedAdapter) - return nestedAdapter->nestedTable(&mColumns.at(column), mData, localIndex.first); - else - throw std::runtime_error("Could not find a nestedadapter"); + return nestedAdapter.nestedTable(&mColumns.at(column), mData, localIndex.first); } -const CSMWorld::NestedRefIdAdapterBase* CSMWorld::RefIdCollection::getNestedAdapter(const CSMWorld::ColumnBase &column, UniversalId::Type type) const +const CSMWorld::NestedRefIdAdapterBase& CSMWorld::RefIdCollection::getNestedAdapter(const CSMWorld::ColumnBase &column, UniversalId::Type type) const { for (std::vector > >::const_iterator iter (mNestedAdapters.begin()); iter!=mNestedAdapters.end(); ++iter) @@ -803,7 +771,7 @@ const CSMWorld::NestedRefIdAdapterBase* CSMWorld::RefIdCollection::getNestedAdap if (it == (iter->second).end()) throw std::runtime_error("No such type in the nestedadapters"); - return it->second; + return *it->second; } } throw std::runtime_error("No such column in the nestedadapters"); diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index f183dc7a0e..4d511d12da 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -52,7 +52,7 @@ namespace CSMWorld const RefIdAdapter& findAdapter (UniversalId::Type) const; ///< Throws an exception if no adaptor for \a Type can be found. - const NestedRefIdAdapterBase* getNestedAdapter(const ColumnBase &column, UniversalId::Type type) const; + const NestedRefIdAdapterBase& getNestedAdapter(const ColumnBase &column, UniversalId::Type type) const; public: From 526b53fce017d154f1a01e5095f4c42d1a271241 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 13 Apr 2015 14:14:00 +1000 Subject: [PATCH 130/185] Add AI packages table to dialogue subview. Also minor bug fixes. --- apps/opencs/model/world/columns.cpp | 17 +- apps/opencs/model/world/columns.hpp | 24 +- .../model/world/nestedcoladapterimp.cpp | 4 +- .../model/world/nestedcoladapterimp.hpp | 3 +- apps/opencs/model/world/refidadapterimp.hpp | 316 +++++++++++++++++- apps/opencs/model/world/refidcollection.cpp | 36 ++ 6 files changed, 380 insertions(+), 20 deletions(-) diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index fca16ec0b5..92a0d8f8d2 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -192,9 +192,9 @@ namespace CSMWorld { ColumnId_NpcDestinations, "Destinations" }, { ColumnId_DestinationCell, "Cell"}, - { ColumnId_PosX, "X"}, - { ColumnId_PosY, "Y"}, - { ColumnId_PosZ, "Z"}, + { ColumnId_PosX, "Dest X"}, + { ColumnId_PosY, "Dest Y"}, + { ColumnId_PosZ, "Dest Z"}, { ColumnId_RotX, "Rotation X"}, { ColumnId_RotY, "Rotation Y"}, { ColumnId_RotZ, "Rotation Z"}, @@ -247,6 +247,17 @@ namespace CSMWorld { ColumnId_EffectRange, "Range"}, { ColumnId_EffectArea, "Area"}, + { ColumnId_AiPackageList, "Ai Packages"}, + { ColumnId_AiPackage, "Package"}, + { ColumnId_AiWanderDist, "Wander Dist"}, + { ColumnId_AiWanderDuration, "Wander Duration"}, + { ColumnId_AiWanderToD, "Wander ToD"}, + { ColumnId_AiWanderIdle, "Wander Idle"}, + { ColumnId_AiWanderRepeat, "Wander Repeat"}, + { ColumnId_AiActivateName, "Activate"}, + { ColumnId_AiTargetId, "Target ID"}, + { ColumnId_AiTargetCell, "Target Cell"}, + { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, { ColumnId_UseValue3, "Use value 3" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 4f77ee23a0..2788966a7f 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -183,9 +183,9 @@ namespace CSMWorld ColumnId_SpellId = 168, ColumnId_NpcDestinations = 169, ColumnId_DestinationCell = 170, - ColumnId_PosX = 171, - ColumnId_PosY = 172, - ColumnId_PosZ = 173, + ColumnId_PosX = 171, // these are float + ColumnId_PosY = 172, // these are float + ColumnId_PosZ = 173, // these are float ColumnId_RotX = 174, ColumnId_RotY = 175, ColumnId_RotZ = 176, @@ -214,9 +214,9 @@ namespace CSMWorld ColumnId_PathgridPoints = 199, ColumnId_PathgridIndex = 200, - ColumnId_PathgridPosX = 201, - ColumnId_PathgridPosY = 202, - ColumnId_PathgridPosZ = 203, + ColumnId_PathgridPosX = 201, // these are int + ColumnId_PathgridPosY = 202, // these are int + ColumnId_PathgridPosZ = 203, // these are int ColumnId_PathgridEdges = 204, ColumnId_PathgridEdgeIndex = 205, ColumnId_PathgridEdge0 = 206, @@ -236,6 +236,18 @@ namespace CSMWorld ColumnId_EffectRange = 217, ColumnId_EffectArea = 218, + ColumnId_AiPackageList = 219, + ColumnId_AiPackage = 220, + ColumnId_AiWanderDist = 221, + ColumnId_AiWanderDuration = 222, + ColumnId_AiWanderToD = 223, + ColumnId_AiWanderIdle = 224, + ColumnId_AiWanderRepeat = 225, + ColumnId_AiActivateName = 226, + // use ColumnId_PosX, etc for AI destinations + ColumnId_AiTargetId = 227, + ColumnId_AiTargetCell = 228, + // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. ColumnId_UseValue1 = 0x10000, diff --git a/apps/opencs/model/world/nestedcoladapterimp.cpp b/apps/opencs/model/world/nestedcoladapterimp.cpp index 785817d337..d974a34c79 100644 --- a/apps/opencs/model/world/nestedcoladapterimp.cpp +++ b/apps/opencs/model/world/nestedcoladapterimp.cpp @@ -121,7 +121,7 @@ namespace CSMWorld ESM::Pathgrid::Point point = pathgrid.mPoints[subRowIndex]; switch (subColIndex) { - case 0: break; + case 0: return; // return without saving case 1: point.mX = value.toInt(); break; case 2: point.mY = value.toInt(); break; case 3: point.mZ = value.toInt(); break; @@ -228,7 +228,7 @@ namespace CSMWorld ESM::Pathgrid::Edge edge = pathgrid.mEdges[subRowIndex]; switch (subColIndex) { - case 0: break; + case 0: return; // return without saving case 1: edge.mV0 = value.toInt(); break; case 2: edge.mV1 = value.toInt(); break; default: throw std::runtime_error("Pathgrid edge subcolumn index out of range"); diff --git a/apps/opencs/model/world/nestedcoladapterimp.hpp b/apps/opencs/model/world/nestedcoladapterimp.hpp index 387b07e5cc..3328396fbb 100644 --- a/apps/opencs/model/world/nestedcoladapterimp.hpp +++ b/apps/opencs/model/world/nestedcoladapterimp.hpp @@ -457,7 +457,8 @@ namespace CSMWorld effect.mRange = ESM::RT_Touch; else if (effectId == "Target") effect.mRange = ESM::RT_Target; - // else leave unchanged + else + return; // leave unchanged break; } case 4: effect.mArea = value.toInt(); break; diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index a3007d4154..c0fcba43cb 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -10,8 +10,6 @@ #include #include #include -#include -#include #include "record.hpp" #include "refiddata.hpp" @@ -489,6 +487,7 @@ namespace CSMWorld const RefIdColumn *mInventory; const RefIdColumn *mSpells; const RefIdColumn *mDestinations; + const RefIdColumn *mAiPackages; std::map mServices; ActorColumns (const NameColumns& base) : NameColumns (base) {} @@ -549,6 +548,9 @@ namespace CSMWorld if (column==mActors.mDestinations) return true; // to show nested tables in dialogue subview, see IdTree::hasChildren() + if (column==mActors.mAiPackages) + return true; // to show nested tables in dialogue subview, see IdTree::hasChildren() + std::map::const_iterator iter = mActors.mServices.find (column); @@ -985,7 +987,7 @@ namespace CSMWorld ESXRecordT container = record.get(); container.mInventory.mList = - static_cast >&>(nestedTable).mNestedTable; + static_cast >&>(nestedTable).mNestedTable; record.setModified (container); } @@ -997,7 +999,7 @@ namespace CSMWorld static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); // deleted by dtor of NestedTableStoring - return new NestedTableWrapper >(record.get().mInventory.mList); + return new NestedTableWrapper >(record.get().mInventory.mList); } virtual QVariant getNestedData (const RefIdColumn *column, @@ -1123,7 +1125,7 @@ namespace CSMWorld ESXRecordT caster = record.get(); caster.mSpells.mList = - static_cast >&>(nestedTable).mNestedTable; + static_cast >&>(nestedTable).mNestedTable; record.setModified (caster); } @@ -1135,7 +1137,7 @@ namespace CSMWorld static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); // deleted by dtor of NestedTableStoring - return new NestedTableWrapper >(record.get().mSpells.mList); + return new NestedTableWrapper >(record.get().mSpells.mList); } virtual QVariant getNestedData (const RefIdColumn *column, @@ -1258,7 +1260,7 @@ namespace CSMWorld ESXRecordT traveller = record.get(); traveller.mTransport.mList = - static_cast >&>(nestedTable).mNestedTable; + static_cast >&>(nestedTable).mNestedTable; record.setModified (traveller); } @@ -1270,7 +1272,7 @@ namespace CSMWorld static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); // deleted by dtor of NestedTableStoring - return new NestedTableWrapper >(record.get().mTransport.mList); + return new NestedTableWrapper >(record.get().mTransport.mList); } virtual QVariant getNestedData (const RefIdColumn *column, @@ -1375,6 +1377,304 @@ namespace CSMWorld return static_cast(record.get().mTransport.mList.size()); } }; + + template + class ActorAiRefIdAdapter : public NestedRefIdAdapterBase + { + UniversalId::Type mType; + + // not implemented + ActorAiRefIdAdapter (const ActorAiRefIdAdapter&); + ActorAiRefIdAdapter& operator= (const ActorAiRefIdAdapter&); + + public: + + ActorAiRefIdAdapter(UniversalId::Type type) :mType(type) {} + + virtual ~ActorAiRefIdAdapter() {} + + virtual void addNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int position) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + ESXRecordT actor = record.get(); + + std::vector& list = actor.mAiPackage.mList; + + ESM::AIPackage newRow; + newRow.mType = ESM::AI_CNDT; + newRow.mCellName = ""; + + if (position >= (int)list.size()) + list.push_back(newRow); + else + list.insert(list.begin()+position, newRow); + + record.setModified (actor); + } + + virtual void removeNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int rowToRemove) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + ESXRecordT actor = record.get(); + + std::vector& list = actor.mAiPackage.mList; + + if (rowToRemove < 0 || rowToRemove >= static_cast (list.size())) + throw std::runtime_error ("index out of range"); + + list.erase (list.begin () + rowToRemove); + + record.setModified (actor); + } + + virtual void setNestedTable (const RefIdColumn* column, + RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + ESXRecordT actor = record.get(); + + actor.mAiPackage.mList = + static_cast >&>(nestedTable).mNestedTable; + + record.setModified (actor); + } + + virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, + const RefIdData& data, int index) const + { + const Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + + // deleted by dtor of NestedTableStoring + return new NestedTableWrapper >(record.get().mAiPackage.mList); + } + + virtual QVariant getNestedData (const RefIdColumn *column, + const RefIdData& data, int index, int subRowIndex, int subColIndex) const + { + const Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + + const std::vector& list = record.get().mAiPackage.mList; + + if (subRowIndex < 0 || subRowIndex >= static_cast (list.size())) + throw std::runtime_error ("index out of range"); + + const ESM::AIPackage& content = list.at(subRowIndex); + + switch (subColIndex) + { + case 0: + switch (content.mType) + { + case ESM::AI_Wander: return QString("AI Wander"); + case ESM::AI_Travel: return QString("AI Travel"); + case ESM::AI_Follow: return QString("AI Follow"); + case ESM::AI_Escort: return QString("AI Escort"); + case ESM::AI_Activate: return QString("AI Activate"); + case ESM::AI_CNDT: + default: return QString("None"); + } + case 1: // wander dist + if (content.mType == ESM::AI_Wander) + return content.mWander.mDistance; + else + return QVariant(); + case 2: // wander dur + if (content.mType == ESM::AI_Wander || + content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort) + return content.mWander.mDuration; + else + return QVariant(); + case 3: // wander ToD + if (content.mType == ESM::AI_Wander) + return content.mWander.mTimeOfDay; // FIXME: not sure of the format + else + return QVariant(); + case 4: // wander idle + if (content.mType == ESM::AI_Wander) + { + return static_cast(content.mWander.mIdle[0]); // FIXME: + } + else + return QVariant(); + case 5: // wander repeat + if (content.mType == ESM::AI_Wander) + return QString(content.mWander.mShouldRepeat ? "Yes" : "No"); + else + return QVariant(); + case 6: // activate name + if (content.mType == ESM::AI_Activate) + return QString(content.mActivate.mName.toString().c_str()); + else + return QVariant(); + case 7: // target id + if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort) + return QString(content.mTarget.mId.toString().c_str()); + else + return QVariant(); + case 8: // target cell + if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort) + return QString::fromUtf8(content.mCellName.c_str()); + else + return QVariant(); + case 9: + if (content.mType == ESM::AI_Travel) + return content.mTravel.mX; + else if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort) + return content.mTarget.mX; + else + return QVariant(); + case 10: + if (content.mType == ESM::AI_Travel) + return content.mTravel.mY; + else if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort) + return content.mTarget.mY; + else + return QVariant(); + case 11: + if (content.mType == ESM::AI_Travel) + return content.mTravel.mZ; + else if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort) + return content.mTarget.mZ; + else + return QVariant(); + default: + throw std::runtime_error("Trying to access non-existing column in the nested table!"); + } + } + + virtual void setNestedData (const RefIdColumn *column, + RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); + ESXRecordT actor = record.get(); + std::vector& list = actor.mAiPackage.mList; + + if (subRowIndex < 0 || subRowIndex >= static_cast (list.size())) + throw std::runtime_error ("index out of range"); + + ESM::AIPackage& content = list.at(subRowIndex); + + switch(subColIndex) + { + case 0: // ai package type + if ("AI Wander" == value.toString().toStdString()) + content.mType = ESM::AI_Wander; + else if ("AI Travel" == value.toString().toStdString()) + content.mType = ESM::AI_Travel; + else if ("AI Follow" == value.toString().toStdString()) + content.mType = ESM::AI_Follow; + else if ("AI Escort" == value.toString().toStdString()) + content.mType = ESM::AI_Escort; + else if ("AI Activate" == value.toString().toStdString()) + content.mType = ESM::AI_Activate; + else + content.mType = ESM::AI_CNDT; + break; // always save + + case 1: + if (content.mType == ESM::AI_Wander) + content.mWander.mDistance = static_cast(value.toInt()); + else + return; // return without saving + case 2: + if (content.mType == ESM::AI_Wander || + content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort) + content.mWander.mDuration = static_cast(value.toInt()); + else + return; // return without saving + case 3: + if (content.mType == ESM::AI_Wander) + content.mWander.mTimeOfDay = static_cast(value.toInt()); + else + return; // return without saving + case 4: + if (content.mType == ESM::AI_Wander) + break; // FIXME: idle + else + return; // return without saving + case 5: + if (content.mType == ESM::AI_Wander) + { + if ("Yes" == value.toString().toStdString()) + content.mWander.mShouldRepeat = 1; + if ("No" == value.toString().toStdString()) + content.mWander.mShouldRepeat = 0; + else + return; // return without saving + } + case 6: // NAME32 + if (content.mType == ESM::AI_Activate) + { + content.mActivate.mName.assign(value.toString().toUtf8().constData()); + break; + } + else + return; // return without saving + case 7: // NAME32 + if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort) + { + content.mTarget.mId.assign(value.toString().toUtf8().constData()); + break; + } + else + return; // return without saving + case 8: + if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort) + { + content.mCellName = std::string(value.toString().toUtf8().constData()); + break; + } + else + return; // return without saving + case 9: + if (content.mType == ESM::AI_Travel) + content.mTravel.mZ = value.toFloat(); + else if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort) + content.mTarget.mZ = value.toFloat(); + else + return; // return without saving + case 10: + if (content.mType == ESM::AI_Travel) + content.mTravel.mZ = value.toFloat(); + else if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort) + content.mTarget.mZ = value.toFloat(); + else + return; // return without saving + case 11: + if (content.mType == ESM::AI_Travel) + content.mTravel.mZ = value.toFloat(); + else if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort) + content.mTarget.mZ = value.toFloat(); + else + return; // return without saving + default: + throw std::runtime_error("Trying to access non-existing column in the nested table!"); + } + + record.setModified (actor); + } + + virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const + { + return 12; + } + + virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const + { + const Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + + return static_cast(record.get().mAiPackage.mList.size()); + } + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 3f14ba4ac0..000426a0b5 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -180,6 +180,42 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_RotZ, CSMWorld::ColumnBase::Display_Float)); + // Nested table + mColumns.push_back(RefIdColumn (Columns::ColumnId_AiPackageList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); + actorsColumns.mAiPackages = &mColumns.back(); + + std::map aiMap; + aiMap.insert( + std::make_pair(UniversalId::Type_Npc, new ActorAiRefIdAdapter (UniversalId::Type_Npc))); + aiMap.insert( + std::make_pair(UniversalId::Type_Creature, new ActorAiRefIdAdapter (UniversalId::Type_Creature))); + + mNestedAdapters.push_back (std::make_pair(&mColumns.back(), aiMap)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_AiPackage, CSMWorld::ColumnBase::Display_String)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_AiWanderDist, CSMWorld::ColumnBase::Display_Integer)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_AiWanderDuration, CSMWorld::ColumnBase::Display_Integer)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_AiWanderToD, CSMWorld::ColumnBase::Display_Integer)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_AiWanderIdle, CSMWorld::ColumnBase::Display_Integer)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_AiWanderRepeat, CSMWorld::ColumnBase::Display_String)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_AiActivateName, CSMWorld::ColumnBase::Display_String)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_AiTargetId, CSMWorld::ColumnBase::Display_String)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_AiTargetCell, CSMWorld::ColumnBase::Display_String)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_PosX, CSMWorld::ColumnBase::Display_Float)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_PosY, CSMWorld::ColumnBase::Display_Float)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_PosZ, CSMWorld::ColumnBase::Display_Float)); + static const struct { int mName; From 513c3a47cb8d54b6dea46bdb5816bde1f5739aa8 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 13 Apr 2015 21:08:23 +1000 Subject: [PATCH 131/185] Add clothing/armor part reference table to dialogue subview. --- apps/opencs/model/world/columns.cpp | 7 +- apps/opencs/model/world/columns.hpp | 7 +- .../model/world/nestedcoladapterimp.hpp | 2 +- apps/opencs/model/world/refidadapterimp.cpp | 16 +- apps/opencs/model/world/refidadapterimp.hpp | 199 ++++++++++++++++-- apps/opencs/model/world/refidcollection.cpp | 24 ++- 6 files changed, 222 insertions(+), 33 deletions(-) diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 92a0d8f8d2..547efac567 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -250,7 +250,7 @@ namespace CSMWorld { ColumnId_AiPackageList, "Ai Packages"}, { ColumnId_AiPackage, "Package"}, { ColumnId_AiWanderDist, "Wander Dist"}, - { ColumnId_AiWanderDuration, "Wander Duration"}, + { ColumnId_AiDuration, "Duration"}, { ColumnId_AiWanderToD, "Wander ToD"}, { ColumnId_AiWanderIdle, "Wander Idle"}, { ColumnId_AiWanderRepeat, "Wander Repeat"}, @@ -258,6 +258,11 @@ namespace CSMWorld { ColumnId_AiTargetId, "Target ID"}, { ColumnId_AiTargetCell, "Target Cell"}, + { ColumnId_PartRefList, "Part Reference"}, + { ColumnId_PartRefType, "Type"}, + { ColumnId_PartRefMale, "Male"}, + { ColumnId_PartRefFemale, "Female"}, + { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, { ColumnId_UseValue3, "Use value 3" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 2788966a7f..6068ea6e75 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -239,7 +239,7 @@ namespace CSMWorld ColumnId_AiPackageList = 219, ColumnId_AiPackage = 220, ColumnId_AiWanderDist = 221, - ColumnId_AiWanderDuration = 222, + ColumnId_AiDuration = 222, ColumnId_AiWanderToD = 223, ColumnId_AiWanderIdle = 224, ColumnId_AiWanderRepeat = 225, @@ -248,6 +248,11 @@ namespace CSMWorld ColumnId_AiTargetId = 227, ColumnId_AiTargetCell = 228, + ColumnId_PartRefList = 229, + ColumnId_PartRefType = 230, + ColumnId_PartRefMale = 231, + ColumnId_PartRefFemale = 232, + // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. ColumnId_UseValue1 = 0x10000, diff --git a/apps/opencs/model/world/nestedcoladapterimp.hpp b/apps/opencs/model/world/nestedcoladapterimp.hpp index 3328396fbb..2aa1123a3a 100644 --- a/apps/opencs/model/world/nestedcoladapterimp.hpp +++ b/apps/opencs/model/world/nestedcoladapterimp.hpp @@ -175,7 +175,7 @@ namespace CSMWorld { ESXRecordT raceOrBthSgn = record.get(); - raceOrBthSgn.mPowers.mList = + raceOrBthSgn.mPowers.mList = static_cast >&>(nestedTable).mNestedTable; record.setModified (raceOrBthSgn); diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index cd3a203271..98c1b6f0f3 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -81,9 +81,10 @@ void CSMWorld::ApparatusRefIdAdapter::setData (const RefIdColumn *column, RefIdD CSMWorld::ArmorRefIdAdapter::ArmorRefIdAdapter (const EnchantableColumns& columns, - const RefIdColumn *type, const RefIdColumn *health, const RefIdColumn *armor) + const RefIdColumn *type, const RefIdColumn *health, const RefIdColumn *armor, + const RefIdColumn *partRef) : EnchantableRefIdAdapter (UniversalId::Type_Armor, columns), - mType (type), mHealth (health), mArmor (armor) + mType (type), mHealth (health), mArmor (armor), mPartRef(partRef) {} QVariant CSMWorld::ArmorRefIdAdapter::getData (const RefIdColumn *column, @@ -101,6 +102,9 @@ QVariant CSMWorld::ArmorRefIdAdapter::getData (const RefIdColumn *column, if (column==mArmor) return record.get().mData.mArmor; + if (column==mPartRef) + return true; // to show nested tables in dialogue subview, see IdTree::hasChildren() + return EnchantableRefIdAdapter::getData (column, data, index); } @@ -156,8 +160,9 @@ void CSMWorld::BookRefIdAdapter::setData (const RefIdColumn *column, RefIdData& } CSMWorld::ClothingRefIdAdapter::ClothingRefIdAdapter (const EnchantableColumns& columns, - const RefIdColumn *type) -: EnchantableRefIdAdapter (UniversalId::Type_Clothing, columns), mType (type) + const RefIdColumn *type, const RefIdColumn *partRef) +: EnchantableRefIdAdapter (UniversalId::Type_Clothing, columns), mType (type), + mPartRef(partRef) {} QVariant CSMWorld::ClothingRefIdAdapter::getData (const RefIdColumn *column, @@ -169,6 +174,9 @@ QVariant CSMWorld::ClothingRefIdAdapter::getData (const RefIdColumn *column, if (column==mType) return record.get().mData.mType; + if (column==mPartRef) + return true; // to show nested tables in dialogue subview, see IdTree::hasChildren() + return EnchantableRefIdAdapter::getData (column, data, index); } diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index c0fcba43cb..bc00d31f98 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -622,11 +622,12 @@ namespace CSMWorld const RefIdColumn *mType; const RefIdColumn *mHealth; const RefIdColumn *mArmor; + const RefIdColumn *mPartRef; public: ArmorRefIdAdapter (const EnchantableColumns& columns, const RefIdColumn *type, - const RefIdColumn *health, const RefIdColumn *armor); + const RefIdColumn *health, const RefIdColumn *armor, const RefIdColumn *partRef); virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) const; @@ -657,10 +658,12 @@ namespace CSMWorld class ClothingRefIdAdapter : public EnchantableRefIdAdapter { const RefIdColumn *mType; + const RefIdColumn *mPartRef; public: - ClothingRefIdAdapter (const EnchantableColumns& columns, const RefIdColumn *type); + ClothingRefIdAdapter (const EnchantableColumns& columns, + const RefIdColumn *type, const RefIdColumn *partRef); virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) const; @@ -1290,27 +1293,13 @@ namespace CSMWorld switch (subColIndex) { - case 0: - return QString::fromUtf8(content.mCellName.c_str()); - - case 1: - return content.mPos.pos[0]; - - case 2: - return content.mPos.pos[1]; - - case 3: - return content.mPos.pos[2]; - - case 4: - return content.mPos.rot[0]; - - case 5: - return content.mPos.rot[1]; - - case 6: - return content.mPos.rot[2]; - + case 0: return QString::fromUtf8(content.mCellName.c_str()); + case 1: return content.mPos.pos[0]; + case 2: return content.mPos.pos[1]; + case 3: return content.mPos.pos[2]; + case 4: return content.mPos.rot[0]; + case 5: return content.mPos.rot[1]; + case 6: return content.mPos.rot[2]; default: throw std::runtime_error("Trying to access non-existing column in the nested table!"); } @@ -1675,6 +1664,170 @@ namespace CSMWorld return static_cast(record.get().mAiPackage.mList.size()); } }; + + static const char *sPartRefs[ESM::PRT_Count] = + { + "Head", "Hair", "Neck", "Cuirass", "Groin", + "Skirt", "Right Hand", "Left Hand", "Right Wrist", "Left Wrist", + "Shield", "Right Forearm", "Left Forearm", "Right Upperarm", "Left Upperarm", + "Right Foot", "Left Foot", "Right Ankle", "Left Ankle", "Right Knee", + "Left Knee", "Right Leg", "Left Leg", "Right Pauldron", "Left Pauldron", + "Weapon", "Tail" + }; + + template + class BodyPartRefIdAdapter : public NestedRefIdAdapterBase + { + UniversalId::Type mType; + + // not implemented + BodyPartRefIdAdapter (const BodyPartRefIdAdapter&); + BodyPartRefIdAdapter& operator= (const BodyPartRefIdAdapter&); + + public: + + BodyPartRefIdAdapter(UniversalId::Type type) :mType(type) {} + + virtual ~BodyPartRefIdAdapter() {} + + virtual void addNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int position) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + ESXRecordT apparel = record.get(); + + std::vector& list = apparel.mParts.mParts; + + ESM::PartReference newPart; + newPart.mPart = 0; // 0 == head + newPart.mMale = ""; + newPart.mFemale = ""; + + if (position >= (int)list.size()) + list.push_back(newPart); + else + list.insert(list.begin()+position, newPart); + + record.setModified (apparel); + } + + virtual void removeNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int rowToRemove) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + ESXRecordT apparel = record.get(); + + std::vector& list = apparel.mParts.mParts; + + if (rowToRemove < 0 || rowToRemove >= static_cast (list.size())) + throw std::runtime_error ("index out of range"); + + list.erase (list.begin () + rowToRemove); + + record.setModified (apparel); + } + + virtual void setNestedTable (const RefIdColumn* column, + RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + ESXRecordT apparel = record.get(); + + apparel.mParts.mParts = + static_cast >&>(nestedTable).mNestedTable; + + record.setModified (apparel); + } + + virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, + const RefIdData& data, int index) const + { + const Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + + // deleted by dtor of NestedTableStoring + return new NestedTableWrapper >(record.get().mParts.mParts); + } + + virtual QVariant getNestedData (const RefIdColumn *column, + const RefIdData& data, int index, int subRowIndex, int subColIndex) const + { + const Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + + const std::vector& list = record.get().mParts.mParts; + + if (subRowIndex < 0 || subRowIndex >= static_cast (list.size())) + throw std::runtime_error ("index out of range"); + + const ESM::PartReference& content = list.at(subRowIndex); + + switch (subColIndex) + { + case 0: return QString(sPartRefs[content.mPart]); + case 1: return QString(content.mMale.c_str()); + case 2: return QString(content.mFemale.c_str()); + default: + throw std::runtime_error("Trying to access non-existing column in the nested table!"); + } + } + + virtual void setNestedData (const RefIdColumn *column, + RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); + ESXRecordT apparel = record.get(); + std::vector& list = apparel.mParts.mParts; + + if (subRowIndex < 0 || subRowIndex >= static_cast (list.size())) + throw std::runtime_error ("index out of range"); + + switch(subColIndex) + { + case 0: + { + std::string part = value.toString().toStdString(); + bool found = false; + for (unsigned int i = 0; i < ESM::PRT_Count; ++i) + { + if (part == sPartRefs[i]) + { + list.at(subRowIndex).mPart = static_cast(i); + found = true; + break; + } + } + if (!found) + return; // return without saving + else + break; + } + case 1: list.at(subRowIndex).mMale = value.toString().toStdString(); break; + case 2: list.at(subRowIndex).mFemale = value.toString().toStdString(); break; + default: + throw std::runtime_error("Trying to access non-existing column in the nested table!"); + } + + record.setModified (apparel); + } + + virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const + { + return 3; + } + + virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const + { + const Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + + return static_cast(record.get().mParts.mParts.size()); + } + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 000426a0b5..48f95451c5 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -196,7 +196,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_AiWanderDist, CSMWorld::ColumnBase::Display_Integer)); mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_AiWanderDuration, CSMWorld::ColumnBase::Display_Integer)); + new RefIdColumn (Columns::ColumnId_AiDuration, CSMWorld::ColumnBase::Display_Integer)); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_AiWanderToD, CSMWorld::ColumnBase::Display_Integer)); mColumns.back().addColumn( @@ -475,6 +475,24 @@ CSMWorld::RefIdCollection::RefIdCollection() weaponColumns.mFlags.insert (std::make_pair (&mColumns.back(), sWeaponFlagTable[i].mFlag)); } + // Nested table + mColumns.push_back(RefIdColumn (Columns::ColumnId_PartRefList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); + const RefIdColumn *partRef = &mColumns.back(); + + std::map partMap; + partMap.insert( + std::make_pair(UniversalId::Type_Armor, new BodyPartRefIdAdapter (UniversalId::Type_Armor))); + partMap.insert( + std::make_pair(UniversalId::Type_Clothing, new BodyPartRefIdAdapter (UniversalId::Type_Clothing))); + + mNestedAdapters.push_back (std::make_pair(&mColumns.back(), partMap)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_PartRefType, CSMWorld::ColumnBase::Display_String)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_PartRefMale, CSMWorld::ColumnBase::Display_String)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_PartRefFemale, CSMWorld::ColumnBase::Display_String)); + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, @@ -482,11 +500,11 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Apparatus, new ApparatusRefIdAdapter (inventoryColumns, apparatusType, toolsColumns.mQuality))); mAdapters.insert (std::make_pair (UniversalId::Type_Armor, - new ArmorRefIdAdapter (enchantableColumns, armorType, health, armor))); + new ArmorRefIdAdapter (enchantableColumns, armorType, health, armor, partRef))); mAdapters.insert (std::make_pair (UniversalId::Type_Book, new BookRefIdAdapter (enchantableColumns, scroll, attribute))); mAdapters.insert (std::make_pair (UniversalId::Type_Clothing, - new ClothingRefIdAdapter (enchantableColumns, clothingType))); + new ClothingRefIdAdapter (enchantableColumns, clothingType, partRef))); mAdapters.insert (std::make_pair (UniversalId::Type_Container, new ContainerRefIdAdapter (nameColumns, weightCapacity, organic, respawn, content))); mAdapters.insert (std::make_pair (UniversalId::Type_Creature, From 1c7ed795c2c45daa7707bac70be534a811bd691c Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 13 Apr 2015 22:21:27 +1000 Subject: [PATCH 132/185] Add creature/item levelled lists to dialogue subview. --- apps/opencs/model/world/columns.cpp | 4 + apps/opencs/model/world/columns.hpp | 4 + apps/opencs/model/world/refidadapterimp.hpp | 182 ++++++++++++++++++++ apps/opencs/model/world/refidcollection.cpp | 109 ++++++------ 4 files changed, 250 insertions(+), 49 deletions(-) diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 547efac567..83d6ceb57f 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -263,6 +263,10 @@ namespace CSMWorld { ColumnId_PartRefMale, "Male"}, { ColumnId_PartRefFemale, "Female"}, + { ColumnId_LevelledList,"Levelled List"}, + { ColumnId_LevelledItemId,"Item ID"}, + { ColumnId_LevelledItemLevel,"Level"}, + { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, { ColumnId_UseValue3, "Use value 3" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 6068ea6e75..81cae5e369 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -253,6 +253,10 @@ namespace CSMWorld ColumnId_PartRefMale = 231, ColumnId_PartRefFemale = 232, + ColumnId_LevelledList = 233, + ColumnId_LevelledItemId = 234, + ColumnId_LevelledItemLevel = 235, + // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. ColumnId_UseValue1 = 0x10000, diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index bc00d31f98..d09aaaa454 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -1828,6 +1828,188 @@ namespace CSMWorld return static_cast(record.get().mParts.mParts.size()); } }; + + struct LevListColumns : public BaseColumns + { + const RefIdColumn *mLevList; + + LevListColumns (const BaseColumns& base) : BaseColumns (base) {} + }; + + template + class LevelledListRefIdAdapter : public BaseRefIdAdapter + { + LevListColumns mLevList; + + public: + + LevelledListRefIdAdapter (UniversalId::Type type, const LevListColumns &columns); + + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) + const; + + virtual void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const; + ///< If the data type does not match an exception is thrown. + }; + + template + LevelledListRefIdAdapter::LevelledListRefIdAdapter (UniversalId::Type type, + const LevListColumns &columns) + : BaseRefIdAdapter (type, columns), mLevList (columns) + {} + + template + QVariant LevelledListRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const + { + if (column==mLevList.mLevList) + return true; // to show nested tables in dialogue subview, see IdTree::hasChildren() + + return BaseRefIdAdapter::getData (column, data, index); + } + + template + void LevelledListRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const + { + BaseRefIdAdapter::setData (column, data, index, value); + return; + } + + template + class NestedLevListRefIdAdapter : public NestedRefIdAdapterBase + { + UniversalId::Type mType; + + // not implemented + NestedLevListRefIdAdapter (const NestedLevListRefIdAdapter&); + NestedLevListRefIdAdapter& operator= (const NestedLevListRefIdAdapter&); + + public: + + NestedLevListRefIdAdapter(UniversalId::Type type) :mType(type) {} + + virtual ~NestedLevListRefIdAdapter() {} + + virtual void addNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int position) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + ESXRecordT leveled = record.get(); + + std::vector& list = leveled.mList; + + ESM::LevelledListBase::LevelItem newItem; + newItem.mId = ""; + newItem.mLevel = 0; + + if (position >= (int)list.size()) + list.push_back(newItem); + else + list.insert(list.begin()+position, newItem); + + record.setModified (leveled); + } + + virtual void removeNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int rowToRemove) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + ESXRecordT leveled = record.get(); + + std::vector& list = leveled.mList; + + if (rowToRemove < 0 || rowToRemove >= static_cast (list.size())) + throw std::runtime_error ("index out of range"); + + list.erase (list.begin () + rowToRemove); + + record.setModified (leveled); + } + + virtual void setNestedTable (const RefIdColumn* column, + RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + ESXRecordT leveled = record.get(); + + leveled.mList = + static_cast >&>(nestedTable).mNestedTable; + + record.setModified (leveled); + } + + virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, + const RefIdData& data, int index) const + { + const Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + + // deleted by dtor of NestedTableStoring + return new NestedTableWrapper >(record.get().mList); + } + + virtual QVariant getNestedData (const RefIdColumn *column, + const RefIdData& data, int index, int subRowIndex, int subColIndex) const + { + const Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + + const std::vector& list = record.get().mList; + + if (subRowIndex < 0 || subRowIndex >= static_cast (list.size())) + throw std::runtime_error ("index out of range"); + + const ESM::LevelledListBase::LevelItem& content = list.at(subRowIndex); + + switch (subColIndex) + { + case 0: return QString(content.mId.c_str()); + case 1: return content.mLevel; + default: + throw std::runtime_error("Trying to access non-existing column in the nested table!"); + } + } + + virtual void setNestedData (const RefIdColumn *column, + RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); + ESXRecordT leveled = record.get(); + std::vector& list = leveled.mList; + + if (subRowIndex < 0 || subRowIndex >= static_cast (list.size())) + throw std::runtime_error ("index out of range"); + + switch(subColIndex) + { + case 0: list.at(subRowIndex).mId = value.toString().toStdString(); break; + case 1: list.at(subRowIndex).mLevel = static_cast(value.toInt()); break; + default: + throw std::runtime_error("Trying to access non-existing column in the nested table!"); + } + + record.setModified (leveled); + } + + virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const + { + return 2; + } + + virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const + { + const Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + + return static_cast(record.get().mList.size()); + } + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 48f95451c5..be5d67766a 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -73,14 +73,13 @@ CSMWorld::RefIdCollection::RefIdCollection() // nested table PotionColumns potionColumns (inventoryColumns); - mColumns.push_back (RefIdColumn (Columns::ColumnId_EffectList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); + mColumns.push_back (RefIdColumn (Columns::ColumnId_EffectList, + ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); potionColumns.mEffects = &mColumns.back(); // see refidadapterimp.hpp - std::map effectsMap; - effectsMap.insert( - std::make_pair(UniversalId::Type_Potion, new EffectsRefIdAdapter (UniversalId::Type_Potion))); + effectsMap.insert(std::make_pair(UniversalId::Type_Potion, + new EffectsRefIdAdapter (UniversalId::Type_Potion))); mNestedAdapters.push_back (std::make_pair(&mColumns.back(), effectsMap)); - mColumns.back().addColumn( new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_String/*, false*/)); mColumns.back().addColumn( @@ -126,15 +125,14 @@ CSMWorld::RefIdCollection::RefIdCollection() actorsColumns.mAlarm = &mColumns.back(); // Nested table - mColumns.push_back(RefIdColumn (Columns::ColumnId_ActorInventory, ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue)); + mColumns.push_back(RefIdColumn (Columns::ColumnId_ActorInventory, + ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue)); actorsColumns.mInventory = &mColumns.back(); - std::map inventoryMap; - inventoryMap.insert( - std::make_pair(UniversalId::Type_Npc, new NestedInventoryRefIdAdapter (UniversalId::Type_Npc))); - inventoryMap.insert( - std::make_pair(UniversalId::Type_Creature, new NestedInventoryRefIdAdapter (UniversalId::Type_Creature))); - + inventoryMap.insert(std::make_pair(UniversalId::Type_Npc, + new NestedInventoryRefIdAdapter (UniversalId::Type_Npc))); + inventoryMap.insert(std::make_pair(UniversalId::Type_Creature, + new NestedInventoryRefIdAdapter (UniversalId::Type_Creature))); mNestedAdapters.push_back (std::make_pair(&mColumns.back(), inventoryMap)); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String)); @@ -142,28 +140,27 @@ CSMWorld::RefIdCollection::RefIdCollection() new RefIdColumn (Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer)); // Nested table - mColumns.push_back(RefIdColumn (Columns::ColumnId_SpellList, ColumnBase::Display_NestedSpellList, ColumnBase::Flag_Dialogue)); + mColumns.push_back(RefIdColumn (Columns::ColumnId_SpellList, + ColumnBase::Display_NestedSpellList, ColumnBase::Flag_Dialogue)); actorsColumns.mSpells = &mColumns.back(); - std::map spellsMap; - spellsMap.insert( - std::make_pair(UniversalId::Type_Npc, new NestedSpellRefIdAdapter (UniversalId::Type_Npc))); - spellsMap.insert( - std::make_pair(UniversalId::Type_Creature, new NestedSpellRefIdAdapter (UniversalId::Type_Creature))); - + spellsMap.insert(std::make_pair(UniversalId::Type_Npc, + new NestedSpellRefIdAdapter (UniversalId::Type_Npc))); + spellsMap.insert(std::make_pair(UniversalId::Type_Creature, + new NestedSpellRefIdAdapter (UniversalId::Type_Creature))); mNestedAdapters.push_back (std::make_pair(&mColumns.back(), spellsMap)); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_SpellId, CSMWorld::ColumnBase::Display_String)); // Nested table - mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcDestinations, ColumnBase::Display_NestedDestinationsList, ColumnBase::Flag_Dialogue)); + mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcDestinations, + ColumnBase::Display_NestedDestinationsList, ColumnBase::Flag_Dialogue)); actorsColumns.mDestinations = &mColumns.back(); - std::map destMap; - destMap.insert( - std::make_pair(UniversalId::Type_Npc, new NestedTravelRefIdAdapter (UniversalId::Type_Npc))); - destMap.insert( - std::make_pair(UniversalId::Type_Creature, new NestedTravelRefIdAdapter (UniversalId::Type_Creature))); + destMap.insert(std::make_pair(UniversalId::Type_Npc, + new NestedTravelRefIdAdapter (UniversalId::Type_Npc))); + destMap.insert(std::make_pair(UniversalId::Type_Creature, + new NestedTravelRefIdAdapter (UniversalId::Type_Creature))); mNestedAdapters.push_back (std::make_pair(&mColumns.back(), destMap)); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_DestinationCell, CSMWorld::ColumnBase::Display_String)); @@ -181,15 +178,14 @@ CSMWorld::RefIdCollection::RefIdCollection() new RefIdColumn (Columns::ColumnId_RotZ, CSMWorld::ColumnBase::Display_Float)); // Nested table - mColumns.push_back(RefIdColumn (Columns::ColumnId_AiPackageList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); + mColumns.push_back(RefIdColumn (Columns::ColumnId_AiPackageList, + ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); actorsColumns.mAiPackages = &mColumns.back(); - std::map aiMap; - aiMap.insert( - std::make_pair(UniversalId::Type_Npc, new ActorAiRefIdAdapter (UniversalId::Type_Npc))); - aiMap.insert( - std::make_pair(UniversalId::Type_Creature, new ActorAiRefIdAdapter (UniversalId::Type_Creature))); - + aiMap.insert(std::make_pair(UniversalId::Type_Npc, + new ActorAiRefIdAdapter (UniversalId::Type_Npc))); + aiMap.insert(std::make_pair(UniversalId::Type_Creature, + new ActorAiRefIdAdapter (UniversalId::Type_Creature))); mNestedAdapters.push_back (std::make_pair(&mColumns.back(), aiMap)); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_AiPackage, CSMWorld::ColumnBase::Display_String)); @@ -284,14 +280,13 @@ CSMWorld::RefIdCollection::RefIdCollection() const RefIdColumn *respawn = &mColumns.back(); // Nested table - mColumns.push_back(RefIdColumn (Columns::ColumnId_ContainerContent, ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue)); + mColumns.push_back(RefIdColumn (Columns::ColumnId_ContainerContent, + ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue)); const RefIdColumn *content = &mColumns.back(); - std::map contMap; - contMap.insert( - std::make_pair(UniversalId::Type_Container, new NestedInventoryRefIdAdapter (UniversalId::Type_Container))); + contMap.insert(std::make_pair(UniversalId::Type_Container, + new NestedInventoryRefIdAdapter (UniversalId::Type_Container))); mNestedAdapters.push_back (std::make_pair(&mColumns.back(), contMap)); - mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String)); mColumns.back().addColumn( @@ -478,20 +473,36 @@ CSMWorld::RefIdCollection::RefIdCollection() // Nested table mColumns.push_back(RefIdColumn (Columns::ColumnId_PartRefList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); const RefIdColumn *partRef = &mColumns.back(); - std::map partMap; - partMap.insert( - std::make_pair(UniversalId::Type_Armor, new BodyPartRefIdAdapter (UniversalId::Type_Armor))); - partMap.insert( - std::make_pair(UniversalId::Type_Clothing, new BodyPartRefIdAdapter (UniversalId::Type_Clothing))); - + partMap.insert(std::make_pair(UniversalId::Type_Armor, + new BodyPartRefIdAdapter (UniversalId::Type_Armor))); + partMap.insert(std::make_pair(UniversalId::Type_Clothing, + new BodyPartRefIdAdapter (UniversalId::Type_Clothing))); mNestedAdapters.push_back (std::make_pair(&mColumns.back(), partMap)); mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_PartRefType, CSMWorld::ColumnBase::Display_String)); + new RefIdColumn (Columns::ColumnId_PartRefType, CSMWorld::ColumnBase::Display_String)); mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_PartRefMale, CSMWorld::ColumnBase::Display_String)); + new RefIdColumn (Columns::ColumnId_PartRefMale, CSMWorld::ColumnBase::Display_String)); mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_PartRefFemale, CSMWorld::ColumnBase::Display_String)); + new RefIdColumn (Columns::ColumnId_PartRefFemale, CSMWorld::ColumnBase::Display_String)); + + LevListColumns levListColumns (baseColumns); + + // Nested table + mColumns.push_back(RefIdColumn (Columns::ColumnId_LevelledList, + ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); + levListColumns.mLevList = &mColumns.back(); + std::map levListMap; + levListMap.insert(std::make_pair(UniversalId::Type_CreatureLevelledList, + new NestedLevListRefIdAdapter (UniversalId::Type_CreatureLevelledList))); + levListMap.insert(std::make_pair(UniversalId::Type_ItemLevelledList, + new NestedLevListRefIdAdapter (UniversalId::Type_ItemLevelledList))); + mNestedAdapters.push_back (std::make_pair(&mColumns.back(), levListMap)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_LevelledItemId, CSMWorld::ColumnBase::Display_String)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_LevelledItemLevel, CSMWorld::ColumnBase::Display_Integer)); + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); @@ -514,10 +525,10 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Ingredient, new InventoryRefIdAdapter (UniversalId::Type_Ingredient, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_CreatureLevelledList, - new BaseRefIdAdapter ( - UniversalId::Type_CreatureLevelledList, baseColumns))); + new LevelledListRefIdAdapter ( + UniversalId::Type_CreatureLevelledList, levListColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_ItemLevelledList, - new BaseRefIdAdapter (UniversalId::Type_ItemLevelledList, baseColumns))); + new LevelledListRefIdAdapter (UniversalId::Type_ItemLevelledList, levListColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Light, new LightRefIdAdapter (lightColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Lockpick, From a2d824bfa6a9e4422cc2c754a05b18d01186b45a Mon Sep 17 00:00:00 2001 From: cc9cii Date: Fri, 17 Apr 2015 01:27:36 +1000 Subject: [PATCH 133/185] Changes to support dialogue only items but in a list view via QDataWidgetMapper. --- apps/opencs/model/world/columnbase.hpp | 13 +-- apps/opencs/model/world/idtree.cpp | 3 +- .../model/world/nestedtableproxymodel.cpp | 33 +++++-- .../model/world/nestedtableproxymodel.hpp | 4 +- apps/opencs/view/world/dialoguesubview.cpp | 96 ++++++++++++++++--- apps/opencs/view/world/dialoguesubview.hpp | 27 +++--- apps/opencs/view/world/util.cpp | 2 +- 7 files changed, 134 insertions(+), 44 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index c7c8d3cd8b..813de8d969 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -23,7 +23,8 @@ namespace CSMWorld enum Flags { Flag_Table = 1, // column should be displayed in table view - Flag_Dialogue = 2 // column should be displayed in dialogue view + Flag_Dialogue = 2, // column should be displayed in dialogue view + Flag_Dialogue_List = 4 // column should be diaplyed in dialogue view }; enum Display @@ -94,11 +95,11 @@ namespace CSMWorld Display_QuestStatusType, //Those are top level columns that nest other columns - Display_NestedItemList, - Display_NestedSpellList, - Display_NestedDestinationsList, - Display_PathgridPointList, - Display_PathgridEdgeList, + Display_NestedItemList, // delete? + Display_NestedSpellList, // delete? + Display_NestedDestinationsList, // delete? + Display_PathgridPointList, // delete? + Display_PathgridEdgeList, // delete? Display_NestedHeader, Display_EnchantmentType, diff --git a/apps/opencs/model/world/idtree.cpp b/apps/opencs/model/world/idtree.cpp index eddde5a898..06db09a0fc 100644 --- a/apps/opencs/model/world/idtree.cpp +++ b/apps/opencs/model/world/idtree.cpp @@ -93,8 +93,7 @@ bool CSMWorld::IdTree::setData (const QModelIndex &index, const QVariant &value, mNestedCollection->setNestedData(parentAddress.first, parentAddress.second, value, index.row(), index.column()); emit dataChanged (CSMWorld::IdTree::index (parentAddress.first, 0), - CSMWorld::IdTree::index (parentAddress.second, idCollection()->getColumns()-1)); - + CSMWorld::IdTree::index (parentAddress.first, idCollection()->getColumns()-1)); return true; } else diff --git a/apps/opencs/model/world/nestedtableproxymodel.cpp b/apps/opencs/model/world/nestedtableproxymodel.cpp index 0f137d78f8..acf1977168 100644 --- a/apps/opencs/model/world/nestedtableproxymodel.cpp +++ b/apps/opencs/model/world/nestedtableproxymodel.cpp @@ -32,12 +32,15 @@ CSMWorld::NestedTableProxyModel::NestedTableProxyModel(const QModelIndex& parent connect(mMainModel, SIGNAL(resetEnd(const QString&)), this, SLOT(forwardResetEnd(const QString&))); + + connect(mMainModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), + this, SLOT(forwardDataChanged(const QModelIndex &, const QModelIndex &))); } QModelIndex CSMWorld::NestedTableProxyModel::mapFromSource(const QModelIndex& sourceIndex) const { const QModelIndex& testedParent = mMainModel->parent(sourceIndex); - const QModelIndex& parent = mMainModel->getModelIndex (mId, mParentColumn); + const QModelIndex& parent = mMainModel->getNestedModelIndex (mId, mParentColumn); if (testedParent == parent) { return createIndex(sourceIndex.row(), sourceIndex.column()); @@ -75,13 +78,8 @@ QModelIndex CSMWorld::NestedTableProxyModel::index(int row, int column, const QM int rows = mMainModel->rowCount(parent); int columns = mMainModel->columnCount(parent); - if (row < 0 || - row >= rows || - column < 0 || - column >= columns) - { + if (row < 0 || row >= rows || column < 0 || column >= columns) return QModelIndex(); - } return createIndex(row, column); } @@ -103,6 +101,9 @@ QVariant CSMWorld::NestedTableProxyModel::data(const QModelIndex& index, int rol return mMainModel->data(mapToSource(index), role); } +// NOTE: Due to mapToSouce(index) the dataChanged() signal resulting from setData() will have the +// source model's index values. The indicies need to be converted to the proxy space values. +// See forwardDataChanged() bool CSMWorld::NestedTableProxyModel::setData (const QModelIndex & index, const QVariant & value, int role) { return mMainModel->setData(mapToSource(index), value, role); @@ -128,7 +129,8 @@ CSMWorld::IdTree* CSMWorld::NestedTableProxyModel::model() const return mMainModel; } -void CSMWorld::NestedTableProxyModel::forwardRowsAboutToInserted(const QModelIndex& parent, int first, int last) +void CSMWorld::NestedTableProxyModel::forwardRowsAboutToInserted(const QModelIndex& parent, + int first, int last) { if (indexIsParent(parent)) { @@ -151,7 +153,8 @@ bool CSMWorld::NestedTableProxyModel::indexIsParent(const QModelIndex& index) mMainModel->data(mMainModel->index(index.row(), 0)).toString().toUtf8().constData() == mId); } -void CSMWorld::NestedTableProxyModel::forwardRowsAboutToRemoved(const QModelIndex& parent, int first, int last) +void CSMWorld::NestedTableProxyModel::forwardRowsAboutToRemoved(const QModelIndex& parent, + int first, int last) { if (indexIsParent(parent)) { @@ -178,3 +181,15 @@ void CSMWorld::NestedTableProxyModel::forwardResetEnd(const QString& id) if (id.toUtf8() == mId.c_str()) endResetModel(); } + +void CSMWorld::NestedTableProxyModel::forwardDataChanged (const QModelIndex& topLeft, + const QModelIndex& bottomRight) +{ + const QModelIndex& parent = mMainModel->getNestedModelIndex (mId, mParentColumn); + + if (topLeft.column() <= parent.column() && bottomRight.column() >= parent.column()) + { + emit dataChanged(index(0,0), + index(mMainModel->rowCount(parent)-1, mMainModel->columnCount(parent)-1)); + } +} diff --git a/apps/opencs/model/world/nestedtableproxymodel.hpp b/apps/opencs/model/world/nestedtableproxymodel.hpp index f5cbdb10b4..2d5a46c482 100644 --- a/apps/opencs/model/world/nestedtableproxymodel.hpp +++ b/apps/opencs/model/world/nestedtableproxymodel.hpp @@ -47,7 +47,7 @@ namespace CSMWorld virtual int columnCount(const QModelIndex& parent) const; - virtual QModelIndex index(int row, int column, const QModelIndex& parent) const; + virtual QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const; virtual QModelIndex parent(const QModelIndex& index) const; @@ -76,6 +76,8 @@ namespace CSMWorld void forwardResetStart(const QString& id); void forwardResetEnd(const QString& id); + + void forwardDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); }; } diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 79eb48534a..88791c9cda 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -28,6 +28,7 @@ #include "../../model/world/columns.hpp" #include "../../model/world/record.hpp" #include "../../model/world/tablemimedata.hpp" +#include "../../model/world/idtree.hpp" #include "../../model/doc/document.hpp" #include "../../model/world/commands.hpp" @@ -175,9 +176,10 @@ void CSVWorld::DialogueDelegateDispatcherProxy::tableMimeDataDropped(const std:: ==============================DialogueDelegateDispatcher========================================== */ -CSVWorld::DialogueDelegateDispatcher::DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, CSMDoc::Document& document) : +CSVWorld::DialogueDelegateDispatcher::DialogueDelegateDispatcher(QObject* parent, + CSMWorld::IdTable* table, CSMDoc::Document& document, QAbstractItemModel *model) : mParent(parent), -mTable(table), +mTable(model ? model : table), mDocument (document), mNotEditableDelegate(table, parent) { @@ -199,7 +201,8 @@ CSVWorld::CommandDelegate* CSVWorld::DialogueDelegateDispatcher::makeDelegate(CS return delegate; } -void CSVWorld::DialogueDelegateDispatcher::editorDataCommited(QWidget* editor, const QModelIndex& index, CSMWorld::ColumnBase::Display display) +void CSVWorld::DialogueDelegateDispatcher::editorDataCommited(QWidget* editor, + const QModelIndex& index, CSMWorld::ColumnBase::Display display) { setModelData(editor, mTable, index, display); } @@ -231,12 +234,14 @@ void CSVWorld::DialogueDelegateDispatcher::setEditorData (QWidget* editor, const } } -void CSVWorld::DialogueDelegateDispatcher::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const +void CSVWorld::DialogueDelegateDispatcher::setModelData(QWidget* editor, + QAbstractItemModel* model, const QModelIndex& index) const { setModelData(editor, model, index, CSMWorld::ColumnBase::Display_None); } -void CSVWorld::DialogueDelegateDispatcher::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const +void CSVWorld::DialogueDelegateDispatcher::setModelData(QWidget* editor, + QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const { std::map::const_iterator delegateIt(mDelegates.find(display)); if (delegateIt != mDelegates.end()) @@ -245,17 +250,20 @@ void CSVWorld::DialogueDelegateDispatcher::setModelData(QWidget* editor, QAbstra } } -void CSVWorld::DialogueDelegateDispatcher::paint (QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const +void CSVWorld::DialogueDelegateDispatcher::paint (QPainter* painter, + const QStyleOptionViewItem& option, const QModelIndex& index) const { //Does nothing } -QSize CSVWorld::DialogueDelegateDispatcher::sizeHint (const QStyleOptionViewItem& option, const QModelIndex& index) const +QSize CSVWorld::DialogueDelegateDispatcher::sizeHint (const QStyleOptionViewItem& option, + const QModelIndex& index) const { return QSize(); //silencing warning, otherwise does nothing } -QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase::Display display, const QModelIndex& index) +QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase::Display display, + const QModelIndex& index) { QVariant variant = index.data(); if (!variant.isValid()) @@ -270,14 +278,16 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase:: QWidget* editor = NULL; if (! (mTable->flags (index) & Qt::ItemIsEditable)) { - return mNotEditableDelegate.createEditor(qobject_cast(mParent), QStyleOptionViewItem(), index); + return mNotEditableDelegate.createEditor(qobject_cast(mParent), + QStyleOptionViewItem(), index); } std::map::iterator delegateIt(mDelegates.find(display)); if (delegateIt != mDelegates.end()) { - editor = delegateIt->second->createEditor(qobject_cast(mParent), QStyleOptionViewItem(), index, display); + editor = delegateIt->second->createEditor(qobject_cast(mParent), + QStyleOptionViewItem(), index, display); DialogueDelegateDispatcherProxy* proxy = new DialogueDelegateDispatcherProxy(editor, display); @@ -339,12 +349,15 @@ CSVWorld::EditWidget::~EditWidget() { delete mNestedModels[i]; } + delete mNestedTableDispatcher; } CSVWorld::EditWidget::EditWidget(QWidget *parent, int row, CSMWorld::IdTable* table, CSMDoc::Document& document, bool createAndDelete) : mDispatcher(this, table, document), +mNestedTableDispatcher(NULL), QScrollArea(parent), mWidgetMapper(NULL), +mNestedTableMapper(NULL), mMainWidget(NULL), mDocument (document), mTable(table) @@ -362,6 +375,7 @@ void CSVWorld::EditWidget::remake(int row) delete mNestedModels[i]; } mNestedModels.clear(); + delete mNestedTableDispatcher; if (mMainWidget) { @@ -376,6 +390,11 @@ void CSVWorld::EditWidget::remake(int row) delete mWidgetMapper; mWidgetMapper = 0; } + if (mNestedTableMapper) + { + delete mNestedTableMapper; + mNestedTableMapper = 0; + } mWidgetMapper = new QDataWidgetMapper (this); mWidgetMapper->setModel(mTable); @@ -417,7 +436,8 @@ void CSVWorld::EditWidget::remake(int row) CSMWorld::ColumnBase::Display display = static_cast (mTable->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); - if (mTable->hasChildren(mTable->index(row, i))) + if (mTable->hasChildren(mTable->index(row, i)) && + !(flags & CSMWorld::ColumnBase::Flag_Dialogue_List)) { mNestedModels.push_back(new CSMWorld::NestedTableProxyModel (mTable->index(row, i), display, dynamic_cast(mTable))); @@ -425,14 +445,15 @@ void CSVWorld::EditWidget::remake(int row) table->resizeColumnsToContents(); - QLabel* label = new QLabel (mTable->headerData (i, Qt::Horizontal, Qt::DisplayRole).toString(), mMainWidget); + QLabel* label = + new QLabel (mTable->headerData (i, Qt::Horizontal, Qt::DisplayRole).toString(), mMainWidget); label->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed); tablesLayout->addWidget(label); tablesLayout->addWidget(table); } - else + else if (!(flags & CSMWorld::ColumnBase::Flag_Dialogue_List)) { mDispatcher.makeDelegate (display); QWidget* editor = mDispatcher.makeEditor (display, (mTable->index (row, i))); @@ -460,6 +481,55 @@ void CSVWorld::EditWidget::remake(int row) } } } + else + { + mNestedModels.push_back(new CSMWorld::NestedTableProxyModel ( + static_cast(mTable)->index(row, i), + display, static_cast(mTable))); + mNestedTableMapper = new QDataWidgetMapper (this); + + mNestedTableMapper->setModel(mNestedModels.back()); + // FIXME: lack MIME support? + mNestedTableDispatcher = + new DialogueDelegateDispatcher (this, mTable, mDocument, mNestedModels.back()); + mNestedTableMapper->setItemDelegate(mNestedTableDispatcher); + + int columnCount = + mTable->columnCount(mTable->getModelIndex (mNestedModels.back()->getParentId(), i)); + for (int col = 0; col < columnCount; ++col) + { + int displayRole = mNestedModels.back()->headerData (col, + Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt(); + + CSMWorld::ColumnBase::Display display = + static_cast (displayRole); + + mNestedTableDispatcher->makeDelegate (display); + + // FIXME: assumed all columns are editable + QWidget* editor = + mNestedTableDispatcher->makeEditor (display, mNestedModels.back()->index (0, col)); + if (editor) + { + mNestedTableMapper->addMapping (editor, col); + + std::string disString = mNestedModels.back()->headerData (col, + Qt::Horizontal, Qt::DisplayRole).toString().toStdString(); + // Need ot use Qt::DisplayRole in order to get the correct string + // from CSMWorld::Columns + QLabel* label = new QLabel (mNestedModels.back()->headerData (col, + Qt::Horizontal, Qt::DisplayRole).toString(), mMainWidget); + + label->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed); + editor->setSizePolicy (QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + + unlockedLayout->addWidget (label, unlocked, 0); + unlockedLayout->addWidget (editor, unlocked, 1); + ++unlocked; + } + } + mNestedTableMapper->setCurrentModelIndex(mNestedModels.back()->index(0, 0)); + } } } diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index 72acb19669..067ff95f52 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -107,9 +107,9 @@ namespace CSVWorld QObject* mParent; - CSMWorld::IdTable* mTable; + QAbstractItemModel* mTable; - CSMDoc::Document& mDocument; + CSMDoc::Document& mDocument; NotEditableSubDelegate mNotEditableDelegate; @@ -119,22 +119,25 @@ namespace CSVWorld public: DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, - CSMDoc::Document& document); + CSMDoc::Document& document, + QAbstractItemModel* model = 0); ~DialogueDelegateDispatcher(); CSVWorld::CommandDelegate* makeDelegate(CSMWorld::ColumnBase::Display display); - QWidget* makeEditor(CSMWorld::ColumnBase::Display display, - const QModelIndex& index); - ///< will return null if delegate is not present, parent of the widget is same as for dispatcher itself + QWidget* makeEditor(CSMWorld::ColumnBase::Display display, const QModelIndex& index); + ///< will return null if delegate is not present, parent of the widget is + //same as for dispatcher itself - virtual void setEditorData (QWidget* editor, - const QModelIndex& index) const; + virtual void setEditorData (QWidget* editor, const QModelIndex& index) const; - virtual void setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const; + virtual void setModelData (QWidget* editor, QAbstractItemModel* model, + const QModelIndex& index) const; - virtual void setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const; + virtual void setModelData (QWidget* editor, + QAbstractItemModel* model, const QModelIndex& index, + CSMWorld::ColumnBase::Display display) const; virtual void paint (QPainter* painter, const QStyleOptionViewItem& option, @@ -153,15 +156,15 @@ namespace CSVWorld void tableMimeDataDropped(QWidget* editor, const QModelIndex& index, const CSMWorld::UniversalId& id, const CSMDoc::Document* document); - - }; class EditWidget : public QScrollArea { Q_OBJECT QDataWidgetMapper *mWidgetMapper; + QDataWidgetMapper *mNestedTableMapper; DialogueDelegateDispatcher mDispatcher; + DialogueDelegateDispatcher *mNestedTableDispatcher; QWidget* mMainWidget; CSMWorld::IdTable* mTable; CSMDoc::Document& mDocument; diff --git a/apps/opencs/view/world/util.cpp b/apps/opencs/view/world/util.cpp index f3b23100a6..5694c6e5ab 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -180,7 +180,7 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO case CSMWorld::ColumnBase::Display_Float: { QDoubleSpinBox *dsb = new QDoubleSpinBox(parent); - dsb->setRange(FLT_MIN, FLT_MAX); + dsb->setRange(-FLT_MAX, FLT_MAX); dsb->setSingleStep(0.01f); dsb->setDecimals(3); return dsb; From 32e73c3debf67f5cfb64671daca1c32b8d12dd4a Mon Sep 17 00:00:00 2001 From: cc9cii Date: Fri, 17 Apr 2015 11:50:19 +1000 Subject: [PATCH 134/185] Add creature/item levelled lists (non table items) to dialogue subview. --- apps/opencs/model/world/columns.cpp | 76 ++++++------ apps/opencs/model/world/columns.hpp | 2 + apps/opencs/model/world/refidadapterimp.hpp | 131 +++++++++++++++++++- apps/opencs/model/world/refidcollection.cpp | 14 +++ 4 files changed, 185 insertions(+), 38 deletions(-) diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 83d6ceb57f..81968d1144 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -223,49 +223,51 @@ namespace CSMWorld { ColumnId_AreaSound, "Area Sound" }, { ColumnId_BoltSound, "Bolt Sound" }, - { ColumnId_PathgridPoints, "Points"}, - { ColumnId_PathgridIndex, "Index"}, - { ColumnId_PathgridPosX, "X"}, - { ColumnId_PathgridPosY, "Y"}, - { ColumnId_PathgridPosZ, "Z"}, - { ColumnId_PathgridEdges, "Edges"}, - { ColumnId_PathgridEdgeIndex, "Index"}, - { ColumnId_PathgridEdge0, "Point 0"}, - { ColumnId_PathgridEdge1, "Point 1"}, + { ColumnId_PathgridPoints, "Points" }, + { ColumnId_PathgridIndex, "Index" }, + { ColumnId_PathgridPosX, "X" }, + { ColumnId_PathgridPosY, "Y" }, + { ColumnId_PathgridPosZ, "Z" }, + { ColumnId_PathgridEdges, "Edges" }, + { ColumnId_PathgridEdgeIndex, "Index" }, + { ColumnId_PathgridEdge0, "Point 0" }, + { ColumnId_PathgridEdge1, "Point 1" }, - { ColumnId_RegionSounds, "Sounds"}, - { ColumnId_SoundName, "Name"}, - { ColumnId_SoundChance, "Chance"}, + { ColumnId_RegionSounds, "Sounds" }, + { ColumnId_SoundName, "Name" }, + { ColumnId_SoundChance, "Chance" }, - { ColumnId_FactionReactions, "Reactions"}, - //{ ColumnId_FactionID, "Faction ID"}, - { ColumnId_FactionReaction, "Reaction"}, + { ColumnId_FactionReactions, "Reactions" }, + //{ ColumnId_FactionID, "Faction ID" }, + { ColumnId_FactionReaction, "Reaction" }, - { ColumnId_EffectList, "Effects"}, - { ColumnId_EffectId, "Effect"}, - //{ ColumnId_EffectAttribute, "Attrib"}, - { ColumnId_EffectRange, "Range"}, - { ColumnId_EffectArea, "Area"}, + { ColumnId_EffectList, "Effects" }, + { ColumnId_EffectId, "Effect" }, + //{ ColumnId_EffectAttribute, "Attrib" }, + { ColumnId_EffectRange, "Range" }, + { ColumnId_EffectArea, "Area" }, - { ColumnId_AiPackageList, "Ai Packages"}, - { ColumnId_AiPackage, "Package"}, - { ColumnId_AiWanderDist, "Wander Dist"}, - { ColumnId_AiDuration, "Duration"}, - { ColumnId_AiWanderToD, "Wander ToD"}, - { ColumnId_AiWanderIdle, "Wander Idle"}, - { ColumnId_AiWanderRepeat, "Wander Repeat"}, - { ColumnId_AiActivateName, "Activate"}, - { ColumnId_AiTargetId, "Target ID"}, - { ColumnId_AiTargetCell, "Target Cell"}, + { ColumnId_AiPackageList, "Ai Packages" }, + { ColumnId_AiPackage, "Package" }, + { ColumnId_AiWanderDist, "Wander Dist" }, + { ColumnId_AiDuration, "Duration" }, + { ColumnId_AiWanderToD, "Wander ToD" }, + { ColumnId_AiWanderIdle, "Wander Idle" }, + { ColumnId_AiWanderRepeat, "Wander Repeat" }, + { ColumnId_AiActivateName, "Activate" }, + { ColumnId_AiTargetId, "Target ID" }, + { ColumnId_AiTargetCell, "Target Cell" }, - { ColumnId_PartRefList, "Part Reference"}, - { ColumnId_PartRefType, "Type"}, - { ColumnId_PartRefMale, "Male"}, - { ColumnId_PartRefFemale, "Female"}, + { ColumnId_PartRefList, "Part Reference" }, + { ColumnId_PartRefType, "Type" }, + { ColumnId_PartRefMale, "Male" }, + { ColumnId_PartRefFemale, "Female" }, - { ColumnId_LevelledList,"Levelled List"}, - { ColumnId_LevelledItemId,"Item ID"}, - { ColumnId_LevelledItemLevel,"Level"}, + { ColumnId_LevelledList,"Levelled List" }, + { ColumnId_LevelledItemId,"Item ID" }, + { ColumnId_LevelledItemLevel,"Level" }, + { ColumnId_LevelledItemType, "Type" }, + { ColumnId_LevelledItemChanceNone, "Chance None" }, { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 81cae5e369..986b90df54 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -256,6 +256,8 @@ namespace CSMWorld ColumnId_LevelledList = 233, ColumnId_LevelledItemId = 234, ColumnId_LevelledItemLevel = 235, + ColumnId_LevelledItemType = 236, + ColumnId_LevelledItemChanceNone = 237, // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index d09aaaa454..2b2b189e09 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -1829,9 +1829,11 @@ namespace CSMWorld } }; + struct LevListColumns : public BaseColumns { const RefIdColumn *mLevList; + const RefIdColumn *mNestedListLevList; LevListColumns (const BaseColumns& base) : BaseColumns (base) {} }; @@ -1863,7 +1865,7 @@ namespace CSMWorld QVariant LevelledListRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, int index) const { - if (column==mLevList.mLevList) + if (column==mLevList.mLevList || column == mLevList.mNestedListLevList) return true; // to show nested tables in dialogue subview, see IdTree::hasChildren() return BaseRefIdAdapter::getData (column, data, index); @@ -1877,6 +1879,133 @@ namespace CSMWorld return; } + + template + class NestedListLevListRefIdAdapter : public NestedRefIdAdapterBase + { + + UniversalId::Type mType; + + // not implemented + NestedListLevListRefIdAdapter (const NestedListLevListRefIdAdapter&); + NestedListLevListRefIdAdapter& operator= (const NestedListLevListRefIdAdapter&); + + public: + + NestedListLevListRefIdAdapter(UniversalId::Type type) + :mType(type) {} + + virtual ~NestedListLevListRefIdAdapter() {} + + virtual void addNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int position) const + { + throw std::logic_error ("cannot add a row to a fixed table"); + } + + virtual void removeNestedRow (const RefIdColumn *column, + RefIdData& data, int index, int rowToRemove) const + { + throw std::logic_error ("cannot remove a row to a fixed table"); + } + + virtual void setNestedTable (const RefIdColumn* column, + RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const + { + throw std::logic_error ("table operation not supported"); + } + + virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, + const RefIdData& data, int index) const + { + throw std::logic_error ("table operation not supported"); + } + + virtual QVariant getNestedData (const RefIdColumn *column, + const RefIdData& data, int index, int subRowIndex, int subColIndex) const + { + const Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + + switch (subColIndex) + { + case 0: + { + if (mType == CSMWorld::UniversalId::Type_CreatureLevelledList && + record.get().mFlags == 0x01) + { + return QString("All Levels"); + } + else if(mType == CSMWorld::UniversalId::Type_ItemLevelledList && + record.get().mFlags == 0x01) + { + return QString("Each"); + } + else if(mType == CSMWorld::UniversalId::Type_ItemLevelledList && + record.get().mFlags == 0x02) + { + return QString("All Levels"); + } + else + throw std::runtime_error("unknown leveled list type"); + } + case 1: return static_cast (record.get().mChanceNone); + default: + throw std::runtime_error("Trying to access non-existing column in the nested table!"); + } + } + + virtual void setNestedData (const RefIdColumn *column, + RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const + { + Record& record = + static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); + ESXRecordT leveled = record.get(); + + switch(subColIndex) + { + case 0: + { + if (mType == CSMWorld::UniversalId::Type_CreatureLevelledList && + value.toString().toStdString() == "All Levels") + { + leveled.mFlags = 0x01; + break; + } + else if(mType == CSMWorld::UniversalId::Type_ItemLevelledList && + value.toString().toStdString() == "Each") + { + leveled.mFlags = 0x01; + break; + } + else if(mType == CSMWorld::UniversalId::Type_ItemLevelledList && + value.toString().toStdString() == "All Levels") + { + leveled.mFlags = 0x02; + break; + } + else + return; // return without saving + } + case 1: leveled.mChanceNone = static_cast(value.toInt()); break; + default: + throw std::runtime_error("Trying to access non-existing column in the nested table!"); + } + + record.setModified (leveled); + } + + virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const + { + return 2; + } + + virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const + { + return 1; // fixed at size 1 + } + }; + template class NestedLevListRefIdAdapter : public NestedRefIdAdapterBase { diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index be5d67766a..02d876df89 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -503,6 +503,20 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_LevelledItemLevel, CSMWorld::ColumnBase::Display_Integer)); + // Nested list + mColumns.push_back(RefIdColumn (Columns::ColumnId_LevelledList, + ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List)); + levListColumns.mNestedListLevList = &mColumns.back(); + std::map nestedListLevListMap; + nestedListLevListMap.insert(std::make_pair(UniversalId::Type_CreatureLevelledList, + new NestedListLevListRefIdAdapter (UniversalId::Type_CreatureLevelledList))); + nestedListLevListMap.insert(std::make_pair(UniversalId::Type_ItemLevelledList, + new NestedListLevListRefIdAdapter (UniversalId::Type_ItemLevelledList))); + mNestedAdapters.push_back (std::make_pair(&mColumns.back(), nestedListLevListMap)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_LevelledItemType, CSMWorld::ColumnBase::Display_String)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_LevelledItemChanceNone, CSMWorld::ColumnBase::Display_Integer)); mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); From c41b4b84a6b9421496cc1a66e34a84e1b9434b31 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Fri, 17 Apr 2015 13:45:45 +1000 Subject: [PATCH 135/185] Cleanup post merge. --- apps/opencs/model/world/columnbase.hpp | 16 +++++----------- apps/opencs/model/world/columns.cpp | 2 ++ apps/opencs/model/world/columns.hpp | 2 ++ apps/opencs/model/world/data.cpp | 4 ++-- apps/opencs/model/world/refidcollection.cpp | 8 ++++---- 5 files changed, 15 insertions(+), 17 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 197fb5ad30..437d07f97d 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -93,15 +93,6 @@ namespace CSMWorld Display_RefRecordType, Display_DialogueType, Display_QuestStatusType, - - //Those are top level columns that nest other columns - Display_NestedItemList, // delete? - Display_NestedSpellList, // delete? - Display_NestedDestinationsList, // delete? - Display_PathgridPointList, // delete? - Display_PathgridEdgeList, // delete? - Display_NestedHeader, - Display_EnchantmentType, Display_BodyPartType, Display_MeshType, @@ -117,7 +108,10 @@ namespace CSMWorld Display_ScriptLines, // console context Display_SoundGeneratorType, Display_School, - Display_Id + Display_Id, + + //top level columns that nest other columns + Display_NestedHeader }; int mColumnId; @@ -135,7 +129,7 @@ namespace CSMWorld virtual std::string getTitle() const; - virtual int getId() const; // FIXME: why have an accessor for a public member? + virtual int getId() const; static bool isId (Display display); diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 81968d1144..ff28a12898 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -269,6 +269,8 @@ namespace CSMWorld { ColumnId_LevelledItemType, "Type" }, { ColumnId_LevelledItemChanceNone, "Chance None" }, + { ColumnId_PowerList, "Powers" }, + { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, { ColumnId_UseValue3, "Use value 3" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 986b90df54..7c28f9589a 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -259,6 +259,8 @@ namespace CSMWorld ColumnId_LevelledItemType = 236, ColumnId_LevelledItemChanceNone = 237, + ColumnId_PowerList = 238, + // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. ColumnId_UseValue1 = 0x10000, diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index d7280e354b..5733fd83f3 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -131,7 +131,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mRaces.addColumn (new WeightHeightColumn (false, true)); mRaces.addColumn (new WeightHeightColumn (false, false)); // Race spells - mRaces.addColumn (new NestedParentColumn (Columns::ColumnId_SpellList)); + mRaces.addColumn (new NestedParentColumn (Columns::ColumnId_PowerList)); index = mRaces.getColumns()-1; mRaces.addAdapter (std::make_pair(&mRaces.getColumn(index), new SpellListAdapter ())); mRaces.getNestableColumn(index)->addColumn( @@ -172,7 +172,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mBirthsigns.addColumn (new TextureColumn); mBirthsigns.addColumn (new DescriptionColumn); // Birthsign spells - mBirthsigns.addColumn (new NestedParentColumn (Columns::ColumnId_SpellList)); + mBirthsigns.addColumn (new NestedParentColumn (Columns::ColumnId_PowerList)); index = mBirthsigns.getColumns()-1; mBirthsigns.addAdapter (std::make_pair(&mBirthsigns.getColumn(index), new SpellListAdapter ())); diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index d133f3ba94..2e53c2b1c7 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -126,7 +126,7 @@ CSMWorld::RefIdCollection::RefIdCollection() // Nested table mColumns.push_back(RefIdColumn (Columns::ColumnId_ActorInventory, - ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue)); + ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); actorsColumns.mInventory = &mColumns.back(); std::map inventoryMap; inventoryMap.insert(std::make_pair(UniversalId::Type_Npc, @@ -141,7 +141,7 @@ CSMWorld::RefIdCollection::RefIdCollection() // Nested table mColumns.push_back(RefIdColumn (Columns::ColumnId_SpellList, - ColumnBase::Display_NestedSpellList, ColumnBase::Flag_Dialogue)); + ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); actorsColumns.mSpells = &mColumns.back(); std::map spellsMap; spellsMap.insert(std::make_pair(UniversalId::Type_Npc, @@ -154,7 +154,7 @@ CSMWorld::RefIdCollection::RefIdCollection() // Nested table mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcDestinations, - ColumnBase::Display_NestedDestinationsList, ColumnBase::Flag_Dialogue)); + ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); actorsColumns.mDestinations = &mColumns.back(); std::map destMap; destMap.insert(std::make_pair(UniversalId::Type_Npc, @@ -281,7 +281,7 @@ CSMWorld::RefIdCollection::RefIdCollection() // Nested table mColumns.push_back(RefIdColumn (Columns::ColumnId_ContainerContent, - ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue)); + ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)); const RefIdColumn *content = &mColumns.back(); std::map contMap; contMap.insert(std::make_pair(UniversalId::Type_Container, From d6c2cff381a356331ed3852d8799967b4fec9196 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Fri, 17 Apr 2015 21:33:25 +1000 Subject: [PATCH 136/185] Convert magic effects Attribute column in the nested tables to use enum delegates. --- apps/opencs/model/world/data.cpp | 4 +-- .../model/world/nestedcoladapterimp.hpp | 34 ++----------------- apps/opencs/model/world/refidcollection.cpp | 2 +- 3 files changed, 5 insertions(+), 35 deletions(-) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 5733fd83f3..843d08281f 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -197,7 +197,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mSpells.getNestableColumn(index)->addColumn( new NestedChildColumn (Columns::ColumnId_Skill, ColumnBase::Display_String)); mSpells.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_String)); // reuse attribute + new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_Attribute)); // reuse attribute mSpells.getNestableColumn(index)->addColumn( new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_Integer)); mSpells.getNestableColumn(index)->addColumn( @@ -271,7 +271,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mEnchantments.getNestableColumn(index)->addColumn( new NestedChildColumn (Columns::ColumnId_Skill, ColumnBase::Display_String)); mEnchantments.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_String)); // reuse attribute + new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_Attribute)); // reuse attribute mEnchantments.getNestableColumn(index)->addColumn( new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_Integer)); mEnchantments.getNestableColumn(index)->addColumn( diff --git a/apps/opencs/model/world/nestedcoladapterimp.hpp b/apps/opencs/model/world/nestedcoladapterimp.hpp index 2aa1123a3a..951c7a6101 100644 --- a/apps/opencs/model/world/nestedcoladapterimp.hpp +++ b/apps/opencs/model/world/nestedcoladapterimp.hpp @@ -354,23 +354,7 @@ namespace CSMWorld } case 2: { - switch (effect.mAttribute) - { - // see ESM::Attribute::AttributeID in - case ESM::Attribute::Strength: - case ESM::Attribute::Intelligence: - case ESM::Attribute::Willpower: - case ESM::Attribute::Agility: - case ESM::Attribute::Speed: - case ESM::Attribute::Endurance: - case ESM::Attribute::Personality: - case ESM::Attribute::Luck: - { - return QString(ESM::Attribute::sAttributeNames[effect.mAttribute].c_str()); - } - case -1: return QString("N/A"); - default: return QVariant(); - } + return effect.mAttribute; } case 3: { @@ -431,21 +415,7 @@ namespace CSMWorld } case 2: { - std::string attr = value.toString().toStdString(); - if ("N/A" == attr) - { - effect.mAttribute = -1; - break; - } - - for (unsigned int i = 0; i < ESM::Attribute::Length; ++i) - { - if (ESM::Attribute::sAttributeNames[i] == attr) - { - effect.mAttribute = static_cast(i); - break; - } - } + effect.mAttribute = static_cast(value.toInt()); break; } case 3: diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 2e53c2b1c7..92fbfd08e0 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -85,7 +85,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.back().addColumn( new NestedChildColumn (Columns::ColumnId_Skill, ColumnBase::Display_String)); mColumns.back().addColumn( - new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_String)); // reuse attribute + new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_Attribute)); // reuse attribute mColumns.back().addColumn( new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_Integer)); mColumns.back().addColumn( From 20af2b67a838dbda3fe1e622b0a25d058e813427 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 17 Apr 2015 18:54:14 +0200 Subject: [PATCH 137/185] Change the triangle pattern used for terrain (Fixes #2459) --- components/terrain/buffercache.cpp | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/components/terrain/buffercache.cpp b/components/terrain/buffercache.cpp index 01032bcdae..1b000fabb1 100644 --- a/components/terrain/buffercache.cpp +++ b/components/terrain/buffercache.cpp @@ -59,13 +59,27 @@ Ogre::HardwareIndexBufferSharedPtr createIndexBuffer(unsigned int flags, unsigne { for (size_t col = colStart; col < colEnd; col += increment) { - indices.push_back(verts*col+row); - indices.push_back(verts*(col+increment)+row+increment); - indices.push_back(verts*col+row+increment); + // diamond pattern + if ((row + col%2) % 2 == 1) + { + indices.push_back(verts*(col+increment)+row); + indices.push_back(verts*(col+increment)+row+increment); + indices.push_back(verts*col+row+increment); - indices.push_back(verts*col+row); - indices.push_back(verts*(col+increment)+row); - indices.push_back(verts*(col+increment)+row+increment); + indices.push_back(verts*col+row); + indices.push_back(verts*(col+increment)+row); + indices.push_back(verts*(col)+row+increment); + } + else + { + indices.push_back(verts*col+row); + indices.push_back(verts*(col+increment)+row+increment); + indices.push_back(verts*col+row+increment); + + indices.push_back(verts*col+row); + indices.push_back(verts*(col+increment)+row); + indices.push_back(verts*(col+increment)+row+increment); + } } } From 0aff188d8d0b230e725665bf37dc87d70a0f9398 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 18 Apr 2015 07:13:02 +1000 Subject: [PATCH 138/185] Fix enum delegate from adding a command to the undo stack when the value has not changed. --- apps/opencs/view/world/enumdelegate.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/world/enumdelegate.cpp b/apps/opencs/view/world/enumdelegate.cpp index 7c305b1b6b..eb523f7818 100644 --- a/apps/opencs/view/world/enumdelegate.cpp +++ b/apps/opencs/view/world/enumdelegate.cpp @@ -21,7 +21,9 @@ void CSVWorld::EnumDelegate::setModelDataImp (QWidget *editor, QAbstractItemMode iter!=mValues.end(); ++iter) if (iter->second==value) { - addCommands (model, index, iter->first); + // do nothing if the value has not changed + if (model->data(index).toInt() != iter->first) + addCommands (model, index, iter->first); break; } } From befd6fe658fc6969e111762b7ebd9b76db1fb318 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 18 Apr 2015 07:15:40 +1000 Subject: [PATCH 139/185] Convert magic effects Skills column in the nested tables to use enum delegates. --- apps/opencs/model/world/columnbase.cpp | 1 + apps/opencs/model/world/columnbase.hpp | 1 + apps/opencs/model/world/columns.cpp | 13 +++++ apps/opencs/model/world/columns.hpp | 1 + apps/opencs/model/world/data.cpp | 4 +- .../model/world/nestedcoladapterimp.hpp | 53 +------------------ apps/opencs/model/world/refidcollection.cpp | 2 +- apps/opencs/view/doc/viewmanager.cpp | 3 +- apps/opencs/view/world/dialoguesubview.cpp | 3 +- 9 files changed, 25 insertions(+), 56 deletions(-) diff --git a/apps/opencs/model/world/columnbase.cpp b/apps/opencs/model/world/columnbase.cpp index 5ef4aa4441..045afe04c5 100644 --- a/apps/opencs/model/world/columnbase.cpp +++ b/apps/opencs/model/world/columnbase.cpp @@ -75,6 +75,7 @@ bool CSMWorld::ColumnBase::isId (Display display) Display_Video, Display_Id, + Display_SkillImpact, Display_None }; diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 437d07f97d..f6ebb16b81 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -109,6 +109,7 @@ namespace CSMWorld Display_SoundGeneratorType, Display_School, Display_Id, + Display_SkillImpact, //top level columns that nest other columns Display_NestedHeader diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index ff28a12898..3d15ed4f3e 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -270,6 +270,7 @@ namespace CSMWorld { ColumnId_LevelledItemChanceNone, "Chance None" }, { ColumnId_PowerList, "Powers" }, + { ColumnId_SkillImpact, "Skills" }, { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, @@ -423,6 +424,17 @@ namespace "Alteration", "Conjuration", "Destruction", "Illusion", "Mysticism", "Restoration", 0 }; + // impact from magic effects + static const char *sSkills[] = + { + "Block", "Armorer", "MediumArmor", "HeavyArmor", "BluntWeapon", + "LongBlade", "Axe", "Spear", "Athletics", "Enchant", + "Destruction", "Alteration", "Illusion", "Conjuration", "Mysticism", + "Restoration", "Alchemy", "Unarmored", "Security", "Sneak", + "Acrobatics", "LightArmor", "ShortBlade", "Marksman", "Mercantile", + "Speechcraft", "HandToHand", 0 + }; + const char **getEnumNames (CSMWorld::Columns::ColumnId column) { switch (column) @@ -445,6 +457,7 @@ namespace case CSMWorld::Columns::ColumnId_MeshType: return sMeshTypes; case CSMWorld::Columns::ColumnId_SoundGeneratorType: return sSoundGeneratorType; case CSMWorld::Columns::ColumnId_School: return sSchools; + case CSMWorld::Columns::ColumnId_SkillImpact: return sSkills; default: return 0; } diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 7c28f9589a..7508c98806 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -260,6 +260,7 @@ namespace CSMWorld ColumnId_LevelledItemChanceNone = 237, ColumnId_PowerList = 238, + ColumnId_SkillImpact = 239, // impact from magic effects // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 843d08281f..f4edb8e576 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -195,7 +195,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mSpells.getNestableColumn(index)->addColumn( new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_String/*, false*/)); // false means no edit mSpells.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_Skill, ColumnBase::Display_String)); + new NestedChildColumn (Columns::ColumnId_SkillImpact, ColumnBase::Display_SkillImpact)); mSpells.getNestableColumn(index)->addColumn( new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_Attribute)); // reuse attribute mSpells.getNestableColumn(index)->addColumn( @@ -269,7 +269,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mEnchantments.getNestableColumn(index)->addColumn( new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_String/*, false*/)); mEnchantments.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_Skill, ColumnBase::Display_String)); + new NestedChildColumn (Columns::ColumnId_SkillImpact, ColumnBase::Display_SkillImpact)); mEnchantments.getNestableColumn(index)->addColumn( new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_Attribute)); // reuse attribute mEnchantments.getNestableColumn(index)->addColumn( diff --git a/apps/opencs/model/world/nestedcoladapterimp.hpp b/apps/opencs/model/world/nestedcoladapterimp.hpp index 951c7a6101..3f8e6d6a9d 100644 --- a/apps/opencs/model/world/nestedcoladapterimp.hpp +++ b/apps/opencs/model/world/nestedcoladapterimp.hpp @@ -315,42 +315,7 @@ namespace CSMWorld } case 1: { - switch (effect.mSkill) - { - // see ESM::Skill::SkillEnum in - case ESM::Skill::Block: - case ESM::Skill::Armorer: - case ESM::Skill::MediumArmor: - case ESM::Skill::HeavyArmor: - case ESM::Skill::BluntWeapon: - case ESM::Skill::LongBlade: - case ESM::Skill::Axe: - case ESM::Skill::Spear: - case ESM::Skill::Athletics: - case ESM::Skill::Enchant: - case ESM::Skill::Destruction: - case ESM::Skill::Alteration: - case ESM::Skill::Illusion: - case ESM::Skill::Conjuration: - case ESM::Skill::Mysticism: - case ESM::Skill::Restoration: - case ESM::Skill::Alchemy: - case ESM::Skill::Unarmored: - case ESM::Skill::Security: - case ESM::Skill::Sneak: - case ESM::Skill::Acrobatics: - case ESM::Skill::LightArmor: - case ESM::Skill::ShortBlade: - case ESM::Skill::Marksman: - case ESM::Skill::Mercantile: - case ESM::Skill::Speechcraft: - case ESM::Skill::HandToHand: - { - return QString(ESM::Skill::sSkillNames[effect.mSkill].c_str()); - } - case -1: return QString("N/A"); - default: return QVariant(); - } + return effect.mSkill; } case 2: { @@ -396,21 +361,7 @@ namespace CSMWorld } case 1: { - std::string skillName = value.toString().toStdString(); - if ("N/A" == skillName) - { - effect.mSkill = -1; - break; - } - - for (unsigned int i = 0; i < ESM::Skill::Length; ++i) - { - if (ESM::Skill::sSkillNames[i] == skillName) - { - effect.mSkill = static_cast(i); - break; - } - } + effect.mSkill = static_cast(value.toInt()); break; } case 2: diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 92fbfd08e0..a685276f4a 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -83,7 +83,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.back().addColumn( new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_String/*, false*/)); mColumns.back().addColumn( - new NestedChildColumn (Columns::ColumnId_Skill, ColumnBase::Display_String)); + new NestedChildColumn (Columns::ColumnId_SkillImpact, ColumnBase::Display_SkillImpact)); mColumns.back().addColumn( new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_Attribute)); // reuse attribute mColumns.back().addColumn( diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 9fee260789..1dfe3a7925 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -84,7 +84,8 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) { CSMWorld::ColumnBase::Display_MeshType, CSMWorld::Columns::ColumnId_MeshType, false }, { CSMWorld::ColumnBase::Display_Gender, CSMWorld::Columns::ColumnId_Gender, true }, { CSMWorld::ColumnBase::Display_SoundGeneratorType, CSMWorld::Columns::ColumnId_SoundGeneratorType, false }, - { CSMWorld::ColumnBase::Display_School, CSMWorld::Columns::ColumnId_School, true } + { CSMWorld::ColumnBase::Display_School, CSMWorld::Columns::ColumnId_School, true }, + { CSMWorld::ColumnBase::Display_SkillImpact, CSMWorld::Columns::ColumnId_SkillImpact, true } }; for (std::size_t i=0; iindex(row, i), display, dynamic_cast(mTable))); NestedTable* table = new NestedTable(mDocument, mNestedModels.back(), this); - table->resizeColumnsToContents(); + // FIXME: does not work well when enum delegates are used + //table->resizeColumnsToContents(); QLabel* label = From e00d7f72ace0366cfbe8487521675761c90a3a87 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 18 Apr 2015 08:09:14 +1000 Subject: [PATCH 140/185] Convert magic effects ID and Range columns in the nested tables to use enum delegate --- apps/opencs/model/world/columnbase.cpp | 2 + apps/opencs/model/world/columnbase.hpp | 2 + apps/opencs/model/world/columns.cpp | 45 ++++++++++++++++++- apps/opencs/model/world/data.cpp | 8 ++-- .../model/world/nestedcoladapterimp.hpp | 42 +++++------------ apps/opencs/model/world/refidcollection.cpp | 4 +- apps/opencs/view/doc/viewmanager.cpp | 4 +- 7 files changed, 69 insertions(+), 38 deletions(-) diff --git a/apps/opencs/model/world/columnbase.cpp b/apps/opencs/model/world/columnbase.cpp index 045afe04c5..5690d92532 100644 --- a/apps/opencs/model/world/columnbase.cpp +++ b/apps/opencs/model/world/columnbase.cpp @@ -76,6 +76,8 @@ bool CSMWorld::ColumnBase::isId (Display display) Display_Id, Display_SkillImpact, + Display_EffectRange, + Display_EffectId, Display_None }; diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index f6ebb16b81..8dab0602e1 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -110,6 +110,8 @@ namespace CSMWorld Display_School, Display_Id, Display_SkillImpact, + Display_EffectRange, + Display_EffectId, //top level columns that nest other columns Display_NestedHeader diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 3d15ed4f3e..19efc81775 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -332,6 +332,7 @@ namespace "Combat", "Magic", "Stealth", 0 }; + // see ESM::Attribute::AttributeID in static const char *sAttributes[] = { "Strength", "Intelligence", "Willpower", "Agility", "Speed", "Endurance", "Personality", @@ -424,7 +425,7 @@ namespace "Alteration", "Conjuration", "Destruction", "Illusion", "Mysticism", "Restoration", 0 }; - // impact from magic effects + // impact from magic effects, see ESM::Skill::SkillEnum in static const char *sSkills[] = { "Block", "Armorer", "MediumArmor", "HeavyArmor", "BluntWeapon", @@ -435,6 +436,46 @@ namespace "Speechcraft", "HandToHand", 0 }; + // range of magic effects, see ESM::RangeType in + static const char *sEffectRange[] = + { + "Self", "Touch", "Target", 0 + }; + + // magic effect names, see ESM::MagicEffect::Effects in + static const char *sEffectId[] = + { + "WaterBreathing", "SwiftSwim", "WaterWalking", "Shield", "FireShield", + "LightningShield", "FrostShield", "Burden", "Feather", "Jump", + "Levitate", "SlowFall", "Lock", "Open", "FireDamage", + "ShockDamage", "FrostDamage", "DrainAttribute", "DrainHealth", "DrainMagicka", + "DrainFatigue", "DrainSkill", "DamageAttribute", "DamageHealth", "DamageMagicka", + "DamageFatigue", "DamageSkill", "Poison", "WeaknessToFire", "WeaknessToFrost", + "WeaknessToShock", "WeaknessToMagicka", "WeaknessToCommonDisease", "WeaknessToBlightDisease", "WeaknessToCorprusDisease", + "WeaknessToPoison", "WeaknessToNormalWeapons", "DisintegrateWeapon", "DisintegrateArmor", "Invisibility", + "Chameleon", "Light", "Sanctuary", "NightEye", "Charm", + "Paralyze", "Silence", "Blind", "Sound", "CalmHumanoid", + "CalmCreature", "FrenzyHumanoid", "FrenzyCreature", "DemoralizeHumanoid", "DemoralizeCreature", + "RallyHumanoid", "RallyCreature", "Dispel", "Soultrap", "Telekinesis", + "Mark", "Recall", "DivineIntervention", "AlmsiviIntervention", "DetectAnimal", + "DetectEnchantment", "DetectKey", "SpellAbsorption", "Reflect", "CureCommonDisease", + "CureBlightDisease", "CureCorprusDisease", "CurePoison", "CureParalyzation", "RestoreAttribute", + "RestoreHealth", "RestoreMagicka", "RestoreFatigue", "RestoreSkill", "FortifyAttribute", + "FortifyHealth", "FortifyMagicka", "FortifyFatigue", "FortifySkill", "FortifyMaximumMagicka", + "AbsorbAttribute", "AbsorbHealth", "AbsorbMagicka", "AbsorbFatigue", "AbsorbSkill", + "ResistFire", "ResistFrost", "ResistShock", "ResistMagicka", "ResistCommonDisease", + "ResistBlightDisease", "ResistCorprusDisease", "ResistPoison", "ResistNormalWeapons", "ResistParalysis", + "RemoveCurse", "TurnUndead", "SummonScamp", "SummonClannfear", "SummonDaedroth", + "SummonDremora", "SummonAncestralGhost", "SummonSkeletalMinion", "SummonBonewalker", "SummonGreaterBonewalker", + "SummonBonelord", "SummonWingedTwilight", "SummonHunger", "SummonGoldenSaint", "SummonFlameAtronach", + "SummonFrostAtronach", "SummonStormAtronach", "FortifyAttack", "CommandCreature", "CommandHumanoid", + "BoundDagger", "BoundLongsword", "BoundMace", "BoundBattleAxe", "BoundSpear", + "BoundLongbow", "ExtraSpell", "BoundCuirass", "BoundHelm", "BoundBoots", + "BoundShield", "BoundGloves", "Corprus", "Vampirism", "SummonCenturionSphere", + "SunDamage", "StuntedMagicka", "SummonFabricant", "SummonWolf", "SummonBear", + "SummonBonewolf", "SummonCreature04", "SummonCreature05", 0 + }; + const char **getEnumNames (CSMWorld::Columns::ColumnId column) { switch (column) @@ -458,6 +499,8 @@ namespace case CSMWorld::Columns::ColumnId_SoundGeneratorType: return sSoundGeneratorType; case CSMWorld::Columns::ColumnId_School: return sSchools; case CSMWorld::Columns::ColumnId_SkillImpact: return sSkills; + case CSMWorld::Columns::ColumnId_EffectRange: return sEffectRange; + case CSMWorld::Columns::ColumnId_EffectId: return sEffectId; default: return 0; } diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index f4edb8e576..0490cbe7a1 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -193,13 +193,13 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc index = mSpells.getColumns()-1; mSpells.addAdapter (std::make_pair(&mSpells.getColumn(index), new EffectsListAdapter ())); mSpells.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_String/*, false*/)); // false means no edit + new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_EffectId)); // false means no edit mSpells.getNestableColumn(index)->addColumn( new NestedChildColumn (Columns::ColumnId_SkillImpact, ColumnBase::Display_SkillImpact)); mSpells.getNestableColumn(index)->addColumn( new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_Attribute)); // reuse attribute mSpells.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_Integer)); + new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_EffectRange)); mSpells.getNestableColumn(index)->addColumn( new NestedChildColumn (Columns::ColumnId_EffectArea, ColumnBase::Display_String)); mSpells.getNestableColumn(index)->addColumn( @@ -267,13 +267,13 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mEnchantments.addAdapter (std::make_pair(&mEnchantments.getColumn(index), new EffectsListAdapter ())); mEnchantments.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_String/*, false*/)); + new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_EffectId)); mEnchantments.getNestableColumn(index)->addColumn( new NestedChildColumn (Columns::ColumnId_SkillImpact, ColumnBase::Display_SkillImpact)); mEnchantments.getNestableColumn(index)->addColumn( new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_Attribute)); // reuse attribute mEnchantments.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_Integer)); + new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_EffectRange)); mEnchantments.getNestableColumn(index)->addColumn( new NestedChildColumn (Columns::ColumnId_EffectArea, ColumnBase::Display_String)); mEnchantments.getNestableColumn(index)->addColumn( diff --git a/apps/opencs/model/world/nestedcoladapterimp.hpp b/apps/opencs/model/world/nestedcoladapterimp.hpp index 3f8e6d6a9d..1ee447f349 100644 --- a/apps/opencs/model/world/nestedcoladapterimp.hpp +++ b/apps/opencs/model/world/nestedcoladapterimp.hpp @@ -309,28 +309,19 @@ namespace CSMWorld { case 0: { - // indexToId() prepends "#d+" hence not so user friendly - QString effectId(ESM::MagicEffect::effectIdToString(effect.mEffectID).c_str()); - return effectId.remove(0, 7); // 7 == sizeof("sEffect") - 1 - } - case 1: - { - return effect.mSkill; - } - case 2: - { - return effect.mAttribute; + if (effect.mEffectID >=0 && effect.mEffectID < ESM::MagicEffect::Length) + return effect.mRange; + else + throw std::runtime_error("Magic effects ID unexpected value"); } + case 1: return effect.mSkill; + case 2: return effect.mAttribute; case 3: { - switch (effect.mRange) - { - // see ESM::RangeType in - case ESM::RT_Self: return QString("Self"); - case ESM::RT_Touch: return QString("Touch"); - case ESM::RT_Target: return QString("Target"); - default: return QVariant(); - } + if (effect.mRange >=0 && effect.mRange <=2) + return effect.mRange; + else + throw std::runtime_error("Magic effects range unexpected value"); } case 4: return effect.mArea; case 5: return effect.mDuration; @@ -355,8 +346,7 @@ namespace CSMWorld { case 0: { - effect.mEffectID = - ESM::MagicEffect::effectStringToId("sEffect"+value.toString().toStdString()); + effect.mEffectID = static_cast(value.toInt()); break; } case 1: @@ -371,15 +361,7 @@ namespace CSMWorld } case 3: { - std::string effectId = value.toString().toStdString(); - if (effectId == "Self") - effect.mRange = ESM::RT_Self; - else if (effectId == "Touch") - effect.mRange = ESM::RT_Touch; - else if (effectId == "Target") - effect.mRange = ESM::RT_Target; - else - return; // leave unchanged + effect.mRange = value.toInt(); break; } case 4: effect.mArea = value.toInt(); break; diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index a685276f4a..636f9a57f8 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -81,13 +81,13 @@ CSMWorld::RefIdCollection::RefIdCollection() new EffectsRefIdAdapter (UniversalId::Type_Potion))); mNestedAdapters.push_back (std::make_pair(&mColumns.back(), effectsMap)); mColumns.back().addColumn( - new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_String/*, false*/)); + new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_EffectId)); mColumns.back().addColumn( new NestedChildColumn (Columns::ColumnId_SkillImpact, ColumnBase::Display_SkillImpact)); mColumns.back().addColumn( new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_Attribute)); // reuse attribute mColumns.back().addColumn( - new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_Integer)); + new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_EffectRange)); mColumns.back().addColumn( new NestedChildColumn (Columns::ColumnId_EffectArea, ColumnBase::Display_String)); mColumns.back().addColumn( diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 1dfe3a7925..1281f89f2a 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -85,7 +85,9 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) { CSMWorld::ColumnBase::Display_Gender, CSMWorld::Columns::ColumnId_Gender, true }, { CSMWorld::ColumnBase::Display_SoundGeneratorType, CSMWorld::Columns::ColumnId_SoundGeneratorType, false }, { CSMWorld::ColumnBase::Display_School, CSMWorld::Columns::ColumnId_School, true }, - { CSMWorld::ColumnBase::Display_SkillImpact, CSMWorld::Columns::ColumnId_SkillImpact, true } + { CSMWorld::ColumnBase::Display_SkillImpact, CSMWorld::Columns::ColumnId_SkillImpact, true }, + { CSMWorld::ColumnBase::Display_EffectRange, CSMWorld::Columns::ColumnId_EffectRange, false }, + { CSMWorld::ColumnBase::Display_EffectId, CSMWorld::Columns::ColumnId_EffectId, false } }; for (std::size_t i=0; i Date: Sat, 18 Apr 2015 08:31:08 +1000 Subject: [PATCH 141/185] Convert clothing/armour part reference type column in the nested tables to use enum delegates. --- apps/opencs/model/world/columnbase.cpp | 1 + apps/opencs/model/world/columnbase.hpp | 1 + apps/opencs/model/world/columns.cpp | 12 +++++++ apps/opencs/model/world/refidadapterimp.hpp | 36 +++++---------------- apps/opencs/model/world/refidcollection.cpp | 2 +- apps/opencs/view/doc/viewmanager.cpp | 3 +- 6 files changed, 25 insertions(+), 30 deletions(-) diff --git a/apps/opencs/model/world/columnbase.cpp b/apps/opencs/model/world/columnbase.cpp index 5690d92532..cea00b7bcc 100644 --- a/apps/opencs/model/world/columnbase.cpp +++ b/apps/opencs/model/world/columnbase.cpp @@ -78,6 +78,7 @@ bool CSMWorld::ColumnBase::isId (Display display) Display_SkillImpact, Display_EffectRange, Display_EffectId, + Display_PartRefType, Display_None }; diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 8dab0602e1..20e3ccce6c 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -112,6 +112,7 @@ namespace CSMWorld Display_SkillImpact, Display_EffectRange, Display_EffectId, + Display_PartRefType, //top level columns that nest other columns Display_NestedHeader diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 19efc81775..fd090d1818 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -476,6 +476,17 @@ namespace "SummonBonewolf", "SummonCreature04", "SummonCreature05", 0 }; + // see ESM::PartReferenceType in + static const char *sPartRefType[] = + { + "Head", "Hair", "Neck", "Cuirass", "Groin", + "Skirt", "Right Hand", "Left Hand", "Right Wrist", "Left Wrist", + "Shield", "Right Forearm", "Left Forearm", "Right Upperarm", "Left Upperarm", + "Right Foot", "Left Foot", "Right Ankle", "Left Ankle", "Right Knee", + "Left Knee", "Right Leg", "Left Leg", "Right Pauldron", "Left Pauldron", + "Weapon", "Tail", 0 + }; + const char **getEnumNames (CSMWorld::Columns::ColumnId column) { switch (column) @@ -501,6 +512,7 @@ namespace case CSMWorld::Columns::ColumnId_SkillImpact: return sSkills; case CSMWorld::Columns::ColumnId_EffectRange: return sEffectRange; case CSMWorld::Columns::ColumnId_EffectId: return sEffectId; + case CSMWorld::Columns::ColumnId_PartRefType: return sPartRefType; default: return 0; } diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 2b2b189e09..4898083934 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -1665,15 +1665,6 @@ namespace CSMWorld } }; - static const char *sPartRefs[ESM::PRT_Count] = - { - "Head", "Hair", "Neck", "Cuirass", "Groin", - "Skirt", "Right Hand", "Left Hand", "Right Wrist", "Left Wrist", - "Shield", "Right Forearm", "Left Forearm", "Right Upperarm", "Left Upperarm", - "Right Foot", "Left Foot", "Right Ankle", "Left Ankle", "Right Knee", - "Left Knee", "Right Leg", "Left Leg", "Right Pauldron", "Left Pauldron", - "Weapon", "Tail" - }; template class BodyPartRefIdAdapter : public NestedRefIdAdapterBase @@ -1767,7 +1758,13 @@ namespace CSMWorld switch (subColIndex) { - case 0: return QString(sPartRefs[content.mPart]); + case 0: + { + if (content.mPart >=0 && content.mPart < ESM::PRT_Count) + return content.mPart; + else + throw std::runtime_error("Part Reference Type unexpected value"); + } case 1: return QString(content.mMale.c_str()); case 2: return QString(content.mFemale.c_str()); default: @@ -1788,24 +1785,7 @@ namespace CSMWorld switch(subColIndex) { - case 0: - { - std::string part = value.toString().toStdString(); - bool found = false; - for (unsigned int i = 0; i < ESM::PRT_Count; ++i) - { - if (part == sPartRefs[i]) - { - list.at(subRowIndex).mPart = static_cast(i); - found = true; - break; - } - } - if (!found) - return; // return without saving - else - break; - } + case 0: list.at(subRowIndex).mPart = static_cast(value.toInt()); break; case 1: list.at(subRowIndex).mMale = value.toString().toStdString(); break; case 2: list.at(subRowIndex).mFemale = value.toString().toStdString(); break; default: diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 636f9a57f8..3bdf8361f8 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -480,7 +480,7 @@ CSMWorld::RefIdCollection::RefIdCollection() new BodyPartRefIdAdapter (UniversalId::Type_Clothing))); mNestedAdapters.push_back (std::make_pair(&mColumns.back(), partMap)); mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_PartRefType, CSMWorld::ColumnBase::Display_String)); + new RefIdColumn (Columns::ColumnId_PartRefType, CSMWorld::ColumnBase::Display_PartRefType)); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_PartRefMale, CSMWorld::ColumnBase::Display_String)); mColumns.back().addColumn( diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 1281f89f2a..3f0c10053a 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -87,7 +87,8 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) { CSMWorld::ColumnBase::Display_School, CSMWorld::Columns::ColumnId_School, true }, { CSMWorld::ColumnBase::Display_SkillImpact, CSMWorld::Columns::ColumnId_SkillImpact, true }, { CSMWorld::ColumnBase::Display_EffectRange, CSMWorld::Columns::ColumnId_EffectRange, false }, - { CSMWorld::ColumnBase::Display_EffectId, CSMWorld::Columns::ColumnId_EffectId, false } + { CSMWorld::ColumnBase::Display_EffectId, CSMWorld::Columns::ColumnId_EffectId, false }, + { CSMWorld::ColumnBase::Display_PartRefType, CSMWorld::Columns::ColumnId_PartRefType, false } }; for (std::size_t i=0; i Date: Sat, 18 Apr 2015 09:37:19 +1000 Subject: [PATCH 142/185] Convert AI package type and AI wander repeat columns in the nested tables to use enum delegate --- apps/opencs/model/world/columnbase.cpp | 2 + apps/opencs/model/world/columnbase.hpp | 2 + apps/opencs/model/world/columns.cpp | 15 +++- apps/opencs/model/world/columns.hpp | 2 +- apps/opencs/model/world/refidadapterimp.hpp | 77 +++++++-------------- apps/opencs/model/world/refidcollection.cpp | 4 +- apps/opencs/view/doc/viewmanager.cpp | 4 +- 7 files changed, 48 insertions(+), 58 deletions(-) diff --git a/apps/opencs/model/world/columnbase.cpp b/apps/opencs/model/world/columnbase.cpp index cea00b7bcc..659954f481 100644 --- a/apps/opencs/model/world/columnbase.cpp +++ b/apps/opencs/model/world/columnbase.cpp @@ -79,6 +79,8 @@ bool CSMWorld::ColumnBase::isId (Display display) Display_EffectRange, Display_EffectId, Display_PartRefType, + Display_AiPackageType, + Display_YesNo, Display_None }; diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 20e3ccce6c..4c3f9385a0 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -113,6 +113,8 @@ namespace CSMWorld Display_EffectRange, Display_EffectId, Display_PartRefType, + Display_AiPackageType, + Display_YesNo, //top level columns that nest other columns Display_NestedHeader diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index fd090d1818..1b5aefee94 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -248,7 +248,7 @@ namespace CSMWorld { ColumnId_EffectArea, "Area" }, { ColumnId_AiPackageList, "Ai Packages" }, - { ColumnId_AiPackage, "Package" }, + { ColumnId_AiPackageType, "Package" }, { ColumnId_AiWanderDist, "Wander Dist" }, { ColumnId_AiDuration, "Duration" }, { ColumnId_AiWanderToD, "Wander ToD" }, @@ -487,6 +487,17 @@ namespace "Weapon", "Tail", 0 }; + // see the enums in + static const char *sAiPackageType[] = + { + "AI Wander", "AI Travel", "AI Follow", "AI Escort", "AI Activate", 0 + }; + + static const char *sAiWanderRepeat[] = + { + "No", "Yes", 0 + }; + const char **getEnumNames (CSMWorld::Columns::ColumnId column) { switch (column) @@ -513,6 +524,8 @@ namespace case CSMWorld::Columns::ColumnId_EffectRange: return sEffectRange; case CSMWorld::Columns::ColumnId_EffectId: return sEffectId; case CSMWorld::Columns::ColumnId_PartRefType: return sPartRefType; + case CSMWorld::Columns::ColumnId_AiPackageType: return sAiPackageType; + case CSMWorld::Columns::ColumnId_AiWanderRepeat: return sAiWanderRepeat; default: return 0; } diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 7508c98806..1760bff30d 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -237,7 +237,7 @@ namespace CSMWorld ColumnId_EffectArea = 218, ColumnId_AiPackageList = 219, - ColumnId_AiPackage = 220, + ColumnId_AiPackageType = 220, ColumnId_AiWanderDist = 221, ColumnId_AiDuration = 222, ColumnId_AiWanderToD = 223, diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 4898083934..5fd888441c 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -1318,34 +1318,13 @@ namespace CSMWorld switch(subColIndex) { - case 0: - list.at(subRowIndex).mCellName = std::string(value.toString().toUtf8().constData()); - break; - - case 1: - list.at(subRowIndex).mPos.pos[0] = value.toFloat(); - break; - - case 2: - list.at(subRowIndex).mPos.pos[1] = value.toFloat(); - break; - - case 3: - list.at(subRowIndex).mPos.pos[2] = value.toFloat(); - break; - - case 4: - list.at(subRowIndex).mPos.rot[0] = value.toFloat(); - break; - - case 5: - list.at(subRowIndex).mPos.rot[1] = value.toFloat(); - break; - - case 6: - list.at(subRowIndex).mPos.rot[2] = value.toFloat(); - break; - + case 0: list.at(subRowIndex).mCellName = std::string(value.toString().toUtf8().constData()); break; + case 1: list.at(subRowIndex).mPos.pos[0] = value.toFloat(); break; + case 2: list.at(subRowIndex).mPos.pos[1] = value.toFloat(); break; + case 3: list.at(subRowIndex).mPos.pos[2] = value.toFloat(); break; + case 4: list.at(subRowIndex).mPos.rot[0] = value.toFloat(); break; + case 5: list.at(subRowIndex).mPos.rot[1] = value.toFloat(); break; + case 6: list.at(subRowIndex).mPos.rot[2] = value.toFloat(); break; default: throw std::runtime_error("Trying to access non-existing column in the nested table!"); } @@ -1461,13 +1440,13 @@ namespace CSMWorld case 0: switch (content.mType) { - case ESM::AI_Wander: return QString("AI Wander"); - case ESM::AI_Travel: return QString("AI Travel"); - case ESM::AI_Follow: return QString("AI Follow"); - case ESM::AI_Escort: return QString("AI Escort"); - case ESM::AI_Activate: return QString("AI Activate"); + case ESM::AI_Wander: return 0; + case ESM::AI_Travel: return 1; + case ESM::AI_Follow: return 2; + case ESM::AI_Escort: return 3; + case ESM::AI_Activate: return 4; case ESM::AI_CNDT: - default: return QString("None"); + default: return QVariant(); } case 1: // wander dist if (content.mType == ESM::AI_Wander) @@ -1494,7 +1473,7 @@ namespace CSMWorld return QVariant(); case 5: // wander repeat if (content.mType == ESM::AI_Wander) - return QString(content.mWander.mShouldRepeat ? "Yes" : "No"); + return content.mWander.mShouldRepeat; else return QVariant(); case 6: // activate name @@ -1554,18 +1533,14 @@ namespace CSMWorld switch(subColIndex) { case 0: // ai package type - if ("AI Wander" == value.toString().toStdString()) - content.mType = ESM::AI_Wander; - else if ("AI Travel" == value.toString().toStdString()) - content.mType = ESM::AI_Travel; - else if ("AI Follow" == value.toString().toStdString()) - content.mType = ESM::AI_Follow; - else if ("AI Escort" == value.toString().toStdString()) - content.mType = ESM::AI_Escort; - else if ("AI Activate" == value.toString().toStdString()) - content.mType = ESM::AI_Activate; - else - content.mType = ESM::AI_CNDT; + switch (value.toInt()) + { + case 0: content.mType = ESM::AI_Wander; + case 1: content.mType = ESM::AI_Travel; + case 2: content.mType = ESM::AI_Follow; + case 3: content.mType = ESM::AI_Escort; + case 4: content.mType = ESM::AI_Activate; + } break; // always save case 1: @@ -1592,12 +1567,8 @@ namespace CSMWorld case 5: if (content.mType == ESM::AI_Wander) { - if ("Yes" == value.toString().toStdString()) - content.mWander.mShouldRepeat = 1; - if ("No" == value.toString().toStdString()) - content.mWander.mShouldRepeat = 0; - else - return; // return without saving + content.mWander.mShouldRepeat = static_cast(value.toInt()); + break; } case 6: // NAME32 if (content.mType == ESM::AI_Activate) diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 3bdf8361f8..caf1041c6d 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -188,7 +188,7 @@ CSMWorld::RefIdCollection::RefIdCollection() new ActorAiRefIdAdapter (UniversalId::Type_Creature))); mNestedAdapters.push_back (std::make_pair(&mColumns.back(), aiMap)); mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_AiPackage, CSMWorld::ColumnBase::Display_String)); + new RefIdColumn (Columns::ColumnId_AiPackageType, CSMWorld::ColumnBase::Display_AiPackageType)); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_AiWanderDist, CSMWorld::ColumnBase::Display_Integer)); mColumns.back().addColumn( @@ -198,7 +198,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_AiWanderIdle, CSMWorld::ColumnBase::Display_Integer)); mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_AiWanderRepeat, CSMWorld::ColumnBase::Display_String)); + new RefIdColumn (Columns::ColumnId_AiWanderRepeat, CSMWorld::ColumnBase::Display_YesNo)); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_AiActivateName, CSMWorld::ColumnBase::Display_String)); mColumns.back().addColumn( diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 3f0c10053a..5908c67a19 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -88,7 +88,9 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) { CSMWorld::ColumnBase::Display_SkillImpact, CSMWorld::Columns::ColumnId_SkillImpact, true }, { CSMWorld::ColumnBase::Display_EffectRange, CSMWorld::Columns::ColumnId_EffectRange, false }, { CSMWorld::ColumnBase::Display_EffectId, CSMWorld::Columns::ColumnId_EffectId, false }, - { CSMWorld::ColumnBase::Display_PartRefType, CSMWorld::Columns::ColumnId_PartRefType, false } + { CSMWorld::ColumnBase::Display_PartRefType, CSMWorld::Columns::ColumnId_PartRefType, false }, + { CSMWorld::ColumnBase::Display_AiPackageType, CSMWorld::Columns::ColumnId_AiPackageType, false }, + { CSMWorld::ColumnBase::Display_YesNo, CSMWorld::Columns::ColumnId_AiWanderRepeat, false } }; for (std::size_t i=0; i Date: Sat, 18 Apr 2015 10:07:53 +1000 Subject: [PATCH 143/185] Change the cell edit selection behaviour of the nested tables. Also auto-expand the enum delegate selections (both main table as well as nested table in the dialogue subview) --- apps/opencs/view/world/dialoguesubview.cpp | 2 ++ apps/opencs/view/world/enumdelegate.cpp | 1 + 2 files changed, 3 insertions(+) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 10a192668e..9d718cf813 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -444,6 +444,8 @@ void CSVWorld::EditWidget::remake(int row) NestedTable* table = new NestedTable(mDocument, mNestedModels.back(), this); // FIXME: does not work well when enum delegates are used //table->resizeColumnsToContents(); + table->setEditTriggers(QAbstractItemView::CurrentChanged); + table->setSelectionBehavior(QAbstractItemView::SelectItems); QLabel* label = diff --git a/apps/opencs/view/world/enumdelegate.cpp b/apps/opencs/view/world/enumdelegate.cpp index eb523f7818..c635948a34 100644 --- a/apps/opencs/view/world/enumdelegate.cpp +++ b/apps/opencs/view/world/enumdelegate.cpp @@ -88,6 +88,7 @@ void CSVWorld::EnumDelegate::setEditorData (QWidget *editor, const QModelIndex& if (mValues[i].first==value) { comboBox->setCurrentIndex (i); + comboBox->showPopup(); break; } } From 48a6006202a5f8c5c8d006fd616983337b39514e Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 18 Apr 2015 14:16:55 +1000 Subject: [PATCH 144/185] Prevent enum delegates from auto expanding when opening a dialogue subview. --- apps/opencs/view/world/dialoguesubview.cpp | 3 +-- apps/opencs/view/world/enumdelegate.cpp | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 9d718cf813..9358bf6c75 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -444,10 +444,9 @@ void CSVWorld::EditWidget::remake(int row) NestedTable* table = new NestedTable(mDocument, mNestedModels.back(), this); // FIXME: does not work well when enum delegates are used //table->resizeColumnsToContents(); - table->setEditTriggers(QAbstractItemView::CurrentChanged); + table->setEditTriggers(QAbstractItemView::SelectedClicked | QAbstractItemView::CurrentChanged); table->setSelectionBehavior(QAbstractItemView::SelectItems); - QLabel* label = new QLabel (mTable->headerData (i, Qt::Horizontal, Qt::DisplayRole).toString(), mMainWidget); diff --git a/apps/opencs/view/world/enumdelegate.cpp b/apps/opencs/view/world/enumdelegate.cpp index c635948a34..bda93678a5 100644 --- a/apps/opencs/view/world/enumdelegate.cpp +++ b/apps/opencs/view/world/enumdelegate.cpp @@ -88,7 +88,8 @@ void CSVWorld::EnumDelegate::setEditorData (QWidget *editor, const QModelIndex& if (mValues[i].first==value) { comboBox->setCurrentIndex (i); - comboBox->showPopup(); + if(!tryDisplay) + comboBox->showPopup(); break; } } From 7561b195abd9e6e08b27fcf7c8a4bb3f5723d41a Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 18 Apr 2015 15:28:34 +1000 Subject: [PATCH 145/185] Revert auto expansion of enums as it was interfering with row based operations. Fix default values of magic effect skill & attributes. --- apps/opencs/model/world/nestedcoladapterimp.hpp | 4 ++-- apps/opencs/view/world/dialoguesubview.cpp | 5 +++-- apps/opencs/view/world/enumdelegate.cpp | 2 -- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/apps/opencs/model/world/nestedcoladapterimp.hpp b/apps/opencs/model/world/nestedcoladapterimp.hpp index 1ee447f349..841c3955a1 100644 --- a/apps/opencs/model/world/nestedcoladapterimp.hpp +++ b/apps/opencs/model/world/nestedcoladapterimp.hpp @@ -252,8 +252,8 @@ namespace CSMWorld // blank row ESM::ENAMstruct effect; effect.mEffectID = 0; - effect.mSkill = 0; - effect.mAttribute = 0; + effect.mSkill = -1; + effect.mAttribute = -1; effect.mRange = 0; effect.mArea = 0; effect.mDuration = 0; diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 9358bf6c75..6626d67c34 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -443,9 +443,10 @@ void CSVWorld::EditWidget::remake(int row) NestedTable* table = new NestedTable(mDocument, mNestedModels.back(), this); // FIXME: does not work well when enum delegates are used - //table->resizeColumnsToContents(); + table->setVisible(false); + table->resizeColumnsToContents(); + table->setVisible(true); table->setEditTriggers(QAbstractItemView::SelectedClicked | QAbstractItemView::CurrentChanged); - table->setSelectionBehavior(QAbstractItemView::SelectItems); QLabel* label = new QLabel (mTable->headerData (i, Qt::Horizontal, Qt::DisplayRole).toString(), mMainWidget); diff --git a/apps/opencs/view/world/enumdelegate.cpp b/apps/opencs/view/world/enumdelegate.cpp index bda93678a5..eb523f7818 100644 --- a/apps/opencs/view/world/enumdelegate.cpp +++ b/apps/opencs/view/world/enumdelegate.cpp @@ -88,8 +88,6 @@ void CSVWorld::EnumDelegate::setEditorData (QWidget *editor, const QModelIndex& if (mValues[i].first==value) { comboBox->setCurrentIndex (i); - if(!tryDisplay) - comboBox->showPopup(); break; } } From dd1e4e8b691c45669669503033b00c972335767b Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sun, 19 Apr 2015 08:58:52 +1000 Subject: [PATCH 146/185] Remove gcc/clang warnings. --- .../model/world/nestedcoladapterimp.cpp | 56 ++++++------- .../model/world/nestedcoladapterimp.hpp | 84 +++++++++---------- .../model/world/nestedcolumnadapter.hpp | 14 ++-- .../opencs/model/world/nestedidcollection.hpp | 14 ++-- apps/opencs/model/world/refidadapterimp.hpp | 16 ++-- 5 files changed, 92 insertions(+), 92 deletions(-) diff --git a/apps/opencs/model/world/nestedcoladapterimp.cpp b/apps/opencs/model/world/nestedcoladapterimp.cpp index d974a34c79..bd6a5c4491 100644 --- a/apps/opencs/model/world/nestedcoladapterimp.cpp +++ b/apps/opencs/model/world/nestedcoladapterimp.cpp @@ -10,7 +10,7 @@ namespace CSMWorld { PathgridPointListAdapter::PathgridPointListAdapter () {} - void PathgridPointListAdapter::addNestedRow(Record& record, int position) const + void PathgridPointListAdapter::addRow(Record& record, int position) const { Pathgrid pathgrid = record.get(); @@ -43,7 +43,7 @@ namespace CSMWorld record.setModified (pathgrid); } - void PathgridPointListAdapter::removeNestedRow(Record& record, int rowToRemove) const + void PathgridPointListAdapter::removeRow(Record& record, int rowToRemove) const { Pathgrid pathgrid = record.get(); @@ -78,7 +78,7 @@ namespace CSMWorld record.setModified (pathgrid); } - void PathgridPointListAdapter::setNestedTable(Record& record, + void PathgridPointListAdapter::setTable(Record& record, const NestedTableWrapperBase& nestedTable) const { Pathgrid pathgrid = record.get(); @@ -100,7 +100,7 @@ namespace CSMWorld return new PathgridPointsWrap(record.get()); } - QVariant PathgridPointListAdapter::getNestedData(const Record& record, + QVariant PathgridPointListAdapter::getData(const Record& record, int subRowIndex, int subColIndex) const { ESM::Pathgrid::Point point = record.get().mPoints[subRowIndex]; @@ -114,7 +114,7 @@ namespace CSMWorld } } - void PathgridPointListAdapter::setNestedData(Record& record, + void PathgridPointListAdapter::setData(Record& record, const QVariant& value, int subRowIndex, int subColIndex) const { Pathgrid pathgrid = record.get(); @@ -133,12 +133,12 @@ namespace CSMWorld record.setModified (pathgrid); } - int PathgridPointListAdapter::getNestedColumnsCount(const Record& record) const + int PathgridPointListAdapter::getColumnsCount(const Record& record) const { return 4; } - int PathgridPointListAdapter::getNestedRowsCount(const Record& record) const + int PathgridPointListAdapter::getRowsCount(const Record& record) const { return static_cast(record.get().mPoints.size()); } @@ -146,7 +146,7 @@ namespace CSMWorld PathgridEdgeListAdapter::PathgridEdgeListAdapter () {} // ToDo: seems to be auto-sorted in the dialog table display after insertion - void PathgridEdgeListAdapter::addNestedRow(Record& record, int position) const + void PathgridEdgeListAdapter::addRow(Record& record, int position) const { Pathgrid pathgrid = record.get(); @@ -167,7 +167,7 @@ namespace CSMWorld record.setModified (pathgrid); } - void PathgridEdgeListAdapter::removeNestedRow(Record& record, int rowToRemove) const + void PathgridEdgeListAdapter::removeRow(Record& record, int rowToRemove) const { Pathgrid pathgrid = record.get(); @@ -181,7 +181,7 @@ namespace CSMWorld record.setModified (pathgrid); } - void PathgridEdgeListAdapter::setNestedTable(Record& record, + void PathgridEdgeListAdapter::setTable(Record& record, const NestedTableWrapperBase& nestedTable) const { Pathgrid pathgrid = record.get(); @@ -198,7 +198,7 @@ namespace CSMWorld return new NestedTableWrapper(record.get().mEdges); } - QVariant PathgridEdgeListAdapter::getNestedData(const Record& record, + QVariant PathgridEdgeListAdapter::getData(const Record& record, int subRowIndex, int subColIndex) const { Pathgrid pathgrid = record.get(); @@ -217,7 +217,7 @@ namespace CSMWorld } // ToDo: detect duplicates in mEdges - void PathgridEdgeListAdapter::setNestedData(Record& record, + void PathgridEdgeListAdapter::setData(Record& record, const QVariant& value, int subRowIndex, int subColIndex) const { Pathgrid pathgrid = record.get(); @@ -239,19 +239,19 @@ namespace CSMWorld record.setModified (pathgrid); } - int PathgridEdgeListAdapter::getNestedColumnsCount(const Record& record) const + int PathgridEdgeListAdapter::getColumnsCount(const Record& record) const { return 3; } - int PathgridEdgeListAdapter::getNestedRowsCount(const Record& record) const + int PathgridEdgeListAdapter::getRowsCount(const Record& record) const { return static_cast(record.get().mEdges.size()); } FactionReactionsAdapter::FactionReactionsAdapter () {} - void FactionReactionsAdapter::addNestedRow(Record& record, int position) const + void FactionReactionsAdapter::addRow(Record& record, int position) const { ESM::Faction faction = record.get(); @@ -263,7 +263,7 @@ namespace CSMWorld record.setModified (faction); } - void FactionReactionsAdapter::removeNestedRow(Record& record, int rowToRemove) const + void FactionReactionsAdapter::removeRow(Record& record, int rowToRemove) const { ESM::Faction faction = record.get(); @@ -282,7 +282,7 @@ namespace CSMWorld record.setModified (faction); } - void FactionReactionsAdapter::setNestedTable(Record& record, + void FactionReactionsAdapter::setTable(Record& record, const NestedTableWrapperBase& nestedTable) const { ESM::Faction faction = record.get(); @@ -299,7 +299,7 @@ namespace CSMWorld return new NestedTableWrapper >(record.get().mReactions); } - QVariant FactionReactionsAdapter::getNestedData(const Record& record, + QVariant FactionReactionsAdapter::getData(const Record& record, int subRowIndex, int subColIndex) const { ESM::Faction faction = record.get(); @@ -322,7 +322,7 @@ namespace CSMWorld } } - void FactionReactionsAdapter::setNestedData(Record& record, + void FactionReactionsAdapter::setData(Record& record, const QVariant& value, int subRowIndex, int subColIndex) const { ESM::Faction faction = record.get(); @@ -360,19 +360,19 @@ namespace CSMWorld record.setModified (faction); } - int FactionReactionsAdapter::getNestedColumnsCount(const Record& record) const + int FactionReactionsAdapter::getColumnsCount(const Record& record) const { return 2; } - int FactionReactionsAdapter::getNestedRowsCount(const Record& record) const + int FactionReactionsAdapter::getRowsCount(const Record& record) const { return static_cast(record.get().mReactions.size()); } RegionSoundListAdapter::RegionSoundListAdapter () {} - void RegionSoundListAdapter::addNestedRow(Record& record, int position) const + void RegionSoundListAdapter::addRow(Record& record, int position) const { ESM::Region region = record.get(); @@ -388,7 +388,7 @@ namespace CSMWorld record.setModified (region); } - void RegionSoundListAdapter::removeNestedRow(Record& record, int rowToRemove) const + void RegionSoundListAdapter::removeRow(Record& record, int rowToRemove) const { ESM::Region region = record.get(); @@ -402,7 +402,7 @@ namespace CSMWorld record.setModified (region); } - void RegionSoundListAdapter::setNestedTable(Record& record, + void RegionSoundListAdapter::setTable(Record& record, const NestedTableWrapperBase& nestedTable) const { ESM::Region region = record.get(); @@ -419,7 +419,7 @@ namespace CSMWorld return new NestedTableWrapper >(record.get().mSoundList); } - QVariant RegionSoundListAdapter::getNestedData(const Record& record, + QVariant RegionSoundListAdapter::getData(const Record& record, int subRowIndex, int subColIndex) const { ESM::Region region = record.get(); @@ -438,7 +438,7 @@ namespace CSMWorld } } - void RegionSoundListAdapter::setNestedData(Record& record, + void RegionSoundListAdapter::setData(Record& record, const QVariant& value, int subRowIndex, int subColIndex) const { ESM::Region region = record.get(); @@ -461,12 +461,12 @@ namespace CSMWorld record.setModified (region); } - int RegionSoundListAdapter::getNestedColumnsCount(const Record& record) const + int RegionSoundListAdapter::getColumnsCount(const Record& record) const { return 2; } - int RegionSoundListAdapter::getNestedRowsCount(const Record& record) const + int RegionSoundListAdapter::getRowsCount(const Record& record) const { return static_cast(record.get().mSoundList.size()); } diff --git a/apps/opencs/model/world/nestedcoladapterimp.hpp b/apps/opencs/model/world/nestedcoladapterimp.hpp index 841c3955a1..8d0b0ce7af 100644 --- a/apps/opencs/model/world/nestedcoladapterimp.hpp +++ b/apps/opencs/model/world/nestedcoladapterimp.hpp @@ -42,24 +42,24 @@ namespace CSMWorld public: PathgridPointListAdapter (); - virtual void addNestedRow(Record& record, int position) const; + virtual void addRow(Record& record, int position) const; - virtual void removeNestedRow(Record& record, int rowToRemove) const; + virtual void removeRow(Record& record, int rowToRemove) const; - virtual void setNestedTable(Record& record, + virtual void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const; virtual NestedTableWrapperBase* nestedTable(const Record& record) const; - virtual QVariant getNestedData(const Record& record, + virtual QVariant getData(const Record& record, int subRowIndex, int subColIndex) const; - virtual void setNestedData(Record& record, + virtual void setData(Record& record, const QVariant& value, int subRowIndex, int subColIndex) const; - virtual int getNestedColumnsCount(const Record& record) const; + virtual int getColumnsCount(const Record& record) const; - virtual int getNestedRowsCount(const Record& record) const; + virtual int getRowsCount(const Record& record) const; }; class PathgridEdgeListAdapter : public NestedColumnAdapter @@ -67,24 +67,24 @@ namespace CSMWorld public: PathgridEdgeListAdapter (); - virtual void addNestedRow(Record& record, int position) const; + virtual void addRow(Record& record, int position) const; - virtual void removeNestedRow(Record& record, int rowToRemove) const; + virtual void removeRow(Record& record, int rowToRemove) const; - virtual void setNestedTable(Record& record, + virtual void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const; virtual NestedTableWrapperBase* nestedTable(const Record& record) const; - virtual QVariant getNestedData(const Record& record, + virtual QVariant getData(const Record& record, int subRowIndex, int subColIndex) const; - virtual void setNestedData(Record& record, + virtual void setData(Record& record, const QVariant& value, int subRowIndex, int subColIndex) const; - virtual int getNestedColumnsCount(const Record& record) const; + virtual int getColumnsCount(const Record& record) const; - virtual int getNestedRowsCount(const Record& record) const; + virtual int getRowsCount(const Record& record) const; }; class FactionReactionsAdapter : public NestedColumnAdapter @@ -92,24 +92,24 @@ namespace CSMWorld public: FactionReactionsAdapter (); - virtual void addNestedRow(Record& record, int position) const; + virtual void addRow(Record& record, int position) const; - virtual void removeNestedRow(Record& record, int rowToRemove) const; + virtual void removeRow(Record& record, int rowToRemove) const; - virtual void setNestedTable(Record& record, + virtual void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const; virtual NestedTableWrapperBase* nestedTable(const Record& record) const; - virtual QVariant getNestedData(const Record& record, + virtual QVariant getData(const Record& record, int subRowIndex, int subColIndex) const; - virtual void setNestedData(Record& record, + virtual void setData(Record& record, const QVariant& value, int subRowIndex, int subColIndex) const; - virtual int getNestedColumnsCount(const Record& record) const; + virtual int getColumnsCount(const Record& record) const; - virtual int getNestedRowsCount(const Record& record) const; + virtual int getRowsCount(const Record& record) const; }; class RegionSoundListAdapter : public NestedColumnAdapter @@ -117,24 +117,24 @@ namespace CSMWorld public: RegionSoundListAdapter (); - virtual void addNestedRow(Record& record, int position) const; + virtual void addRow(Record& record, int position) const; - virtual void removeNestedRow(Record& record, int rowToRemove) const; + virtual void removeRow(Record& record, int rowToRemove) const; - virtual void setNestedTable(Record& record, + virtual void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const; virtual NestedTableWrapperBase* nestedTable(const Record& record) const; - virtual QVariant getNestedData(const Record& record, + virtual QVariant getData(const Record& record, int subRowIndex, int subColIndex) const; - virtual void setNestedData(Record& record, + virtual void setData(Record& record, const QVariant& value, int subRowIndex, int subColIndex) const; - virtual int getNestedColumnsCount(const Record& record) const; + virtual int getColumnsCount(const Record& record) const; - virtual int getNestedRowsCount(const Record& record) const; + virtual int getRowsCount(const Record& record) const; }; template @@ -143,7 +143,7 @@ namespace CSMWorld public: SpellListAdapter () {} - virtual void addNestedRow(Record& record, int position) const + virtual void addRow(Record& record, int position) const { ESXRecordT raceOrBthSgn = record.get(); @@ -157,7 +157,7 @@ namespace CSMWorld record.setModified (raceOrBthSgn); } - virtual void removeNestedRow(Record& record, int rowToRemove) const + virtual void removeRow(Record& record, int rowToRemove) const { ESXRecordT raceOrBthSgn = record.get(); @@ -171,7 +171,7 @@ namespace CSMWorld record.setModified (raceOrBthSgn); } - virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) const + virtual void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const { ESXRecordT raceOrBthSgn = record.get(); @@ -187,7 +187,7 @@ namespace CSMWorld return new NestedTableWrapper >(record.get().mPowers.mList); } - virtual QVariant getNestedData(const Record& record, int subRowIndex, int subColIndex) const + virtual QVariant getData(const Record& record, int subRowIndex, int subColIndex) const { ESXRecordT raceOrBthSgn = record.get(); @@ -204,7 +204,7 @@ namespace CSMWorld } } - virtual void setNestedData(Record& record, const QVariant& value, + virtual void setData(Record& record, const QVariant& value, int subRowIndex, int subColIndex) const { ESXRecordT raceOrBthSgn = record.get(); @@ -226,12 +226,12 @@ namespace CSMWorld record.setModified (raceOrBthSgn); } - virtual int getNestedColumnsCount(const Record& record) const + virtual int getColumnsCount(const Record& record) const { return 1; } - virtual int getNestedRowsCount(const Record& record) const + virtual int getRowsCount(const Record& record) const { return static_cast(record.get().mPowers.mList.size()); } @@ -243,7 +243,7 @@ namespace CSMWorld public: EffectsListAdapter () {} - virtual void addNestedRow(Record& record, int position) const + virtual void addRow(Record& record, int position) const { ESXRecordT magic = record.get(); @@ -265,7 +265,7 @@ namespace CSMWorld record.setModified (magic); } - virtual void removeNestedRow(Record& record, int rowToRemove) const + virtual void removeRow(Record& record, int rowToRemove) const { ESXRecordT magic = record.get(); @@ -279,7 +279,7 @@ namespace CSMWorld record.setModified (magic); } - virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) const + virtual void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const { ESXRecordT magic = record.get(); @@ -295,7 +295,7 @@ namespace CSMWorld return new NestedTableWrapper >(record.get().mEffects.mList); } - virtual QVariant getNestedData(const Record& record, int subRowIndex, int subColIndex) const + virtual QVariant getData(const Record& record, int subRowIndex, int subColIndex) const { ESXRecordT magic = record.get(); @@ -331,7 +331,7 @@ namespace CSMWorld } } - virtual void setNestedData(Record& record, const QVariant& value, + virtual void setData(Record& record, const QVariant& value, int subRowIndex, int subColIndex) const { ESXRecordT magic = record.get(); @@ -376,12 +376,12 @@ namespace CSMWorld record.setModified (magic); } - virtual int getNestedColumnsCount(const Record& record) const + virtual int getColumnsCount(const Record& record) const { return 8; } - virtual int getNestedRowsCount(const Record& record) const + virtual int getRowsCount(const Record& record) const { return static_cast(record.get().mEffects.mList.size()); } diff --git a/apps/opencs/model/world/nestedcolumnadapter.hpp b/apps/opencs/model/world/nestedcolumnadapter.hpp index e7e66ed4d4..5e7256fa7c 100644 --- a/apps/opencs/model/world/nestedcolumnadapter.hpp +++ b/apps/opencs/model/world/nestedcolumnadapter.hpp @@ -19,21 +19,21 @@ namespace CSMWorld virtual ~NestedColumnAdapter() {} - virtual void addNestedRow(Record& record, int position) const = 0; + virtual void addRow(Record& record, int position) const = 0; - virtual void removeNestedRow(Record& record, int rowToRemove) const = 0; + virtual void removeRow(Record& record, int rowToRemove) const = 0; - virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) const = 0; + virtual void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const = 0; virtual NestedTableWrapperBase* nestedTable(const Record& record) const = 0; - virtual QVariant getNestedData(const Record& record, int subRowIndex, int subColIndex) const = 0; + virtual QVariant getData(const Record& record, int subRowIndex, int subColIndex) const = 0; - virtual void setNestedData(Record& record, const QVariant& value, int subRowIndex, int subColIndex) const = 0; + virtual void setData(Record& record, const QVariant& value, int subRowIndex, int subColIndex) const = 0; - virtual int getNestedColumnsCount(const Record& record) const = 0; + virtual int getColumnsCount(const Record& record) const = 0; - virtual int getNestedRowsCount(const Record& record) const = 0; + virtual int getRowsCount(const Record& record) const = 0; }; } diff --git a/apps/opencs/model/world/nestedidcollection.hpp b/apps/opencs/model/world/nestedidcollection.hpp index 0cf51b9d89..2b795f9c67 100644 --- a/apps/opencs/model/world/nestedidcollection.hpp +++ b/apps/opencs/model/world/nestedidcollection.hpp @@ -93,7 +93,7 @@ namespace CSMWorld Record record; record.assign(Collection::getRecord(row)); - getAdapter(Collection::getColumn(column)).addNestedRow(record, position); + getAdapter(Collection::getColumn(column)).addRow(record, position); Collection::setRecord(row, record); } @@ -104,7 +104,7 @@ namespace CSMWorld Record record; record.assign(Collection::getRecord(row)); - getAdapter(Collection::getColumn(column)).removeNestedRow(record, subRow); + getAdapter(Collection::getColumn(column)).removeRow(record, subRow); Collection::setRecord(row, record); } @@ -113,7 +113,7 @@ namespace CSMWorld QVariant NestedIdCollection::getNestedData (int row, int column, int subRow, int subColumn) const { - return getAdapter(Collection::getColumn(column)).getNestedData( + return getAdapter(Collection::getColumn(column)).getData( Collection::getRecord(row), subRow, subColumn); } @@ -124,7 +124,7 @@ namespace CSMWorld Record record; record.assign(Collection::getRecord(row)); - getAdapter(Collection::getColumn(column)).setNestedData( + getAdapter(Collection::getColumn(column)).setData( record, data, subRow, subColumn); Collection::setRecord(row, record); @@ -145,7 +145,7 @@ namespace CSMWorld Record record; record.assign(Collection::getRecord(row)); - getAdapter(Collection::getColumn(column)).setNestedTable( + getAdapter(Collection::getColumn(column)).setTable( record, nestedTable); Collection::setRecord(row, record); @@ -154,14 +154,14 @@ namespace CSMWorld template int NestedIdCollection::getNestedRowsCount(int row, int column) const { - return getAdapter(Collection::getColumn(column)).getNestedRowsCount( + return getAdapter(Collection::getColumn(column)).getRowsCount( Collection::getRecord(row)); } template int NestedIdCollection::getNestedColumnsCount(int row, int column) const { - return getAdapter(Collection::getColumn(column)).getNestedColumnsCount( + return getAdapter(Collection::getColumn(column)).getColumnsCount( Collection::getRecord(row)); } diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 5fd888441c..9556c83e38 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -867,7 +867,7 @@ namespace CSMWorld { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); - EffectsListAdapter::addNestedRow(record, position); + EffectsListAdapter::addRow(record, position); } using NestedRefIdAdapterBase::removeNestedRow; @@ -876,7 +876,7 @@ namespace CSMWorld { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); - EffectsListAdapter::removeNestedRow(record, rowToRemove); + EffectsListAdapter::removeRow(record, rowToRemove); } using NestedRefIdAdapterBase::setNestedTable; @@ -885,7 +885,7 @@ namespace CSMWorld { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); - EffectsListAdapter::setNestedTable(record, nestedTable); + EffectsListAdapter::setTable(record, nestedTable); } using NestedRefIdAdapterBase::nestedTable; @@ -903,7 +903,7 @@ namespace CSMWorld { const Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); - return EffectsListAdapter::getNestedData(record, subRowIndex, subColIndex); + return EffectsListAdapter::getData(record, subRowIndex, subColIndex); } using NestedRefIdAdapterBase::setNestedData; @@ -912,14 +912,14 @@ namespace CSMWorld { Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); - EffectsListAdapter::setNestedData(record, value, subRowIndex, subColIndex); + EffectsListAdapter::setData(record, value, subRowIndex, subColIndex); } using NestedRefIdAdapterBase::getNestedColumnsCount; virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const { const Record record; // not used, just a dummy - return EffectsListAdapter::getNestedColumnsCount(record); + return EffectsListAdapter::getColumnsCount(record); } using NestedRefIdAdapterBase::getNestedRowsCount; @@ -927,7 +927,7 @@ namespace CSMWorld { const Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); - return EffectsListAdapter::getNestedRowsCount(record); + return EffectsListAdapter::getRowsCount(record); } }; @@ -1731,7 +1731,7 @@ namespace CSMWorld { case 0: { - if (content.mPart >=0 && content.mPart < ESM::PRT_Count) + if (content.mPart < ESM::PRT_Count) return content.mPart; else throw std::runtime_error("Part Reference Type unexpected value"); From 8b1ac451acd0b5f3838d0a46e2cd7dd150d25f73 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sun, 19 Apr 2015 09:42:44 +1000 Subject: [PATCH 147/185] More warning fixes. --- apps/opencs/model/world/nestedcoladapterimp.cpp | 8 ++++---- apps/opencs/model/world/nestedcoladapterimp.hpp | 12 ++++++------ apps/opencs/model/world/nestedcolumnadapter.hpp | 2 +- apps/opencs/model/world/nestedidcollection.hpp | 2 +- apps/opencs/model/world/refidadapterimp.hpp | 10 +--------- 5 files changed, 13 insertions(+), 21 deletions(-) diff --git a/apps/opencs/model/world/nestedcoladapterimp.cpp b/apps/opencs/model/world/nestedcoladapterimp.cpp index bd6a5c4491..bfb2fb578c 100644 --- a/apps/opencs/model/world/nestedcoladapterimp.cpp +++ b/apps/opencs/model/world/nestedcoladapterimp.cpp @@ -94,7 +94,7 @@ namespace CSMWorld record.setModified (pathgrid); } - NestedTableWrapperBase* PathgridPointListAdapter::nestedTable(const Record& record) const + NestedTableWrapperBase* PathgridPointListAdapter::table(const Record& record) const { // deleted by dtor of NestedTableStoring return new PathgridPointsWrap(record.get()); @@ -192,7 +192,7 @@ namespace CSMWorld record.setModified (pathgrid); } - NestedTableWrapperBase* PathgridEdgeListAdapter::nestedTable(const Record& record) const + NestedTableWrapperBase* PathgridEdgeListAdapter::table(const Record& record) const { // deleted by dtor of NestedTableStoring return new NestedTableWrapper(record.get().mEdges); @@ -293,7 +293,7 @@ namespace CSMWorld record.setModified (faction); } - NestedTableWrapperBase* FactionReactionsAdapter::nestedTable(const Record& record) const + NestedTableWrapperBase* FactionReactionsAdapter::table(const Record& record) const { // deleted by dtor of NestedTableStoring return new NestedTableWrapper >(record.get().mReactions); @@ -413,7 +413,7 @@ namespace CSMWorld record.setModified (region); } - NestedTableWrapperBase* RegionSoundListAdapter::nestedTable(const Record& record) const + NestedTableWrapperBase* RegionSoundListAdapter::table(const Record& record) const { // deleted by dtor of NestedTableStoring return new NestedTableWrapper >(record.get().mSoundList); diff --git a/apps/opencs/model/world/nestedcoladapterimp.hpp b/apps/opencs/model/world/nestedcoladapterimp.hpp index 8d0b0ce7af..4a7101cbac 100644 --- a/apps/opencs/model/world/nestedcoladapterimp.hpp +++ b/apps/opencs/model/world/nestedcoladapterimp.hpp @@ -49,7 +49,7 @@ namespace CSMWorld virtual void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const; - virtual NestedTableWrapperBase* nestedTable(const Record& record) const; + virtual NestedTableWrapperBase* table(const Record& record) const; virtual QVariant getData(const Record& record, int subRowIndex, int subColIndex) const; @@ -74,7 +74,7 @@ namespace CSMWorld virtual void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const; - virtual NestedTableWrapperBase* nestedTable(const Record& record) const; + virtual NestedTableWrapperBase* table(const Record& record) const; virtual QVariant getData(const Record& record, int subRowIndex, int subColIndex) const; @@ -99,7 +99,7 @@ namespace CSMWorld virtual void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const; - virtual NestedTableWrapperBase* nestedTable(const Record& record) const; + virtual NestedTableWrapperBase* table(const Record& record) const; virtual QVariant getData(const Record& record, int subRowIndex, int subColIndex) const; @@ -124,7 +124,7 @@ namespace CSMWorld virtual void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const; - virtual NestedTableWrapperBase* nestedTable(const Record& record) const; + virtual NestedTableWrapperBase* table(const Record& record) const; virtual QVariant getData(const Record& record, int subRowIndex, int subColIndex) const; @@ -181,7 +181,7 @@ namespace CSMWorld record.setModified (raceOrBthSgn); } - virtual NestedTableWrapperBase* nestedTable(const Record& record) const + virtual NestedTableWrapperBase* table(const Record& record) const { // deleted by dtor of NestedTableStoring return new NestedTableWrapper >(record.get().mPowers.mList); @@ -289,7 +289,7 @@ namespace CSMWorld record.setModified (magic); } - virtual NestedTableWrapperBase* nestedTable(const Record& record) const + virtual NestedTableWrapperBase* table(const Record& record) const { // deleted by dtor of NestedTableStoring return new NestedTableWrapper >(record.get().mEffects.mList); diff --git a/apps/opencs/model/world/nestedcolumnadapter.hpp b/apps/opencs/model/world/nestedcolumnadapter.hpp index 5e7256fa7c..462b5a5ab1 100644 --- a/apps/opencs/model/world/nestedcolumnadapter.hpp +++ b/apps/opencs/model/world/nestedcolumnadapter.hpp @@ -25,7 +25,7 @@ namespace CSMWorld virtual void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const = 0; - virtual NestedTableWrapperBase* nestedTable(const Record& record) const = 0; + virtual NestedTableWrapperBase* table(const Record& record) const = 0; virtual QVariant getData(const Record& record, int subRowIndex, int subColIndex) const = 0; diff --git a/apps/opencs/model/world/nestedidcollection.hpp b/apps/opencs/model/world/nestedidcollection.hpp index 2b795f9c67..792a13b7db 100644 --- a/apps/opencs/model/world/nestedidcollection.hpp +++ b/apps/opencs/model/world/nestedidcollection.hpp @@ -134,7 +134,7 @@ namespace CSMWorld CSMWorld::NestedTableWrapperBase* NestedIdCollection::nestedTable(int row, int column) const { - return getAdapter(Collection::getColumn(column)).nestedTable( + return getAdapter(Collection::getColumn(column)).table( Collection::getRecord(row)); } diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 9556c83e38..d3d52d2e1c 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -861,7 +861,6 @@ namespace CSMWorld virtual ~EffectsRefIdAdapter() {} - using NestedRefIdAdapterBase::addNestedRow; virtual void addNestedRow (const RefIdColumn *column, RefIdData& data, int index, int position) const { @@ -870,7 +869,6 @@ namespace CSMWorld EffectsListAdapter::addRow(record, position); } - using NestedRefIdAdapterBase::removeNestedRow; virtual void removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, int rowToRemove) const { @@ -879,7 +877,6 @@ namespace CSMWorld EffectsListAdapter::removeRow(record, rowToRemove); } - using NestedRefIdAdapterBase::setNestedTable; virtual void setNestedTable (const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const { @@ -888,16 +885,14 @@ namespace CSMWorld EffectsListAdapter::setTable(record, nestedTable); } - using NestedRefIdAdapterBase::nestedTable; virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, const RefIdData& data, int index) const { const Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); - return EffectsListAdapter::nestedTable(record); + return EffectsListAdapter::table(record); } - using NestedRefIdAdapterBase::getNestedData; virtual QVariant getNestedData (const RefIdColumn *column, const RefIdData& data, int index, int subRowIndex, int subColIndex) const { @@ -906,7 +901,6 @@ namespace CSMWorld return EffectsListAdapter::getData(record, subRowIndex, subColIndex); } - using NestedRefIdAdapterBase::setNestedData; virtual void setNestedData (const RefIdColumn *column, RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const { @@ -915,14 +909,12 @@ namespace CSMWorld EffectsListAdapter::setData(record, value, subRowIndex, subColIndex); } - using NestedRefIdAdapterBase::getNestedColumnsCount; virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const { const Record record; // not used, just a dummy return EffectsListAdapter::getColumnsCount(record); } - using NestedRefIdAdapterBase::getNestedRowsCount; virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const { const Record& record = From cb3396643b44d07d95df7d17a396103c1959bf58 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sun, 19 Apr 2015 10:32:06 +1000 Subject: [PATCH 148/185] Back to the old layout of dialoguesubview. --- apps/opencs/view/world/dialoguesubview.cpp | 39 ++++++++++------------ 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 6626d67c34..2e800b56f7 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -405,21 +405,22 @@ void CSVWorld::EditWidget::remake(int row) line->setGeometry(QRect(320, 150, 118, 3)); line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); + + QFrame* line2 = new QFrame(mMainWidget); + line2->setObjectName(QString::fromUtf8("line")); + line2->setGeometry(QRect(320, 150, 118, 3)); + line2->setFrameShape(QFrame::HLine); + line2->setFrameShadow(QFrame::Sunken); + QVBoxLayout *mainLayout = new QVBoxLayout(mMainWidget); QGridLayout *lockedLayout = new QGridLayout(); - QScrollArea *scroll = new QScrollArea(mMainWidget); - QWidget *unlockedWidget = new QWidget(scroll); - QVBoxLayout *overLayout = new QVBoxLayout(unlockedWidget); QGridLayout *unlockedLayout = new QGridLayout(); QVBoxLayout *tablesLayout = new QVBoxLayout(); mainLayout->addLayout(lockedLayout, QSizePolicy::Fixed); - mainLayout->addSpacing(5); // FIXME: arbitrary number mainLayout->addWidget(line, 1); - mainLayout->addWidget(scroll, QSizePolicy::Preferred); - overLayout->addLayout(unlockedLayout, QSizePolicy::Preferred); - overLayout->addStretch(1); - mainLayout->addSpacing(5); // FIXME: arbitrary number + mainLayout->addLayout(unlockedLayout, QSizePolicy::Preferred); + mainLayout->addWidget(line2, 1); mainLayout->addLayout(tablesLayout, QSizePolicy::Preferred); mainLayout->addStretch(1); @@ -443,11 +444,15 @@ void CSVWorld::EditWidget::remake(int row) NestedTable* table = new NestedTable(mDocument, mNestedModels.back(), this); // FIXME: does not work well when enum delegates are used - table->setVisible(false); - table->resizeColumnsToContents(); - table->setVisible(true); + //table->resizeColumnsToContents(); table->setEditTriggers(QAbstractItemView::SelectedClicked | QAbstractItemView::CurrentChanged); + int rows = mNestedModels.back()->rowCount(mTable->index(row, i)); + int rowHeight = (rows == 0) ? table->horizontalHeader()->height() : table->rowHeight(0); + int tableMaxHeight = (5 * rowHeight) + + table->horizontalHeader()->height() + 2 * table->frameWidth(); + table->setMinimumHeight(tableMaxHeight); + QLabel* label = new QLabel (mTable->headerData (i, Qt::Horizontal, Qt::DisplayRole).toString(), mMainWidget); @@ -538,18 +543,8 @@ void CSVWorld::EditWidget::remake(int row) mWidgetMapper->setCurrentModelIndex(mTable->index(row, 0)); - if (unlocked != 0) - { + if (unlocked == 0) mainLayout->removeWidget(line); - scroll->setWidget(unlockedWidget); - scroll->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Minimum); - scroll->setWidgetResizable(true); - } - else - { - delete unlockedWidget; - delete scroll; - } this->setWidget(mMainWidget); this->setWidgetResizable(true); From 18162557b00c1c72436e0f4746cfc020a8efd3ba Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sun, 19 Apr 2015 13:31:16 +1000 Subject: [PATCH 149/185] TopicInfos result script are now displayed in dialogue subviews. --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/world/columnbase.hpp | 4 +- apps/opencs/model/world/columns.cpp | 2 + apps/opencs/model/world/columns.hpp | 2 + apps/opencs/model/world/data.cpp | 16 ++- apps/opencs/model/world/data.hpp | 3 +- .../model/world/nestedcoladapterimp.cpp | 58 +++++++++ .../model/world/nestedcoladapterimp.hpp | 26 +++++ .../model/world/nestedinfocollection.cpp | 110 ++++++++++++++++++ .../model/world/nestedinfocollection.hpp | 50 ++++++++ apps/opencs/model/world/refidcollection.cpp | 2 +- 11 files changed, 266 insertions(+), 9 deletions(-) create mode 100644 apps/opencs/model/world/nestedinfocollection.cpp create mode 100644 apps/opencs/model/world/nestedinfocollection.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 9a5fc19331..9fb80324ec 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -25,7 +25,7 @@ opencs_units (model/world opencs_units_noqt (model/world universalid record commands columnbase scriptcontext cell refidcollection refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope - pathgrid landtexture land nestedtablewrapper nestedcollection nestedcoladapterimp + pathgrid landtexture land nestedtablewrapper nestedcollection nestedcoladapterimp nestedinfocollection ) opencs_hdrs_noqt (model/world diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 4c3f9385a0..0e954eccab 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -178,8 +178,8 @@ namespace CSMWorld template struct NestedParentColumn : public Column { - NestedParentColumn (int id) : Column (id, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue) + NestedParentColumn (int id, int flags = ColumnBase::Flag_Dialogue) : Column (id, + ColumnBase::Display_NestedHeader, flags) {} virtual QVariant get (const Record& record) const diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 1b5aefee94..1ea7da6471 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -272,6 +272,8 @@ namespace CSMWorld { ColumnId_PowerList, "Powers" }, { ColumnId_SkillImpact, "Skills" }, + { ColumnId_InfoList, "Info List" }, + { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, { ColumnId_UseValue3, "Use value 3" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 1760bff30d..5a1577ddb3 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -262,6 +262,8 @@ namespace CSMWorld ColumnId_PowerList = 238, ColumnId_SkillImpact = 239, // impact from magic effects + ColumnId_InfoList = 240, + // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. ColumnId_UseValue1 = 0x10000, diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 0490cbe7a1..873d8b78aa 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -193,11 +193,11 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc index = mSpells.getColumns()-1; mSpells.addAdapter (std::make_pair(&mSpells.getColumn(index), new EffectsListAdapter ())); mSpells.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_EffectId)); // false means no edit + new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_EffectId)); mSpells.getNestableColumn(index)->addColumn( new NestedChildColumn (Columns::ColumnId_SkillImpact, ColumnBase::Display_SkillImpact)); mSpells.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_Attribute)); // reuse attribute + new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_Attribute)); mSpells.getNestableColumn(index)->addColumn( new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_EffectRange)); mSpells.getNestableColumn(index)->addColumn( @@ -235,6 +235,13 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mTopicInfos.addColumn (new PcRankColumn); mTopicInfos.addColumn (new SoundFileColumn); mTopicInfos.addColumn (new ResponseColumn); + // Result script + mTopicInfos.addColumn (new NestedParentColumn (Columns::ColumnId_InfoList, + ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List)); + index = mTopicInfos.getColumns()-1; + mTopicInfos.addAdapter (std::make_pair(&mTopicInfos.getColumn(index), new InfoListAdapter ())); + mTopicInfos.getNestableColumn(index)->addColumn( + new NestedChildColumn (Columns::ColumnId_ScriptText, ColumnBase::Display_ScriptLines)); mJournalInfos.addColumn (new StringIdColumn (true)); mJournalInfos.addColumn (new RecordStateColumn); @@ -271,7 +278,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mEnchantments.getNestableColumn(index)->addColumn( new NestedChildColumn (Columns::ColumnId_SkillImpact, ColumnBase::Display_SkillImpact)); mEnchantments.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_Attribute)); // reuse attribute + new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_Attribute)); mEnchantments.getNestableColumn(index)->addColumn( new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_EffectRange)); mEnchantments.getNestableColumn(index)->addColumn( @@ -423,7 +430,8 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc addModel (new IdTree (&mSpells, &mSpells), UniversalId::Type_Spell); addModel (new IdTable (&mTopics), UniversalId::Type_Topic); addModel (new IdTable (&mJournals), UniversalId::Type_Journal); - addModel (new IdTable (&mTopicInfos, IdTable::Feature_ReorderWithinTopic), UniversalId::Type_TopicInfo); + addModel (new IdTree (&mTopicInfos, &mTopicInfos, IdTable::Feature_ReorderWithinTopic), + UniversalId::Type_TopicInfo); addModel (new IdTable (&mJournalInfos, IdTable::Feature_ReorderWithinTopic), UniversalId::Type_JournalInfo); addModel (new IdTable (&mCells, IdTable::Feature_ViewId), UniversalId::Type_Cell); addModel (new IdTree (&mEnchantments, &mEnchantments), UniversalId::Type_Enchantment); diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index 5ab69ac10d..8689b98c0c 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -42,6 +42,7 @@ #include "refidcollection.hpp" #include "refcollection.hpp" #include "infocollection.hpp" +#include "nestedinfocollection.hpp" #include "pathgrid.hpp" #ifndef Q_MOC_RUN #include "subcellcollection.hpp" @@ -85,7 +86,7 @@ namespace CSMWorld IdCollection mDebugProfiles; IdCollection mSoundGens; IdCollection mStartScripts; - InfoCollection mTopicInfos; + NestedInfoCollection mTopicInfos; InfoCollection mJournalInfos; IdCollection mCells; IdCollection mLandTextures; diff --git a/apps/opencs/model/world/nestedcoladapterimp.cpp b/apps/opencs/model/world/nestedcoladapterimp.cpp index bfb2fb578c..d29155a478 100644 --- a/apps/opencs/model/world/nestedcoladapterimp.cpp +++ b/apps/opencs/model/world/nestedcoladapterimp.cpp @@ -5,6 +5,7 @@ #include "idcollection.hpp" #include "pathgrid.hpp" +#include "info.hpp" namespace CSMWorld { @@ -470,4 +471,61 @@ namespace CSMWorld { return static_cast(record.get().mSoundList.size()); } + + InfoListAdapter::InfoListAdapter () {} + + void InfoListAdapter::addRow(Record& record, int position) const + { + throw std::logic_error ("cannot add a row to a fixed table"); + } + + void InfoListAdapter::removeRow(Record& record, int rowToRemove) const + { + throw std::logic_error ("cannot add a row to a fixed table"); + } + + void InfoListAdapter::setTable(Record& record, + const NestedTableWrapperBase& nestedTable) const + { + throw std::logic_error ("table operation not supported"); + } + + NestedTableWrapperBase* InfoListAdapter::table(const Record& record) const + { + throw std::logic_error ("table operation not supported"); + } + + QVariant InfoListAdapter::getData(const Record& record, + int subRowIndex, int subColIndex) const + { + Info info = record.get(); + + if (subColIndex == 0) + return QString(info.mResultScript.c_str()); + else + throw std::runtime_error("Trying to access non-existing column in the nested table!"); + } + + void InfoListAdapter::setData(Record& record, + const QVariant& value, int subRowIndex, int subColIndex) const + { + Info info = record.get(); + + if (subColIndex == 0) + info.mResultScript = value.toString().toStdString(); + else + throw std::runtime_error("Trying to access non-existing column in the nested table!"); + + record.setModified (info); + } + + int InfoListAdapter::getColumnsCount(const Record& record) const + { + return 1; + } + + int InfoListAdapter::getRowsCount(const Record& record) const + { + return 1; // fixed at size 1 + } } diff --git a/apps/opencs/model/world/nestedcoladapterimp.hpp b/apps/opencs/model/world/nestedcoladapterimp.hpp index 4a7101cbac..96dcd943de 100644 --- a/apps/opencs/model/world/nestedcoladapterimp.hpp +++ b/apps/opencs/model/world/nestedcoladapterimp.hpp @@ -21,6 +21,7 @@ namespace ESM namespace CSMWorld { struct Pathgrid; + struct Info; struct PathgridPointsWrap : public NestedTableWrapperBase { @@ -386,6 +387,31 @@ namespace CSMWorld return static_cast(record.get().mEffects.mList.size()); } }; + + class InfoListAdapter : public NestedColumnAdapter + { + public: + InfoListAdapter (); + + virtual void addRow(Record& record, int position) const; + + virtual void removeRow(Record& record, int rowToRemove) const; + + virtual void setTable(Record& record, + const NestedTableWrapperBase& nestedTable) const; + + virtual NestedTableWrapperBase* table(const Record& record) const; + + virtual QVariant getData(const Record& record, + int subRowIndex, int subColIndex) const; + + virtual void setData(Record& record, + const QVariant& value, int subRowIndex, int subColIndex) const; + + virtual int getColumnsCount(const Record& record) const; + + virtual int getRowsCount(const Record& record) const; + }; } #endif // CSM_WOLRD_NESTEDCOLADAPTERIMP_H diff --git a/apps/opencs/model/world/nestedinfocollection.cpp b/apps/opencs/model/world/nestedinfocollection.cpp new file mode 100644 index 0000000000..4abaaf9c02 --- /dev/null +++ b/apps/opencs/model/world/nestedinfocollection.cpp @@ -0,0 +1,110 @@ +#include "nestedinfocollection.hpp" + +#include "nestedcoladapterimp.hpp" + +namespace CSMWorld +{ + NestedInfoCollection::NestedInfoCollection () + {} + + NestedInfoCollection::~NestedInfoCollection() + { + for (std::map* >::iterator + iter (mAdapters.begin()); iter!=mAdapters.end(); ++iter) + { + delete (*iter).second; + } + } + + void NestedInfoCollection::addAdapter(std::pair* > adapter) + { + mAdapters.insert(adapter); + } + + const NestedColumnAdapter& NestedInfoCollection::getAdapter(const ColumnBase &column) const + { + std::map* >::const_iterator iter = + mAdapters.find (&column); + + if (iter==mAdapters.end()) + throw std::logic_error("No such column in the nestedidadapter"); + + return *iter->second; + } + + void NestedInfoCollection::addNestedRow(int row, int column, int position) + { + Record record; + record.assign(Collection >::getRecord(row)); + + getAdapter(Collection >::getColumn(column)).addRow(record, position); + + Collection >::setRecord(row, record); + } + + void NestedInfoCollection::removeNestedRows(int row, int column, int subRow) + { + Record record; + record.assign(Collection >::getRecord(row)); + + getAdapter(Collection >::getColumn(column)).removeRow(record, subRow); + + Collection >::setRecord(row, record); + } + + QVariant NestedInfoCollection::getNestedData (int row, + int column, int subRow, int subColumn) const + { + return getAdapter(Collection >::getColumn(column)).getData( + Collection >::getRecord(row), subRow, subColumn); + } + + void NestedInfoCollection::setNestedData(int row, + int column, const QVariant& data, int subRow, int subColumn) + { + Record record; + record.assign(Collection >::getRecord(row)); + + getAdapter(Collection >::getColumn(column)).setData( + record, data, subRow, subColumn); + + Collection >::setRecord(row, record); + } + + CSMWorld::NestedTableWrapperBase* NestedInfoCollection::nestedTable(int row, + int column) const + { + return getAdapter(Collection >::getColumn(column)).table( + Collection >::getRecord(row)); + } + + void NestedInfoCollection::setNestedTable(int row, + int column, const CSMWorld::NestedTableWrapperBase& nestedTable) + { + Record record; + record.assign(Collection >::getRecord(row)); + + getAdapter(Collection >::getColumn(column)).setTable( + record, nestedTable); + + Collection >::setRecord(row, record); + } + + int NestedInfoCollection::getNestedRowsCount(int row, int column) const + { + return getAdapter(Collection >::getColumn(column)).getRowsCount( + Collection >::getRecord(row)); + } + + int NestedInfoCollection::getNestedColumnsCount(int row, int column) const + { + return getAdapter(Collection >::getColumn(column)).getColumnsCount( + Collection >::getRecord(row)); + } + + CSMWorld::NestableColumn *NestedInfoCollection::getNestableColumn(int column) + { + return Collection >::getNestableColumn(column); + } +} diff --git a/apps/opencs/model/world/nestedinfocollection.hpp b/apps/opencs/model/world/nestedinfocollection.hpp new file mode 100644 index 0000000000..03c0c23496 --- /dev/null +++ b/apps/opencs/model/world/nestedinfocollection.hpp @@ -0,0 +1,50 @@ +#ifndef CSM_WOLRD_NESTEDINFOCOLLECTION_H +#define CSM_WOLRD_NESTEDINFOCOLLECTION_H + +#include + +#include "infocollection.hpp" +#include "nestedcollection.hpp" + +namespace CSMWorld +{ + struct NestedTableWrapperBase; + + template + class NestedColumnAdapter; + + class NestedInfoCollection : public InfoCollection, public NestedCollection + { + std::map* > mAdapters; + + const NestedColumnAdapter& getAdapter(const ColumnBase &column) const; + + public: + + NestedInfoCollection (); + ~NestedInfoCollection(); + + virtual void addNestedRow(int row, int column, int position); + + virtual void removeNestedRows(int row, int column, int subRow); + + virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const; + + virtual void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn); + + virtual NestedTableWrapperBase* nestedTable(int row, int column) const; + + virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable); + + virtual int getNestedRowsCount(int row, int column) const; + + virtual int getNestedColumnsCount(int row, int column) const; + + // this method is inherited from NestedCollection, not from Collection > + virtual NestableColumn *getNestableColumn(int column); + + void addAdapter(std::pair* > adapter); + }; +} + +#endif // CSM_WOLRD_NESTEDINFOCOLLECTION_H diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index caf1041c6d..4a8f398cd0 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -85,7 +85,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.back().addColumn( new NestedChildColumn (Columns::ColumnId_SkillImpact, ColumnBase::Display_SkillImpact)); mColumns.back().addColumn( - new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_Attribute)); // reuse attribute + new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_Attribute)); mColumns.back().addColumn( new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_EffectRange)); mColumns.back().addColumn( From a836446d223462378767ed39730149ceb3f33624 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sun, 19 Apr 2015 21:07:45 +1000 Subject: [PATCH 150/185] Fix assert() triggering due to bad index being passed. --- apps/opencs/view/world/dialoguesubview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 2e800b56f7..f067c32251 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -447,7 +447,7 @@ void CSVWorld::EditWidget::remake(int row) //table->resizeColumnsToContents(); table->setEditTriggers(QAbstractItemView::SelectedClicked | QAbstractItemView::CurrentChanged); - int rows = mNestedModels.back()->rowCount(mTable->index(row, i)); + int rows = mTable->rowCount(mTable->index(row, i)); int rowHeight = (rows == 0) ? table->horizontalHeader()->height() : table->rowHeight(0); int tableMaxHeight = (5 * rowHeight) + table->horizontalHeader()->height() + 2 * table->frameWidth(); From f326b14604048b26722966add5d49bf02aa9db4c Mon Sep 17 00:00:00 2001 From: cc9cii Date: Tue, 21 Apr 2015 10:25:19 +1000 Subject: [PATCH 151/185] Allow Qt to cleanup its signals. --- apps/opencs/model/doc/documentmanager.cpp | 2 +- apps/opencs/view/doc/view.cpp | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/apps/opencs/model/doc/documentmanager.cpp b/apps/opencs/model/doc/documentmanager.cpp index 7a1a86153d..2d444f2451 100644 --- a/apps/opencs/model/doc/documentmanager.cpp +++ b/apps/opencs/model/doc/documentmanager.cpp @@ -69,7 +69,7 @@ void CSMDoc::DocumentManager::removeDocument (CSMDoc::Document *document) throw std::runtime_error ("removing invalid document"); mDocuments.erase (iter); - delete document; + document->deleteLater(); if (mDocuments.empty()) emit lastDocumentDeleted(); diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index aaf8f2d6a7..e430bfa5e3 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -32,10 +32,6 @@ void CSVDoc::View::closeEvent (QCloseEvent *event) event->ignore(); else { - // delete the subviews first - for (QList::iterator iter = mSubViews.begin(); iter != mSubViews.end(); ++iter) - delete *iter; - // closeRequest() returns true if last document mViewManager.removeDocAndView(mDocument); } @@ -98,7 +94,7 @@ void CSVDoc::View::setupEditMenu() QAction *search = new QAction (tr ("Search"), this); connect (search, SIGNAL (triggered()), this, SLOT (addSearchSubView())); - edit->addAction (search); + edit->addAction (search); } void CSVDoc::View::setupViewMenu() From f7c7aeecb3c188db6b5274acef45ac717976d966 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 21 Apr 2015 14:44:51 +0200 Subject: [PATCH 152/185] fixed missing state update when starting a global search --- apps/opencs/model/doc/document.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index cb3b4ba187..31d0aaccdd 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2382,7 +2382,8 @@ CSMWorld::UniversalId CSMDoc::Document::newSearch() void CSMDoc::Document::runSearch (const CSMWorld::UniversalId& searchId, const CSMTools::Search& search) { - return mTools.runSearch (searchId, search); + mTools.runSearch (searchId, search); + emit stateChanged (getState(), this); } void CSMDoc::Document::abortOperation (int type) From b80f8afab8cd3a99e643ac64623e2624645b7e51 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 22 Apr 2015 00:04:46 +0200 Subject: [PATCH 153/185] Readme: Make status badges consistent again --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aa5af0e6d7..811eb87632 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ OpenMW ====== -[![Build Status](https://img.shields.io/travis/OpenMW/openmw.svg?style=plastic)](https://travis-ci.org/OpenMW/openmw) [![Coverity Scan Build Status](https://scan.coverity.com/projects/3740/badge.svg)](https://scan.coverity.com/projects/3740) +[![Build Status](https://img.shields.io/travis/OpenMW/openmw.svg)](https://travis-ci.org/OpenMW/openmw) [![Coverity Scan Build Status](https://scan.coverity.com/projects/3740/badge.svg)](https://scan.coverity.com/projects/3740) OpenMW is an attempt at recreating the engine for the popular role-playing game Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work. From e49b8fe690fa899b72b74844415be46c79e87716 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 22 Apr 2015 01:17:01 +0200 Subject: [PATCH 154/185] Fix persuasion mechanics using player stats instead of NPC's (Fixes #2475) --- .../mwmechanics/mechanicsmanagerimp.cpp | 46 ++++++++++++------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 617f38daf2..da8d49db0f 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -52,6 +52,31 @@ namespace return ((50.f - disposition) * fFightDispMult); } + void getPersuasionRatings(const MWMechanics::NpcStats& stats, float& rating1, float& rating2, float& rating3, bool player) + { + const MWWorld::Store &gmst = + MWBase::Environment::get().getWorld()->getStore().get(); + + float persTerm = stats.getAttribute(ESM::Attribute::Personality).getModified() / gmst.find("fPersonalityMod")->getFloat(); + float luckTerm = stats.getAttribute(ESM::Attribute::Luck).getModified() / gmst.find("fLuckMod")->getFloat(); + float repTerm = stats.getReputation() * gmst.find("fReputationMod")->getFloat(); + float fatigueTerm = stats.getFatigueTerm(); + float levelTerm = stats.getLevel() * gmst.find("fLevelMod")->getFloat(); + + rating1 = (repTerm + luckTerm + persTerm + stats.getSkill(ESM::Skill::Speechcraft).getModified()) * fatigueTerm; + + if (player) + { + rating2 = rating1 + levelTerm; + rating3 = (stats.getSkill(ESM::Skill::Mercantile).getModified() + luckTerm + persTerm) * fatigueTerm; + } + else + { + rating2 = (levelTerm + repTerm + luckTerm + persTerm + stats.getSkill(ESM::Skill::Speechcraft).getModified()) * fatigueTerm; + rating3 = (stats.getSkill(ESM::Skill::Mercantile).getModified() + repTerm + luckTerm + persTerm) * fatigueTerm; + } + } + } namespace MWMechanics @@ -685,24 +710,11 @@ namespace MWMechanics MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld()->getPlayerPtr(); const MWMechanics::NpcStats &playerStats = playerPtr.getClass().getNpcStats(playerPtr); - float persTerm = playerStats.getAttribute(ESM::Attribute::Personality).getModified() - / gmst.find("fPersonalityMod")->getFloat(); + float npcRating1, npcRating2, npcRating3; + getPersuasionRatings(npcStats, npcRating1, npcRating2, npcRating3, false); - float luckTerm = playerStats.getAttribute(ESM::Attribute::Luck).getModified() - / gmst.find("fLuckMod")->getFloat(); - - float repTerm = playerStats.getReputation() * gmst.find("fReputationMod")->getFloat(); - float levelTerm = playerStats.getLevel() * gmst.find("fLevelMod")->getFloat(); - - float fatigueTerm = playerStats.getFatigueTerm(); - - float playerRating1 = (repTerm + luckTerm + persTerm + playerStats.getSkill(ESM::Skill::Speechcraft).getModified()) * fatigueTerm; - float playerRating2 = playerRating1 + levelTerm; - float playerRating3 = (playerStats.getSkill(ESM::Skill::Mercantile).getModified() + luckTerm + persTerm) * fatigueTerm; - - float npcRating1 = (repTerm + luckTerm + persTerm + playerStats.getSkill(ESM::Skill::Speechcraft).getModified()) * fatigueTerm; - float npcRating2 = (levelTerm + repTerm + luckTerm + persTerm + npcStats.getSkill(ESM::Skill::Speechcraft).getModified()) * fatigueTerm; - float npcRating3 = (playerStats.getSkill(ESM::Skill::Mercantile).getModified() + repTerm + luckTerm + persTerm) * fatigueTerm; + float playerRating1, playerRating2, playerRating3; + getPersuasionRatings(playerStats, playerRating1, playerRating2, playerRating3, true); int currentDisposition = std::min(100, std::max(0, int(getDerivedDisposition(npc) + currentTemporaryDispositionDelta))); From 82bc666e002af107a32dbc1f06bce8b4de9cf1b7 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Wed, 22 Apr 2015 09:25:55 +1000 Subject: [PATCH 155/185] Make AI package items to be editable when a new row is added. --- apps/opencs/model/world/refidadapterimp.hpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index d3d52d2e1c..41d8c65d56 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -1363,7 +1363,13 @@ namespace CSMWorld std::vector& list = actor.mAiPackage.mList; ESM::AIPackage newRow; - newRow.mType = ESM::AI_CNDT; + newRow.mType = ESM::AI_Wander; + newRow.mWander.mDistance = 0; + newRow.mWander.mDuration = 0; + newRow.mWander.mTimeOfDay = 0; + for (int i = 0; i < 8; ++i) + newRow.mWander.mIdle[i] = 0; + newRow.mWander.mShouldRepeat = 0; newRow.mCellName = ""; if (position >= (int)list.size()) From 6fcf4ea9e3fdf445ba282a029f63b4d84ac1d8c4 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 23 Apr 2015 14:24:43 +0200 Subject: [PATCH 156/185] In ModifyCommand replace proxy model with the source model (Fixes #2498) --- apps/opencs/model/world/commands.cpp | 21 +++++++++++++++------ apps/opencs/model/world/commands.hpp | 2 +- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/apps/opencs/model/world/commands.cpp b/apps/opencs/model/world/commands.cpp index d12c5d228f..ce82e07bfa 100644 --- a/apps/opencs/model/world/commands.cpp +++ b/apps/opencs/model/world/commands.cpp @@ -1,28 +1,37 @@ #include "commands.hpp" +#include + #include +#include #include "idtable.hpp" #include "idtree.hpp" -#include #include "nestedtablewrapper.hpp" CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelIndex& index, const QVariant& new_, QUndoCommand* parent) -: QUndoCommand (parent), mModel (model), mIndex (index), mNew (new_) +: QUndoCommand (parent), mModel (&model), mIndex (index), mNew (new_) { - setText ("Modify " + mModel.headerData (mIndex.column(), Qt::Horizontal, Qt::DisplayRole).toString()); + if (QAbstractProxyModel *proxy = dynamic_cast (&model)) + { + // Replace proxy with actual model + mIndex = proxy->mapToSource (index); + mModel = proxy->sourceModel(); + } + + setText ("Modify " + mModel->headerData (mIndex.column(), Qt::Horizontal, Qt::DisplayRole).toString()); } void CSMWorld::ModifyCommand::redo() { - mOld = mModel.data (mIndex, Qt::EditRole); - mModel.setData (mIndex, mNew); + mOld = mModel->data (mIndex, Qt::EditRole); + mModel->setData (mIndex, mNew); } void CSMWorld::ModifyCommand::undo() { - mModel.setData (mIndex, mOld); + mModel->setData (mIndex, mOld); } diff --git a/apps/opencs/model/world/commands.hpp b/apps/opencs/model/world/commands.hpp index a70b361783..2bd47ae916 100644 --- a/apps/opencs/model/world/commands.hpp +++ b/apps/opencs/model/world/commands.hpp @@ -26,7 +26,7 @@ namespace CSMWorld class ModifyCommand : public QUndoCommand { - QAbstractItemModel& mModel; + QAbstractItemModel *mModel; QModelIndex mIndex; QVariant mNew; QVariant mOld; From a6925683c69817aad02305356e02e881d9a03c3e Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 25 Apr 2015 06:04:39 +1000 Subject: [PATCH 157/185] Off by one error - can't delete the last element of a refid collection. --- apps/opencs/model/world/refiddata.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index eaa7b115d3..85d16a6eb2 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -130,7 +130,7 @@ namespace CSMWorld template void RefIdDataContainer::erase (int index, int count) { - if (index<0 || index+count>=getSize()) + if (index<0 || index+count>getSize()) throw std::runtime_error ("invalid RefIdDataContainer index"); mContainer.erase (mContainer.begin()+index, mContainer.begin()+index+count); From 8aaa74a9838aeb92710c601369534b3b82433e9a Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 25 Apr 2015 06:06:11 +1000 Subject: [PATCH 158/185] Undo for delete operation in referenceables table. Implemented by saving UniversalId::Type in DeleteCommand. --- apps/opencs/model/world/commanddispatcher.cpp | 24 ++++++++++++++++--- apps/opencs/model/world/commands.cpp | 7 +++--- apps/opencs/model/world/commands.hpp | 4 +++- apps/opencs/model/world/idtable.cpp | 4 ++-- apps/opencs/model/world/idtable.hpp | 3 ++- apps/opencs/model/world/idtree.cpp | 7 ++++++ apps/opencs/model/world/idtree.hpp | 2 ++ 7 files changed, 41 insertions(+), 10 deletions(-) diff --git a/apps/opencs/model/world/commanddispatcher.cpp b/apps/opencs/model/world/commanddispatcher.cpp index ca6faafbc0..d94033d9cf 100644 --- a/apps/opencs/model/world/commanddispatcher.cpp +++ b/apps/opencs/model/world/commanddispatcher.cpp @@ -8,6 +8,7 @@ #include "../doc/document.hpp" #include "idtable.hpp" +#include "idtree.hpp" #include "record.hpp" #include "commands.hpp" @@ -153,7 +154,15 @@ void CSMWorld::CommandDispatcher::executeDelete() std::string id = model.data (model.getModelIndex (*iter, columnIndex)). toString().toUtf8().constData(); - mDocument.getUndoStack().push (new CSMWorld::DeleteCommand (model, id)); + if (mId.getType() == UniversalId::Type_Referenceables) + { + IdTree& tree = dynamic_cast (*mDocument.getData().getTableModel (mId)); + std::pair localIndex = tree.searchId (id); + + mDocument.getUndoStack().push (new CSMWorld::DeleteCommand (model, id, localIndex.second)); + } + else + mDocument.getUndoStack().push (new CSMWorld::DeleteCommand (model, id)); } if (rows.size()>1) @@ -219,8 +228,17 @@ void CSMWorld::CommandDispatcher::executeExtendedDelete() Misc::StringUtils::lowerCase (record.get().mCell))) continue; - mDocument.getUndoStack().push ( - new CSMWorld::DeleteCommand (model, record.get().mId)); + if (mId.getType() == UniversalId::Type_Referenceables) + { + IdTree& tree = dynamic_cast (*mDocument.getData().getTableModel (mId)); + std::pair localIndex = tree.searchId (record.get().mId); + + mDocument.getUndoStack().push ( + new CSMWorld::DeleteCommand (model, record.get().mId, localIndex.second)); + } + else + mDocument.getUndoStack().push ( + new CSMWorld::DeleteCommand (model, record.get().mId)); } } } diff --git a/apps/opencs/model/world/commands.cpp b/apps/opencs/model/world/commands.cpp index ce82e07bfa..5a3190846d 100644 --- a/apps/opencs/model/world/commands.cpp +++ b/apps/opencs/model/world/commands.cpp @@ -103,8 +103,9 @@ void CSMWorld::RevertCommand::undo() mModel.setRecord (mId, *mOld); } -CSMWorld::DeleteCommand::DeleteCommand (IdTable& model, const std::string& id, QUndoCommand* parent) -: QUndoCommand (parent), mModel (model), mId (id), mOld (0) +CSMWorld::DeleteCommand::DeleteCommand (IdTable& model, + const std::string& id, CSMWorld::UniversalId::Type type, QUndoCommand* parent) +: QUndoCommand (parent), mModel (model), mId (id), mOld (0), mType(type) { setText (("Delete record " + id).c_str()); @@ -135,7 +136,7 @@ void CSMWorld::DeleteCommand::redo() void CSMWorld::DeleteCommand::undo() { - mModel.setRecord (mId, *mOld); + mModel.setRecord (mId, *mOld, mType); } diff --git a/apps/opencs/model/world/commands.hpp b/apps/opencs/model/world/commands.hpp index 2bd47ae916..89ca5d1ffd 100644 --- a/apps/opencs/model/world/commands.hpp +++ b/apps/opencs/model/world/commands.hpp @@ -111,6 +111,7 @@ namespace CSMWorld IdTable& mModel; std::string mId; RecordBase *mOld; + UniversalId::Type mType; // not implemented DeleteCommand (const DeleteCommand&); @@ -118,7 +119,8 @@ namespace CSMWorld public: - DeleteCommand (IdTable& model, const std::string& id, QUndoCommand *parent = 0); + DeleteCommand (IdTable& model, const std::string& id, + UniversalId::Type type = UniversalId::Type_None, QUndoCommand *parent = 0); virtual ~DeleteCommand(); diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index 28742c8f2c..2f0164c2d3 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -145,7 +145,7 @@ QModelIndex CSMWorld::IdTable::getModelIndex (const std::string& id, int column) return index(mIdCollection->getIndex (id), column); } -void CSMWorld::IdTable::setRecord (const std::string& id, const RecordBase& record) +void CSMWorld::IdTable::setRecord (const std::string& id, const RecordBase& record, CSMWorld::UniversalId::Type type) { int index = mIdCollection->searchId (id); @@ -155,7 +155,7 @@ void CSMWorld::IdTable::setRecord (const std::string& id, const RecordBase& reco beginInsertRows (QModelIndex(), index, index); - mIdCollection->appendRecord (record); + mIdCollection->appendRecord (record, type); endInsertRows(); } diff --git a/apps/opencs/model/world/idtable.hpp b/apps/opencs/model/world/idtable.hpp index 559a43cb73..9ecba02142 100644 --- a/apps/opencs/model/world/idtable.hpp +++ b/apps/opencs/model/world/idtable.hpp @@ -59,7 +59,8 @@ namespace CSMWorld virtual QModelIndex getModelIndex (const std::string& id, int column) const; - void setRecord (const std::string& id, const RecordBase& record); + void setRecord (const std::string& id, const RecordBase& record, + UniversalId::Type type = UniversalId::Type_None); ///< Add record or overwrite existing recrod. const RecordBase& getRecord (const std::string& id) const; diff --git a/apps/opencs/model/world/idtree.cpp b/apps/opencs/model/world/idtree.cpp index 06db09a0fc..564e4ec2f4 100644 --- a/apps/opencs/model/world/idtree.cpp +++ b/apps/opencs/model/world/idtree.cpp @@ -4,6 +4,7 @@ #include "collectionbase.hpp" #include "nestedcollection.hpp" +#include "refidcollection.hpp" // HACK: for searchId() only #include "columnbase.hpp" // NOTE: parent class still needs idCollection @@ -257,3 +258,9 @@ CSMWorld::NestedTableWrapperBase* CSMWorld::IdTree::nestedTable(const QModelInde return mNestedCollection->nestedTable(index.row(), index.column()); } + +// HACK: to get the UniversalId::Type associated with a particular record +std::pair CSMWorld::IdTree::searchId (const std::string& id) const +{ + return dynamic_cast(idCollection())->getDataSet().searchId(id); +} diff --git a/apps/opencs/model/world/idtree.hpp b/apps/opencs/model/world/idtree.hpp index 5337ed82b8..73cc9bdfd8 100644 --- a/apps/opencs/model/world/idtree.hpp +++ b/apps/opencs/model/world/idtree.hpp @@ -73,6 +73,8 @@ namespace CSMWorld virtual bool hasChildren (const QModelIndex& index) const; + std::pair searchId (const std::string& id) const; + signals: void resetStart(const QString& id); From acb800b8f980f5cdb52974f6ec43def7a6ac7480 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 25 Apr 2015 09:39:37 +1000 Subject: [PATCH 159/185] Resolve merge issues and fix typos. --- apps/opencs/model/world/columnbase.hpp | 2 +- apps/opencs/model/world/ref.cpp | 3 -- apps/opencs/view/world/dialoguesubview.cpp | 42 ++++++++++------------ apps/opencs/view/world/dialoguesubview.hpp | 17 ++------- apps/opencs/view/world/nestedtable.cpp | 4 +++ apps/opencs/view/world/nestedtable.hpp | 3 ++ apps/opencs/view/world/util.cpp | 8 ++--- components/esm/cellref.cpp | 6 ++-- components/esm/cellref.hpp | 13 +++---- 9 files changed, 38 insertions(+), 60 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 257b67d723..71c22a9f07 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -18,7 +18,7 @@ namespace CSMWorld { Role_Flags = Qt::UserRole, Role_Display = Qt::UserRole+1, - Role_ColumnId = Qt::UserRole+1 + Role_ColumnId = Qt::UserRole+2 }; enum Flags diff --git a/apps/opencs/model/world/ref.cpp b/apps/opencs/model/world/ref.cpp index 6612349f7b..13706c950c 100644 --- a/apps/opencs/model/world/ref.cpp +++ b/apps/opencs/model/world/ref.cpp @@ -8,7 +8,6 @@ CSMWorld::CellRef::CellRef() mRefNum.mIndex = 0; mRefNum.mContentFile = 0; } -<<<<<<< HEAD std::pair CSMWorld::CellRef::getCellIndex() const { @@ -17,5 +16,3 @@ std::pair CSMWorld::CellRef::getCellIndex() const return std::make_pair ( std::floor (mPos.pos[0]/cellSize), std::floor (mPos.pos[1]/cellSize)); } -======= ->>>>>>> master diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 12b4c86f67..cf3653c1b2 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -176,18 +176,12 @@ void CSVWorld::DialogueDelegateDispatcherProxy::tableMimeDataDropped(const std:: ==============================DialogueDelegateDispatcher========================================== */ -<<<<<<< HEAD -CSVWorld::DialogueDelegateDispatcher::DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, CSMWorld::CommandDispatcher& commandDispatcher, CSMDoc::Document& document) : -mParent(parent), -mTable(table), -mCommandDispatcher (commandDispatcher), mDocument (document), -======= CSVWorld::DialogueDelegateDispatcher::DialogueDelegateDispatcher(QObject* parent, - CSMWorld::IdTable* table, CSMDoc::Document& document, QAbstractItemModel *model) : + CSMWorld::IdTable* table, CSMWorld::CommandDispatcher& commandDispatcher, + CSMDoc::Document& document, QAbstractItemModel *model) : mParent(parent), mTable(model ? model : table), -mDocument (document), ->>>>>>> master +mCommandDispatcher (commandDispatcher), mDocument (document), mNotEditableDelegate(table, parent) { } @@ -350,10 +344,6 @@ CSVWorld::DialogueDelegateDispatcher::~DialogueDelegateDispatcher() =============================================================EditWidget===================================================== */ -<<<<<<< HEAD -CSVWorld::EditWidget::EditWidget(QWidget *parent, int row, CSMWorld::IdTable* table, CSMWorld::CommandDispatcher& commandDispatcher, CSMDoc::Document& document, bool createAndDelete) : -mDispatcher(this, table, commandDispatcher, document), -======= CSVWorld::EditWidget::~EditWidget() { for (unsigned i = 0; i < mNestedModels.size(); ++i) @@ -363,15 +353,17 @@ CSVWorld::EditWidget::~EditWidget() delete mNestedTableDispatcher; } -CSVWorld::EditWidget::EditWidget(QWidget *parent, int row, CSMWorld::IdTable* table, CSMDoc::Document& document, bool createAndDelete) : -mDispatcher(this, table, document), +CSVWorld::EditWidget::EditWidget(QWidget *parent, + int row, CSMWorld::IdTable* table, CSMWorld::CommandDispatcher& commandDispatcher, + CSMDoc::Document& document, bool createAndDelete) : +mDispatcher(this, table, commandDispatcher, document), mNestedTableDispatcher(NULL), ->>>>>>> master QScrollArea(parent), mWidgetMapper(NULL), mNestedTableMapper(NULL), mMainWidget(NULL), mCommandDispatcher (commandDispatcher), +mDocument (document), mTable(table) { remake (row); @@ -454,7 +446,14 @@ void CSVWorld::EditWidget::remake(int row) { mNestedModels.push_back(new CSMWorld::NestedTableProxyModel (mTable->index(row, i), display, dynamic_cast(mTable))); - NestedTable* table = new NestedTable(mDocument, mNestedModels.back(), this); + int idColumn = mTable->findColumnIndex (CSMWorld::Columns::ColumnId_Id); + int typeColumn = mTable->findColumnIndex (CSMWorld::Columns::ColumnId_RecordType); + + CSMWorld::UniversalId id = CSMWorld::UniversalId( + static_cast (mTable->data (mTable->index (row, typeColumn)).toInt()), + mTable->data (mTable->index (row, idColumn)).toString().toUtf8().constData()); + + NestedTable* table = new NestedTable(mDocument, id, mNestedModels.back(), this); // FIXME: does not work well when enum delegates are used //table->resizeColumnsToContents(); table->setEditTriggers(QAbstractItemView::SelectedClicked | QAbstractItemView::CurrentChanged); @@ -511,7 +510,7 @@ void CSVWorld::EditWidget::remake(int row) mNestedTableMapper->setModel(mNestedModels.back()); // FIXME: lack MIME support? mNestedTableDispatcher = - new DialogueDelegateDispatcher (this, mTable, mDocument, mNestedModels.back()); + new DialogueDelegateDispatcher (this, mTable, mCommandDispatcher, mDocument, mNestedModels.back()); mNestedTableMapper->setItemDelegate(mNestedTableDispatcher); int columnCount = @@ -638,11 +637,8 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM mMainLayout = new QVBoxLayout(mainWidget); -<<<<<<< HEAD - mEditWidget = new EditWidget(mainWidget, mRow, mTable, mCommandDispatcher, document, false); -======= - mEditWidget = new EditWidget(mainWidget, mTable->getModelIndex(mCurrentId, 0).row(), mTable, document, false); ->>>>>>> master + mEditWidget = new EditWidget(mainWidget, + mTable->getModelIndex(mCurrentId, 0).row(), mTable, mCommandDispatcher, document, false); connect(mEditWidget, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)), this, SLOT(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*))); diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index 4d463246aa..b5a44d266f 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -109,10 +109,7 @@ namespace CSVWorld QAbstractItemModel* mTable; -<<<<<<< HEAD CSMWorld::CommandDispatcher& mCommandDispatcher; -======= ->>>>>>> master CSMDoc::Document& mDocument; NotEditableSubDelegate mNotEditableDelegate; @@ -121,15 +118,11 @@ namespace CSVWorld //once we move to the C++11 we should use unique_ptr public: -<<<<<<< HEAD - DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, - CSMWorld::CommandDispatcher& commandDispatcher, CSMDoc::Document& document); -======= DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, + CSMWorld::CommandDispatcher& commandDispatcher, CSMDoc::Document& document, QAbstractItemModel* model = 0); ->>>>>>> master ~DialogueDelegateDispatcher(); @@ -176,23 +169,17 @@ namespace CSVWorld DialogueDelegateDispatcher *mNestedTableDispatcher; QWidget* mMainWidget; CSMWorld::IdTable* mTable; -<<<<<<< HEAD CSMWorld::CommandDispatcher& mCommandDispatcher; - - public: - - EditWidget (QWidget *parent, int row, CSMWorld::IdTable* table, CSMWorld::CommandDispatcher& commandDispatcher, CSMDoc::Document& document, bool createAndDelete = false); -======= CSMDoc::Document& mDocument; std::vector mNestedModels; //Plain, raw C pointers, deleted in the dtor public: EditWidget (QWidget *parent, int row, CSMWorld::IdTable* table, + CSMWorld::CommandDispatcher& commandDispatcher, CSMDoc::Document& document, bool createAndDelete = false); virtual ~EditWidget(); ->>>>>>> master void remake(int row); diff --git a/apps/opencs/view/world/nestedtable.cpp b/apps/opencs/view/world/nestedtable.cpp index 1597c81a35..5c8762020f 100644 --- a/apps/opencs/view/world/nestedtable.cpp +++ b/apps/opencs/view/world/nestedtable.cpp @@ -2,6 +2,7 @@ #include "../../model/world/nestedtableproxymodel.hpp" #include "../../model/world/universalid.hpp" #include "../../model/world/commands.hpp" +#include "../../model/world/commanddispatcher.hpp" #include "util.hpp" #include @@ -10,12 +11,14 @@ #include CSVWorld::NestedTable::NestedTable(CSMDoc::Document& document, + CSMWorld::UniversalId id, CSMWorld::NestedTableProxyModel* model, QWidget* parent) : QTableView(parent), mUndoStack(document.getUndoStack()), mModel(model) { + mDispatcher = new CSMWorld::CommandDispatcher (document, id, this); setSelectionBehavior (QAbstractItemView::SelectRows); setSelectionMode (QAbstractItemView::ExtendedSelection); @@ -31,6 +34,7 @@ CSVWorld::NestedTable::NestedTable(CSMDoc::Document& document, model->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); CommandDelegate *delegate = CommandDelegateFactoryCollection::get().makeDelegate(display, + mDispatcher, document, this); diff --git a/apps/opencs/view/world/nestedtable.hpp b/apps/opencs/view/world/nestedtable.hpp index f41ba43452..b8e91844c2 100644 --- a/apps/opencs/view/world/nestedtable.hpp +++ b/apps/opencs/view/world/nestedtable.hpp @@ -12,6 +12,7 @@ namespace CSMWorld { class NestedTableProxyModel; class UniversalId; + class CommandDispatcher; } namespace CSMDoc @@ -29,9 +30,11 @@ namespace CSVWorld QAction *mRemoveRowAction; QUndoStack& mUndoStack; CSMWorld::NestedTableProxyModel* mModel; + CSMWorld::CommandDispatcher *mDispatcher; public: NestedTable(CSMDoc::Document& document, + CSMWorld::UniversalId id, CSMWorld::NestedTableProxyModel* model, QWidget* parent = NULL); diff --git a/apps/opencs/view/world/util.cpp b/apps/opencs/view/world/util.cpp index fbcfc5215d..8b4bfeaacc 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -124,13 +124,9 @@ void CSVWorld::CommandDelegate::setModelDataImp (QWidget *editor, QAbstractItemM QVariant new_ = hack.getData(); -<<<<<<< HEAD - if (model->data (index)!=new_) - mCommandDispatcher->executeModify (model, index, new_); -======= if ((model->data (index)!=new_) && (model->flags(index) & Qt::ItemIsEditable)) - getUndoStack().push (new CSMWorld::ModifyCommand (*model, index, new_)); ->>>>>>> master + //getUndoStack().push (new CSMWorld::ModifyCommand (*model, index, new_)); // FIXME + mCommandDispatcher->executeModify (model, index, new_); } CSVWorld::CommandDelegate::CommandDelegate (CSMWorld::CommandDispatcher *commandDispatcher, diff --git a/components/esm/cellref.cpp b/components/esm/cellref.cpp index f78cc0c85a..f9f5e161a3 100644 --- a/components/esm/cellref.cpp +++ b/components/esm/cellref.cpp @@ -18,7 +18,7 @@ void ESM::RefNum::save (ESMWriter &esm, bool wide, const std::string& tag) const esm.writeHNT (tag, *this, 8); else { - int refNum = (mIndex & 0xffffff) | ((mContentFile==-1 ? 0xff : mContentFile)<<24); + int refNum = (mIndex & 0xffffff) | ((hasContentFile() ? mContentFile<<24 : 0xff)); esm.writeHNT (tag, refNum, 4); } @@ -27,11 +27,11 @@ void ESM::RefNum::save (ESMWriter &esm, bool wide, const std::string& tag) const void ESM::CellRef::load (ESMReader& esm, bool wideRefNum, bool ignoreRefNum) { - loadId(esm, wideRefNum); + loadId(esm, wideRefNum, ignoreRefNum); loadData(esm); } -void ESM::CellRef::loadId(ESMReader &esm, bool wideRefNum) +void ESM::CellRef::loadId (ESMReader& esm, bool wideRefNum, bool ignoreRefNum) { // According to Hrnchamd, this does not belong to the actual ref. Instead, it is a marker indicating that // the following refs are part of a "temp refs" section. A temp ref is not being tracked by the moved references system. diff --git a/components/esm/cellref.hpp b/components/esm/cellref.hpp index f98b407c65..0fb449e161 100644 --- a/components/esm/cellref.hpp +++ b/components/esm/cellref.hpp @@ -13,21 +13,16 @@ namespace ESM struct RefNum { -<<<<<<< HEAD - int mIndex; - int mContentFile; // -1 no content file + unsigned int mIndex; + int mContentFile; void load (ESMReader& esm, bool wide = false); void save (ESMWriter &esm, bool wide = false, const std::string& tag = "FRMR") const; -======= - unsigned int mIndex; - int mContentFile; enum { RefNum_NoContentFile = -1 }; inline bool hasContentFile() const { return mContentFile != RefNum_NoContentFile; } inline void unset() { mIndex = 0; mContentFile = RefNum_NoContentFile; } ->>>>>>> master }; /* Cell reference. This represents ONE object (of many) inside the @@ -105,9 +100,9 @@ namespace ESM Position mPos; /// Calls loadId and loadData - void load (ESMReader& esm, bool wideRefNum = false); + void load (ESMReader& esm, bool wideRefNum = false, bool ignoreRefNum = false); - void loadId (ESMReader& esm, bool wideRefNum = false); + void loadId (ESMReader& esm, bool wideRefNum = false, bool ignoreRefNum = false); /// Implicitly called by load void loadData (ESMReader& esm); From 932f1f9fbd02b50770a7831d1862bdfde954fdfd Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 25 Apr 2015 15:26:32 +1000 Subject: [PATCH 160/185] Alternative way of finding UniversalId without bloating IdTree. --- apps/opencs/model/world/commanddispatcher.cpp | 22 +++++-------------- apps/opencs/model/world/idtree.cpp | 7 ------ apps/opencs/model/world/idtree.hpp | 2 -- 3 files changed, 6 insertions(+), 25 deletions(-) diff --git a/apps/opencs/model/world/commanddispatcher.cpp b/apps/opencs/model/world/commanddispatcher.cpp index d94033d9cf..199f91e29c 100644 --- a/apps/opencs/model/world/commanddispatcher.cpp +++ b/apps/opencs/model/world/commanddispatcher.cpp @@ -8,7 +8,6 @@ #include "../doc/document.hpp" #include "idtable.hpp" -#include "idtree.hpp" #include "record.hpp" #include "commands.hpp" @@ -156,10 +155,10 @@ void CSMWorld::CommandDispatcher::executeDelete() if (mId.getType() == UniversalId::Type_Referenceables) { - IdTree& tree = dynamic_cast (*mDocument.getData().getTableModel (mId)); - std::pair localIndex = tree.searchId (id); - - mDocument.getUndoStack().push (new CSMWorld::DeleteCommand (model, id, localIndex.second)); + mDocument.getUndoStack().push ( new CSMWorld::DeleteCommand (model, id, + static_cast(model.data (model.index ( + model.getModelIndex (id, columnIndex).row(), + model.findColumnIndex (CSMWorld::Columns::ColumnId_RecordType))).toInt()))); } else mDocument.getUndoStack().push (new CSMWorld::DeleteCommand (model, id)); @@ -228,17 +227,8 @@ void CSMWorld::CommandDispatcher::executeExtendedDelete() Misc::StringUtils::lowerCase (record.get().mCell))) continue; - if (mId.getType() == UniversalId::Type_Referenceables) - { - IdTree& tree = dynamic_cast (*mDocument.getData().getTableModel (mId)); - std::pair localIndex = tree.searchId (record.get().mId); - - mDocument.getUndoStack().push ( - new CSMWorld::DeleteCommand (model, record.get().mId, localIndex.second)); - } - else - mDocument.getUndoStack().push ( - new CSMWorld::DeleteCommand (model, record.get().mId)); + mDocument.getUndoStack().push ( + new CSMWorld::DeleteCommand (model, record.get().mId)); } } } diff --git a/apps/opencs/model/world/idtree.cpp b/apps/opencs/model/world/idtree.cpp index 564e4ec2f4..06db09a0fc 100644 --- a/apps/opencs/model/world/idtree.cpp +++ b/apps/opencs/model/world/idtree.cpp @@ -4,7 +4,6 @@ #include "collectionbase.hpp" #include "nestedcollection.hpp" -#include "refidcollection.hpp" // HACK: for searchId() only #include "columnbase.hpp" // NOTE: parent class still needs idCollection @@ -258,9 +257,3 @@ CSMWorld::NestedTableWrapperBase* CSMWorld::IdTree::nestedTable(const QModelInde return mNestedCollection->nestedTable(index.row(), index.column()); } - -// HACK: to get the UniversalId::Type associated with a particular record -std::pair CSMWorld::IdTree::searchId (const std::string& id) const -{ - return dynamic_cast(idCollection())->getDataSet().searchId(id); -} diff --git a/apps/opencs/model/world/idtree.hpp b/apps/opencs/model/world/idtree.hpp index 73cc9bdfd8..5337ed82b8 100644 --- a/apps/opencs/model/world/idtree.hpp +++ b/apps/opencs/model/world/idtree.hpp @@ -73,8 +73,6 @@ namespace CSMWorld virtual bool hasChildren (const QModelIndex& index) const; - std::pair searchId (const std::string& id) const; - signals: void resetStart(const QString& id); From dcce59f76cb5915216dfaffface63a8592eba85b Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 25 Apr 2015 17:20:02 +1000 Subject: [PATCH 161/185] Pass MovedCellRef info to RefCollection. Still has debugging code. --- apps/opencs/model/world/refcollection.cpp | 21 ++++++++++++++++-- components/esm/loadcell.cpp | 26 +++++++++++++++++++---- components/esm/loadcell.hpp | 3 ++- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/apps/opencs/model/world/refcollection.cpp b/apps/opencs/model/world/refcollection.cpp index 39f85da708..bd4e69d6b2 100644 --- a/apps/opencs/model/world/refcollection.cpp +++ b/apps/opencs/model/world/refcollection.cpp @@ -2,8 +2,10 @@ #include "refcollection.hpp" #include +#include // FIXME: debug only #include +#include #include "ref.hpp" #include "cell.hpp" @@ -20,20 +22,35 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool CellRef ref; bool deleted = false; + ESM::MovedCellRef mref; - while (ESM::Cell::getNextRef (reader, ref, deleted, true)) + // hack to initialise mindex + while (!(mref.mRefNum.mIndex = 0) && ESM::Cell::getNextRef (reader, ref, deleted, true, &mref)) { // Keep mOriginalCell empty when in modified (as an indicator that the // original cell will always be equal the current cell). ref.mOriginalCell = base ? cell2.mId : ""; + if (mref.mRefNum.mIndex != 0 && + ((int)std::floor(ref.mPos.pos[0]/8192) != mref.mTarget[0] || + (int)std::floor(ref.mPos.pos[1]/8192) != mref.mTarget[1])) + { + //std::cout <<"refcollection #" << mref.mTarget[0] << " " << mref.mTarget[1] << std::endl; + } + if (cell.get().isExterior()) { // ignoring moved references sub-record; instead calculate cell from coordinates std::pair index = ref.getCellIndex(); std::ostringstream stream; - stream << "#" << index.first << " " << index.second; + if (mref.mRefNum.mIndex) + { + stream << "#" << mref.mTarget[0] << " " << mref.mTarget[1]; + //std::cout <<"refcollection " + stream.str() << std::endl; + } + else + stream << "#" << index.first << " " << index.second; ref.mCell = stream.str(); } diff --git a/components/esm/loadcell.cpp b/components/esm/loadcell.cpp index d836ec9cfd..aed56f415b 100644 --- a/components/esm/loadcell.cpp +++ b/components/esm/loadcell.cpp @@ -3,6 +3,7 @@ #include #include #include +#include // FIXME: debugging only #include @@ -168,11 +169,12 @@ std::string Cell::getDescription() const } } -bool Cell::getNextRef(ESMReader &esm, CellRef &ref, bool& deleted, bool ignoreMoves) +bool Cell::getNextRef(ESMReader &esm, CellRef &ref, bool& deleted, bool ignoreMoves, MovedCellRef *mref) { // TODO: Try and document reference numbering, I don't think this has been done anywhere else. if (!esm.hasMoreSubs()) return false; + //bool print = false; // FIXME: debugging only // NOTE: We should not need this check. It is a safety check until we have checked // more plugins, and how they treat these moved references. @@ -180,9 +182,12 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref, bool& deleted, bool ignoreMo { if (ignoreMoves) { - MovedCellRef mref; - esm.getHT (mref.mRefNum.mIndex); - esm.getHNOT (mref.mTarget, "CNDT"); + esm.getHT (mref->mRefNum.mIndex); + esm.getHNOT (mref->mTarget, "CNDT"); + //std::cout << "index " + std::to_string(mref->mRefNum.mIndex) + " target " << + //std::to_string(mref->mTarget[0]) + ", " + std::to_string(mref->mTarget[1]) << std::endl; + //print = true; // FIXME: debugging only + adjustRefNum (mref->mRefNum, esm); } else { @@ -194,6 +199,19 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref, bool& deleted, bool ignoreMo ref.load (esm); +#if 0 + // FIXME: debugging only + if (print && + ((int)std::floor(ref.mPos.pos[0]/8192) != mref->mTarget[0] || + (int)std::floor(ref.mPos.pos[1]/8192) != mref->mTarget[1])) + { + std::cout << ref.mRefID << + ", " + std::to_string((int)std::floor(ref.mPos.pos[0]/8192)) << + ", " + std::to_string((int)std::floor(ref.mPos.pos[1]/8192)) << + ", Z: " +std::to_string(ref.mPos.pos[2]) << std::endl; + } +#endif + // Identify references belonging to a parent file and adapt the ID accordingly. adjustRefNum (ref.mRefNum, esm); diff --git a/components/esm/loadcell.hpp b/components/esm/loadcell.hpp index 554fa39674..b78d4075a7 100644 --- a/components/esm/loadcell.hpp +++ b/components/esm/loadcell.hpp @@ -157,7 +157,8 @@ struct Cell reuse one memory location without blanking it between calls. */ /// \param ignoreMoves ignore MVRF record and read reference like a regular CellRef. - static bool getNextRef(ESMReader &esm, CellRef &ref, bool& deleted, bool ignoreMoves = false); + static bool getNextRef(ESMReader &esm, + CellRef &ref, bool& deleted, bool ignoreMoves = false, MovedCellRef *mref = 0); /* This fetches an MVRF record, which is used to track moved references. * Since they are comparably rare, we use a separate method for this. From 2e2d6e04feb8e5cf80b04219b0c1730fe90b26e1 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 25 Apr 2015 17:43:29 +1000 Subject: [PATCH 162/185] gcc friendly version. --- apps/opencs/model/world/refcollection.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/world/refcollection.cpp b/apps/opencs/model/world/refcollection.cpp index bd4e69d6b2..14d4a1db57 100644 --- a/apps/opencs/model/world/refcollection.cpp +++ b/apps/opencs/model/world/refcollection.cpp @@ -31,12 +31,14 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool // original cell will always be equal the current cell). ref.mOriginalCell = base ? cell2.mId : ""; +#if 0 if (mref.mRefNum.mIndex != 0 && ((int)std::floor(ref.mPos.pos[0]/8192) != mref.mTarget[0] || (int)std::floor(ref.mPos.pos[1]/8192) != mref.mTarget[1])) { - //std::cout <<"refcollection #" << mref.mTarget[0] << " " << mref.mTarget[1] << std::endl; + std::cout <<"refcollection #" << mref.mTarget[0] << " " << mref.mTarget[1] << std::endl; } +#endif if (cell.get().isExterior()) { From e668b35b02ee40236a7291cd14f7df3b5fb27b49 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 25 Apr 2015 17:51:31 +1000 Subject: [PATCH 163/185] Fix typo. --- components/esm/cellref.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esm/cellref.cpp b/components/esm/cellref.cpp index f9f5e161a3..ef33f495f1 100644 --- a/components/esm/cellref.cpp +++ b/components/esm/cellref.cpp @@ -18,7 +18,7 @@ void ESM::RefNum::save (ESMWriter &esm, bool wide, const std::string& tag) const esm.writeHNT (tag, *this, 8); else { - int refNum = (mIndex & 0xffffff) | ((hasContentFile() ? mContentFile<<24 : 0xff)); + int refNum = (mIndex & 0xffffff) | ((hasContentFile() ? mContentFile : 0xff)<<24); esm.writeHNT (tag, refNum, 4); } From 74b98f7178584a04d32f9e1b1bc7cd3ab1b1b1ba Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sun, 26 Apr 2015 11:35:46 +1000 Subject: [PATCH 164/185] Fixed initial loading of moved refs. --- apps/opencs/model/world/data.cpp | 13 ++++-- apps/opencs/model/world/idcollection.hpp | 9 ++++ apps/opencs/model/world/refcollection.cpp | 57 ++++++++++++++++------- 3 files changed, 58 insertions(+), 21 deletions(-) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index b25d84829a..91fa556ab7 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -3,6 +3,7 @@ #include #include +#include #include @@ -861,9 +862,15 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages) case ESM::REC_CELL: { - mCells.load (*mReader, mBase); - std::string cellId = Misc::StringUtils::lowerCase (mCells.getId (mCells.getSize()-1)); - mRefs.load (*mReader, mCells.getSize()-1, mBase, mRefLoadCache[cellId], messages); + int index = mCells.load (*mReader, mBase); + if (index < 0 || index >= mCells.getSize()) + { + // log an error and continue loading the refs to the last loaded cell + std::cerr << "Logic error: cell index out of bounds" << std::endl; + index = mCells.getSize()-1; + } + std::string cellId = Misc::StringUtils::lowerCase (mCells.getId (index)); + mRefs.load (*mReader, index, mBase, mRefLoadCache[cellId], messages); break; } diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index f00ea447aa..4eafc59bd5 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -74,6 +74,15 @@ namespace CSMWorld { ESXRecordT record; + // Sometimes id (i.e. NAME of the cell) may be different to the id we stored + // earlier. e.g. NAME == "Vivec, Arena" but id == "#-4 11". Sometime NAME is + // missing altogether for scripts or cells. + // + // In such cases the returned index will be -1. We then try updating the + // IdAccessor's id manually (e.g. set mId of the record to "Vivec, Arena") + // and try getting the index once more after loading the record. The mId of the + // record would have changed to "#-4 11" after the load, and searchId() should find + // it (if this is a modify) int index = this->searchId (id); if (index==-1) diff --git a/apps/opencs/model/world/refcollection.cpp b/apps/opencs/model/world/refcollection.cpp index 14d4a1db57..bd4cf918cf 100644 --- a/apps/opencs/model/world/refcollection.cpp +++ b/apps/opencs/model/world/refcollection.cpp @@ -2,7 +2,6 @@ #include "refcollection.hpp" #include -#include // FIXME: debug only #include #include @@ -25,36 +24,58 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool ESM::MovedCellRef mref; // hack to initialise mindex - while (!(mref.mRefNum.mIndex = 0) && ESM::Cell::getNextRef (reader, ref, deleted, true, &mref)) + while (!(mref.mRefNum.mIndex = 0) && ESM::Cell::getNextRef(reader, ref, deleted, true, &mref)) { // Keep mOriginalCell empty when in modified (as an indicator that the // original cell will always be equal the current cell). ref.mOriginalCell = base ? cell2.mId : ""; -#if 0 - if (mref.mRefNum.mIndex != 0 && - ((int)std::floor(ref.mPos.pos[0]/8192) != mref.mTarget[0] || - (int)std::floor(ref.mPos.pos[1]/8192) != mref.mTarget[1])) - { - std::cout <<"refcollection #" << mref.mTarget[0] << " " << mref.mTarget[1] << std::endl; - } -#endif - if (cell.get().isExterior()) { // ignoring moved references sub-record; instead calculate cell from coordinates std::pair index = ref.getCellIndex(); std::ostringstream stream; - if (mref.mRefNum.mIndex) - { - stream << "#" << mref.mTarget[0] << " " << mref.mTarget[1]; - //std::cout <<"refcollection " + stream.str() << std::endl; - } - else - stream << "#" << index.first << " " << index.second; + stream << "#" << index.first << " " << index.second; ref.mCell = stream.str(); + + // It is not always possibe to ignore moved references sub-record and calculate from + // coordinates. Some mods may place the ref in positions outside normal bounds, + // resulting in non sensical cell id's. + // + // Use the target cell from the MVRF tag but if different output an error message + if (!base && // don't try to update base records + mref.mRefNum.mIndex != 0) // MVRF tag found + { + std::ostringstream stream; + stream << "#" << mref.mTarget[0] << " " << mref.mTarget[1]; + ref.mCell = stream.str(); // overwrite + + ref.mOriginalCell = cell2.mId; + + if (deleted) + { + // FIXME: how to mark the record deleted? + CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Cell, + mCells.getId (cellIndex)); + + messages.add (id, "Moved reference "+ref.mRefID+" is in DELE state"); + + continue; + } + else + { + if (index.first != mref.mTarget[0] || index.second != mref.mTarget[1]) + { + std::cerr << "The Position of moved ref " + << ref.mRefID << " does not match the target cell" << std::endl; + std::cerr << "Position: #" << index.first << " " << index.second + <<", Target #"<< mref.mTarget[0] << " " << mref.mTarget[1] << std::endl; + } + // FIXME: need to transfer the ref to the new cell + } + } } else ref.mCell = cell2.mId; From 7673be6d0fb9a2083d63d421a0e30c886270a372 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sun, 26 Apr 2015 12:18:23 +1000 Subject: [PATCH 165/185] Loading of moved refs complete. --- apps/opencs/model/world/data.cpp | 6 +++--- apps/opencs/model/world/refcollection.cpp | 19 ++++++++++++------- apps/opencs/model/world/refcollection.hpp | 2 +- components/esm/loadcell.cpp | 18 ------------------ 4 files changed, 16 insertions(+), 29 deletions(-) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 91fa556ab7..f4ae78ae72 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -3,7 +3,6 @@ #include #include -#include #include @@ -866,11 +865,12 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages) if (index < 0 || index >= mCells.getSize()) { // log an error and continue loading the refs to the last loaded cell - std::cerr << "Logic error: cell index out of bounds" << std::endl; + CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_None); + messages.add (id, "Logic error: cell index out of bounds"); index = mCells.getSize()-1; } std::string cellId = Misc::StringUtils::lowerCase (mCells.getId (index)); - mRefs.load (*mReader, index, mBase, mRefLoadCache[cellId], messages); + mRefs.load (*mReader, index, mBase, mRefLoadCache, cellId, messages); break; } diff --git a/apps/opencs/model/world/refcollection.cpp b/apps/opencs/model/world/refcollection.cpp index bd4cf918cf..c94ec1dc41 100644 --- a/apps/opencs/model/world/refcollection.cpp +++ b/apps/opencs/model/world/refcollection.cpp @@ -2,6 +2,7 @@ #include "refcollection.hpp" #include +#include #include #include @@ -12,8 +13,10 @@ #include "record.hpp" void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool base, - std::map& cache, CSMDoc::Messages& messages) + std::map >& cache, const std::string& origCellId, + CSMDoc::Messages& messages) { + std::string cellid = origCellId; Record cell = mCells.getRecord (cellIndex); Cell& cell2 = base ? cell.mBase : cell.mModified; @@ -73,18 +76,20 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool std::cerr << "Position: #" << index.first << " " << index.second <<", Target #"<< mref.mTarget[0] << " " << mref.mTarget[1] << std::endl; } - // FIXME: need to transfer the ref to the new cell + + // transfer the ref to the new cell + cellid = ref.mCell; } } } else ref.mCell = cell2.mId; - std::map::iterator iter = cache.find (ref.mRefNum); + std::map::iterator iter = cache[cellid].find (ref.mRefNum); if (deleted) { - if (iter==cache.end()) + if (iter==cache[cellid].end()) { CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Cell, mCells.getId (cellIndex)); @@ -101,7 +106,7 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool if (record.mState==RecordBase::State_BaseOnly) { removeRows (index, 1); - cache.erase (iter); + cache[cellid].erase (iter); } else { @@ -112,7 +117,7 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool continue; } - if (iter==cache.end()) + if (iter==cache[cellid].end()) { // new reference ref.mId = getNewId(); @@ -123,7 +128,7 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool appendRecord (record); - cache.insert (std::make_pair (ref.mRefNum, ref.mId)); + cache[cellid].insert (std::make_pair (ref.mRefNum, ref.mId)); } else { diff --git a/apps/opencs/model/world/refcollection.hpp b/apps/opencs/model/world/refcollection.hpp index 46572752e3..82ec2f390d 100644 --- a/apps/opencs/model/world/refcollection.hpp +++ b/apps/opencs/model/world/refcollection.hpp @@ -27,7 +27,7 @@ namespace CSMWorld {} void load (ESM::ESMReader& reader, int cellIndex, bool base, - std::map& cache, + std::map >& cache, const std::string& cellid, CSMDoc::Messages& messages); ///< Load a sequence of references. diff --git a/components/esm/loadcell.cpp b/components/esm/loadcell.cpp index aed56f415b..0f8897c488 100644 --- a/components/esm/loadcell.cpp +++ b/components/esm/loadcell.cpp @@ -3,7 +3,6 @@ #include #include #include -#include // FIXME: debugging only #include @@ -174,7 +173,6 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref, bool& deleted, bool ignoreMo // TODO: Try and document reference numbering, I don't think this has been done anywhere else. if (!esm.hasMoreSubs()) return false; - //bool print = false; // FIXME: debugging only // NOTE: We should not need this check. It is a safety check until we have checked // more plugins, and how they treat these moved references. @@ -184,9 +182,6 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref, bool& deleted, bool ignoreMo { esm.getHT (mref->mRefNum.mIndex); esm.getHNOT (mref->mTarget, "CNDT"); - //std::cout << "index " + std::to_string(mref->mRefNum.mIndex) + " target " << - //std::to_string(mref->mTarget[0]) + ", " + std::to_string(mref->mTarget[1]) << std::endl; - //print = true; // FIXME: debugging only adjustRefNum (mref->mRefNum, esm); } else @@ -199,19 +194,6 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref, bool& deleted, bool ignoreMo ref.load (esm); -#if 0 - // FIXME: debugging only - if (print && - ((int)std::floor(ref.mPos.pos[0]/8192) != mref->mTarget[0] || - (int)std::floor(ref.mPos.pos[1]/8192) != mref->mTarget[1])) - { - std::cout << ref.mRefID << - ", " + std::to_string((int)std::floor(ref.mPos.pos[0]/8192)) << - ", " + std::to_string((int)std::floor(ref.mPos.pos[1]/8192)) << - ", Z: " +std::to_string(ref.mPos.pos[2]) << std::endl; - } -#endif - // Identify references belonging to a parent file and adapt the ID accordingly. adjustRefNum (ref.mRefNum, esm); From e0d061c37b9fc0f37c729bc8cf54abe8a06f11d1 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sun, 26 Apr 2015 12:32:07 +1000 Subject: [PATCH 166/185] Implemented a workaround for saving moved refs. --- apps/opencs/model/doc/savingstages.cpp | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index e5595ccf69..5a45691d56 100644 --- a/apps/opencs/model/doc/savingstages.cpp +++ b/apps/opencs/model/doc/savingstages.cpp @@ -303,13 +303,34 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages) if (ref.mState==CSMWorld::RecordBase::State_Modified || ref.mState==CSMWorld::RecordBase::State_ModifiedOnly) { + // To get an MVRF tag, the ref's mOriginalCell needs to be non-empty (empty + // is meant to indicate that it is the same as the current cell) and + // different to mCell (its current cell) TODO: the second check seems redundant? + // + // To have mOriginalCell be non-empty, it needs to be loaded as 'base' in + // RefCollection::load() + // + // recalculate the ref's cell location + std::ostringstream stream; + if (!interior) + { + std::pair index = ref.get().getCellIndex(); + stream << "#" << index.first << " " << index.second; + } + if (!ref.get().mOriginalCell.empty() && - ref.get().mOriginalCell!=ref.get().mCell) + ref.get().mOriginalCell!=stream.str()) { ESM::MovedCellRef moved; moved.mRefNum = ref.get().mRefNum; - std::istringstream stream (ref.get().mCell.c_str()); + // Need to fill mTarget with the ref's new position. + // + // For this to work the view tht modified this ref needed to have the + // ref's mCell updted properly. + // + // For now use the temporary solution calculated above + std::istringstream stream (stream.str().c_str()); char ignore; stream >> ignore >> moved.mTarget[0] >> moved.mTarget[1]; From b54e5714c968b29ed3d87ca13bfa376ba28bc192 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sun, 26 Apr 2015 14:55:40 +1000 Subject: [PATCH 167/185] Revert rebasing the moved refs to the new cell, because the original ref may still be referred by a mod. --- apps/opencs/model/doc/savingstages.cpp | 13 ++---- apps/opencs/model/world/data.cpp | 2 +- apps/opencs/model/world/refcollection.cpp | 55 +++++++++++------------ apps/opencs/model/world/refcollection.hpp | 3 +- 4 files changed, 33 insertions(+), 40 deletions(-) diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index 5a45691d56..1f6da2580d 100644 --- a/apps/opencs/model/doc/savingstages.cpp +++ b/apps/opencs/model/doc/savingstages.cpp @@ -303,13 +303,6 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages) if (ref.mState==CSMWorld::RecordBase::State_Modified || ref.mState==CSMWorld::RecordBase::State_ModifiedOnly) { - // To get an MVRF tag, the ref's mOriginalCell needs to be non-empty (empty - // is meant to indicate that it is the same as the current cell) and - // different to mCell (its current cell) TODO: the second check seems redundant? - // - // To have mOriginalCell be non-empty, it needs to be loaded as 'base' in - // RefCollection::load() - // // recalculate the ref's cell location std::ostringstream stream; if (!interior) @@ -318,8 +311,10 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages) stream << "#" << index.first << " " << index.second; } - if (!ref.get().mOriginalCell.empty() && - ref.get().mOriginalCell!=stream.str()) + // 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 ((ref.get().mOriginalCell.empty() ? ref.get().mCell : ref.get().mOriginalCell) + != stream.str()) { ESM::MovedCellRef moved; moved.mRefNum = ref.get().mRefNum; diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index f4ae78ae72..97b34551de 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -870,7 +870,7 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages) index = mCells.getSize()-1; } std::string cellId = Misc::StringUtils::lowerCase (mCells.getId (index)); - mRefs.load (*mReader, index, mBase, mRefLoadCache, cellId, messages); + mRefs.load (*mReader, index, mBase, mRefLoadCache[cellId], messages); break; } diff --git a/apps/opencs/model/world/refcollection.cpp b/apps/opencs/model/world/refcollection.cpp index c94ec1dc41..8f12b6844b 100644 --- a/apps/opencs/model/world/refcollection.cpp +++ b/apps/opencs/model/world/refcollection.cpp @@ -13,10 +13,8 @@ #include "record.hpp" void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool base, - std::map >& cache, const std::string& origCellId, - CSMDoc::Messages& messages) + std::map& cache, CSMDoc::Messages& messages) { - std::string cellid = origCellId; Record cell = mCells.getRecord (cellIndex); Cell& cell2 = base ? cell.mBase : cell.mModified; @@ -43,18 +41,13 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool ref.mCell = stream.str(); - // It is not always possibe to ignore moved references sub-record and calculate from - // coordinates. Some mods may place the ref in positions outside normal bounds, - // resulting in non sensical cell id's. - // - // Use the target cell from the MVRF tag but if different output an error message if (!base && // don't try to update base records mref.mRefNum.mIndex != 0) // MVRF tag found { - std::ostringstream stream; - stream << "#" << mref.mTarget[0] << " " << mref.mTarget[1]; - ref.mCell = stream.str(); // overwrite - + // there is a requirement for a placeholder where the original object was + // + // see the forum discussions here for more details: + // https://forum.openmw.org/viewtopic.php?f=6&t=577&start=30 ref.mOriginalCell = cell2.mId; if (deleted) @@ -67,29 +60,35 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool continue; } - else - { - if (index.first != mref.mTarget[0] || index.second != mref.mTarget[1]) - { - std::cerr << "The Position of moved ref " - << ref.mRefID << " does not match the target cell" << std::endl; - std::cerr << "Position: #" << index.first << " " << index.second - <<", Target #"<< mref.mTarget[0] << " " << mref.mTarget[1] << std::endl; - } - // transfer the ref to the new cell - cellid = ref.mCell; + // It is not always possibe to ignore moved references sub-record and + // calculate from coordinates. Some mods may place the ref in positions + // outside normal bounds, resulting in non sensical cell id's. This often + // happens if the moved ref was deleted. + // + // Use the target cell from the MVRF tag but if different output an error + // message + if (index.first != mref.mTarget[0] || index.second != mref.mTarget[1]) + { + std::cerr << "The Position of moved ref " + << ref.mRefID << " does not match the target cell" << std::endl; + std::cerr << "Position: #" << index.first << " " << index.second + <<", Target #"<< mref.mTarget[0] << " " << mref.mTarget[1] << std::endl; + + std::ostringstream stream; + stream << "#" << mref.mTarget[0] << " " << mref.mTarget[1]; + ref.mCell = stream.str(); // overwrite } } } else ref.mCell = cell2.mId; - std::map::iterator iter = cache[cellid].find (ref.mRefNum); + std::map::iterator iter = cache.find (ref.mRefNum); if (deleted) { - if (iter==cache[cellid].end()) + if (iter==cache.end()) { CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Cell, mCells.getId (cellIndex)); @@ -106,7 +105,7 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool if (record.mState==RecordBase::State_BaseOnly) { removeRows (index, 1); - cache[cellid].erase (iter); + cache.erase (iter); } else { @@ -117,7 +116,7 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool continue; } - if (iter==cache[cellid].end()) + if (iter==cache.end()) { // new reference ref.mId = getNewId(); @@ -128,7 +127,7 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool appendRecord (record); - cache[cellid].insert (std::make_pair (ref.mRefNum, ref.mId)); + cache.insert (std::make_pair (ref.mRefNum, ref.mId)); } else { diff --git a/apps/opencs/model/world/refcollection.hpp b/apps/opencs/model/world/refcollection.hpp index 82ec2f390d..d031398d3f 100644 --- a/apps/opencs/model/world/refcollection.hpp +++ b/apps/opencs/model/world/refcollection.hpp @@ -27,8 +27,7 @@ namespace CSMWorld {} void load (ESM::ESMReader& reader, int cellIndex, bool base, - std::map >& cache, const std::string& cellid, - CSMDoc::Messages& messages); + std::map& cache, CSMDoc::Messages& messages); ///< Load a sequence of references. std::string getNewId(); From 889749a4933b4b641320363cad2b007cfef17658 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sun, 26 Apr 2015 15:44:40 +1000 Subject: [PATCH 168/185] Allow non-empty mOriginalCell (case where a moved ref is moved again) --- apps/opencs/model/doc/savingstages.cpp | 17 ++++++++++++++--- apps/opencs/model/world/commands.cpp | 7 +------ apps/opencs/model/world/commands.hpp | 1 - 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index 1f6da2580d..7363f999e5 100644 --- a/apps/opencs/model/doc/savingstages.cpp +++ b/apps/opencs/model/doc/savingstages.cpp @@ -238,8 +238,19 @@ void CSMDoc::CollectionReferencesStage::perform (int stage, Messages& messages) mState.getSubRecords()[Misc::StringUtils::lowerCase (cellId)]; // collect moved references at the end of the container - if (!record.get().mOriginalCell.empty() && - record.get().mOriginalCell!=record.get().mCell) + bool interior = cellId.substr (0, 1)!="#"; + std::ostringstream stream; + if (!interior) + { + // recalculate the ref's cell location + std::pair index = record.get().getCellIndex(); + 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 ((record.get().mOriginalCell.empty() ? + record.get().mCell : record.get().mOriginalCell) != stream.str() && !interior) indices.push_back (i); else indices.push_front (i); @@ -314,7 +325,7 @@ void CSMDoc::WriteCellCollectionStage::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 ((ref.get().mOriginalCell.empty() ? ref.get().mCell : ref.get().mOriginalCell) - != stream.str()) + != stream.str() && !interior) { ESM::MovedCellRef moved; moved.mRefNum = ref.get().mRefNum; diff --git a/apps/opencs/model/world/commands.cpp b/apps/opencs/model/world/commands.cpp index afc4fcb962..4fe9651486 100644 --- a/apps/opencs/model/world/commands.cpp +++ b/apps/opencs/model/world/commands.cpp @@ -8,11 +8,10 @@ #include #include +#include "idtable.hpp" #include "idtree.hpp" #include "nestedtablewrapper.hpp" -#include "idtable.hpp" - CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelIndex& index, const QVariant& new_, QUndoCommand* parent) : QUndoCommand (parent), mModel (&model), mIndex (index), mNew (new_) @@ -227,10 +226,6 @@ void CSMWorld::UpdateCellCommand::undo() } - - - - CSMWorld::DeleteNestedCommand::DeleteNestedCommand (IdTree& model, const std::string& id, int nestedRow, diff --git a/apps/opencs/model/world/commands.hpp b/apps/opencs/model/world/commands.hpp index ca7c13fea4..f3d2b852ac 100644 --- a/apps/opencs/model/world/commands.hpp +++ b/apps/opencs/model/world/commands.hpp @@ -20,7 +20,6 @@ class QAbstractItemModel; namespace CSMWorld { class IdTable; - class RecordBase; class IdTree; struct RecordBase; struct NestedTableWrapperBase; From 2ef8103cc77c18c46113ebb6d4decc565cdd72ea Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 26 Apr 2015 12:36:05 +0200 Subject: [PATCH 169/185] fixed ReportModel::RemoveRows view updates --- apps/opencs/model/tools/reportmodel.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/tools/reportmodel.cpp b/apps/opencs/model/tools/reportmodel.cpp index 5648ace549..1248e202bf 100644 --- a/apps/opencs/model/tools/reportmodel.cpp +++ b/apps/opencs/model/tools/reportmodel.cpp @@ -120,7 +120,14 @@ bool CSMTools::ReportModel::removeRows (int row, int count, const QModelIndex& p if (parent.isValid()) return false; - mRows.erase (mRows.begin()+row, mRows.begin()+row+count); + if (count>0) + { + beginRemoveRows (parent, row, row+count-1); + + mRows.erase (mRows.begin()+row, mRows.begin()+row+count); + + endRemoveRows(); + } return true; } From 33a8cd245a37cec85dfc7bf1bbb8e32f1f247fa9 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sun, 26 Apr 2015 21:02:50 +1000 Subject: [PATCH 170/185] Fix crash with gcc/linux. --- apps/opencs/model/doc/savingstages.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index 7363f999e5..d6258da6ae 100644 --- a/apps/opencs/model/doc/savingstages.cpp +++ b/apps/opencs/model/doc/savingstages.cpp @@ -331,15 +331,10 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages) moved.mRefNum = ref.get().mRefNum; // Need to fill mTarget with the ref's new position. - // - // For this to work the view tht modified this ref needed to have the - // ref's mCell updted properly. - // - // For now use the temporary solution calculated above - std::istringstream stream (stream.str().c_str()); + std::istringstream istream (stream.str().c_str()); char ignore; - stream >> ignore >> moved.mTarget[0] >> moved.mTarget[1]; + istream >> ignore >> moved.mTarget[0] >> moved.mTarget[1]; ref.get().mRefNum.save (mState.getWriter(), false, "MVRF"); mState.getWriter().writeHNT ("CNDT", moved.mTarget, 8); From dab650a3d54f2ff903716ffe0b0b0f829e3c8aa7 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 26 Apr 2015 13:26:20 +0200 Subject: [PATCH 171/185] remove rows from result table after a successful replace (configurable via user settings) --- apps/opencs/model/settings/usersettings.cpp | 5 ++++- apps/opencs/view/tools/searchsubview.cpp | 9 ++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index 7a975c99c4..6e240c9987 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -220,7 +220,10 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() "Characters after search string"); after->setDefaultValue (10); after->setRange (0, 1000); - after->setToolTip ("Maximum number of character to display in search result after the searched text"); + after->setToolTip ("Maximum number of character to display in search result after the searched text"); + + Setting *autoDelete = createSetting (Type_CheckBox, "auto-delete", "Delete row from result table after a successful replace"); + autoDelete->setDefaultValue ("true"); } { diff --git a/apps/opencs/view/tools/searchsubview.cpp b/apps/opencs/view/tools/searchsubview.cpp index 5743ad7614..9a654c802f 100644 --- a/apps/opencs/view/tools/searchsubview.cpp +++ b/apps/opencs/view/tools/searchsubview.cpp @@ -7,6 +7,7 @@ #include "../../model/tools/search.hpp" #include "../../model/tools/reportmodel.hpp" #include "../../model/world/idtablebase.hpp" +#include "../../model/settings/usersettings.hpp" #include "reporttable.hpp" #include "searchbox.hpp" @@ -22,7 +23,10 @@ void CSVTools::SearchSubView::replace (bool selection) const CSMTools::ReportModel& model = dynamic_cast (*mTable->model()); - + + bool autoDelete = CSMSettings::UserSettings::instance().setting ( + "search/auto-delete", QString ("true"))=="true"; + // We are running through the indices in reverse order to avoid messing up multiple results // in a single string. for (std::vector::const_reverse_iterator iter (indices.rbegin()); iter!=indices.rend(); ++iter) @@ -38,6 +42,9 @@ void CSVTools::SearchSubView::replace (bool selection) mSearch.replace (mDocument, table, id, hint, replace); mTable->flagAsReplaced (*iter); + + if (autoDelete) + mTable->model()->removeRows (*iter, 1); } } From 6fac4c5dd981d0f11f409fb9099e04e01e826e93 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 26 Apr 2015 13:31:35 +0200 Subject: [PATCH 172/185] made user settings handling in search sub view more consistent --- apps/opencs/view/tools/searchsubview.cpp | 18 +++++++----------- apps/opencs/view/tools/searchsubview.hpp | 2 -- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/apps/opencs/view/tools/searchsubview.cpp b/apps/opencs/view/tools/searchsubview.cpp index 9a654c802f..2038612a26 100644 --- a/apps/opencs/view/tools/searchsubview.cpp +++ b/apps/opencs/view/tools/searchsubview.cpp @@ -49,8 +49,7 @@ void CSVTools::SearchSubView::replace (bool selection) } CSVTools::SearchSubView::SearchSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) -: CSVDoc::SubView (id), mDocument (document), mPaddingBefore (10), mPaddingAfter (10), - mLocked (false) +: CSVDoc::SubView (id), mDocument (document), mLocked (false) { QVBoxLayout *layout = new QVBoxLayout; @@ -91,14 +90,6 @@ void CSVTools::SearchSubView::setEditLock (bool locked) void CSVTools::SearchSubView::updateUserSetting (const QString &name, const QStringList &list) { mTable->updateUserSetting (name, list); - - if (!list.empty()) - { - if (name=="search/char-before") - mPaddingBefore = list.at (0).toInt(); - else if (name=="search/char-after") - mPaddingAfter = list.at (0).toInt(); - } } void CSVTools::SearchSubView::stateChanged (int state, CSMDoc::Document *document) @@ -108,8 +99,13 @@ void CSVTools::SearchSubView::stateChanged (int state, CSMDoc::Document *documen void CSVTools::SearchSubView::startSearch (const CSMTools::Search& search) { + CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance(); + + int paddingBefore = userSettings.setting ("search/char-before", QString ("5")).toInt(); + int paddingAfter = userSettings.setting ("search/char-after", QString ("5")).toInt(); + mSearch = search; - mSearch.setPadding (mPaddingBefore, mPaddingAfter); + mSearch.setPadding (paddingBefore, paddingAfter); mTable->clear(); mDocument.runSearch (getUniversalId(), mSearch); diff --git a/apps/opencs/view/tools/searchsubview.hpp b/apps/opencs/view/tools/searchsubview.hpp index eeefa9afbf..6dedd6ef2b 100644 --- a/apps/opencs/view/tools/searchsubview.hpp +++ b/apps/opencs/view/tools/searchsubview.hpp @@ -26,8 +26,6 @@ namespace CSVTools ReportTable *mTable; SearchBox mSearchBox; CSMDoc::Document& mDocument; - int mPaddingBefore; - int mPaddingAfter; CSMTools::Search mSearch; bool mLocked; From ae5de0cb2b1ad90ded17fc227a513979dd8118e9 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 27 Apr 2015 22:43:09 +0200 Subject: [PATCH 173/185] implemented additional check before performing replace (make sure data hasn't been changed since the search) --- apps/opencs/model/tools/search.cpp | 17 ++++++++++++++++ apps/opencs/model/tools/search.hpp | 4 ++++ apps/opencs/view/tools/searchsubview.cpp | 26 +++++++++++++++++------- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/apps/opencs/model/tools/search.cpp b/apps/opencs/model/tools/search.cpp index cb88507547..7eb531161e 100644 --- a/apps/opencs/model/tools/search.cpp +++ b/apps/opencs/model/tools/search.cpp @@ -276,4 +276,21 @@ void CSMTools::Search::replace (CSMDoc::Document& document, CSMWorld::IdTableBas new CSMWorld::ModifyCommand (*model, index, QString::fromUtf8 (newText.c_str()))); } } + +bool CSMTools::Search::verify (CSMDoc::Document& document, CSMWorld::IdTableBase *model, + const CSMWorld::UniversalId& id, const std::string& messageHint) const +{ + CSMDoc::Messages messages; + + int row = model->getModelIndex (id.getId(), + model->findColumnIndex (CSMWorld::Columns::ColumnId_Id)).row(); + + searchRow (model, row, messages); + + for (CSMDoc::Messages::Iterator iter (messages.begin()); iter!=messages.end(); ++iter) + if (iter->mHint==messageHint) + return true; + + return false; +} diff --git a/apps/opencs/model/tools/search.hpp b/apps/opencs/model/tools/search.hpp index c9dfc4c446..69b98bbdb2 100644 --- a/apps/opencs/model/tools/search.hpp +++ b/apps/opencs/model/tools/search.hpp @@ -88,6 +88,10 @@ namespace CSMTools void replace (CSMDoc::Document& document, CSMWorld::IdTableBase *model, const CSMWorld::UniversalId& id, const std::string& messageHint, const std::string& replaceText) const; + + // Check if model still matches search results. + bool verify (CSMDoc::Document& document, CSMWorld::IdTableBase *model, + const CSMWorld::UniversalId& id, const std::string& messageHint) const; }; } diff --git a/apps/opencs/view/tools/searchsubview.cpp b/apps/opencs/view/tools/searchsubview.cpp index 2038612a26..32c26ee969 100644 --- a/apps/opencs/view/tools/searchsubview.cpp +++ b/apps/opencs/view/tools/searchsubview.cpp @@ -26,6 +26,9 @@ void CSVTools::SearchSubView::replace (bool selection) bool autoDelete = CSMSettings::UserSettings::instance().setting ( "search/auto-delete", QString ("true"))=="true"; + + CSMTools::Search search (mSearch); + CSMWorld::IdTableBase *currentTable = 0; // We are running through the indices in reverse order to avoid messing up multiple results // in a single string. @@ -37,14 +40,23 @@ void CSVTools::SearchSubView::replace (bool selection) CSMWorld::IdTableBase *table = &dynamic_cast ( *mDocument.getData().getTableModel (type)); - - std::string hint = model.getHint (*iter); - - mSearch.replace (mDocument, table, id, hint, replace); - mTable->flagAsReplaced (*iter); - if (autoDelete) - mTable->model()->removeRows (*iter, 1); + if (table!=currentTable) + { + search.configure (table); + currentTable = table; + } + + std::string hint = model.getHint (*iter); + + if (search.verify (mDocument, table, id, hint)) + { + search.replace (mDocument, table, id, hint, replace); + mTable->flagAsReplaced (*iter); + + if (autoDelete) + mTable->model()->removeRows (*iter, 1); + } } } From 49884f54f7f00e1d4413b77eae3d6091043aa016 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Tue, 28 Apr 2015 08:07:01 +1000 Subject: [PATCH 174/185] Fix loading moved references. --- apps/opencs/model/world/data.cpp | 4 ++-- apps/opencs/model/world/refcollection.cpp | 8 +++++++- apps/opencs/view/world/util.cpp | 1 - 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 97b34551de..fc4532fb0e 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -458,6 +458,8 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc UniversalId::Type_Texture); addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_Videos)), UniversalId::Type_Video); + + mRefLoadCache.clear(); // clear here rather than startLoading() and continueLoading() for multiple content files } CSMWorld::Data::~Data() @@ -779,7 +781,6 @@ int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base mReader = 0; mDialogue = 0; - mRefLoadCache.clear(); mReader = new ESM::ESMReader; mReader->setEncoder (&mEncoder); @@ -816,7 +817,6 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages) mReader = 0; mDialogue = 0; - mRefLoadCache.clear(); return true; } diff --git a/apps/opencs/model/world/refcollection.cpp b/apps/opencs/model/world/refcollection.cpp index 8f12b6844b..ff30dafae6 100644 --- a/apps/opencs/model/world/refcollection.cpp +++ b/apps/opencs/model/world/refcollection.cpp @@ -84,7 +84,13 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool else ref.mCell = cell2.mId; - std::map::iterator iter = cache.find (ref.mRefNum); + // ignore content file number + std::map::iterator iter = cache.begin(); + for (; iter != cache.end(); ++iter) + { + if (ref.mRefNum.mIndex == iter->first.mIndex) + break; + } if (deleted) { diff --git a/apps/opencs/view/world/util.cpp b/apps/opencs/view/world/util.cpp index 8b4bfeaacc..a11b5bdded 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -125,7 +125,6 @@ void CSVWorld::CommandDelegate::setModelDataImp (QWidget *editor, QAbstractItemM QVariant new_ = hack.getData(); if ((model->data (index)!=new_) && (model->flags(index) & Qt::ItemIsEditable)) - //getUndoStack().push (new CSMWorld::ModifyCommand (*model, index, new_)); // FIXME mCommandDispatcher->executeModify (model, index, new_); } From e69687b0f290a6ea519d167d467530ddc0a0de6e Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 28 Apr 2015 14:06:52 +0200 Subject: [PATCH 175/185] silenced a warning (potentially unintialised variable) --- components/nif/nifkey.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/nif/nifkey.hpp b/components/nif/nifkey.hpp index cb81427201..b36b1d8cb1 100644 --- a/components/nif/nifkey.hpp +++ b/components/nif/nifkey.hpp @@ -18,6 +18,8 @@ struct KeyT { float mTension; // Only for TBC interpolation float mBias; // Only for TBC interpolation float mContinuity; // Only for TBC interpolation + + KeyT() : mTension (0), mBias (0), mContinuity (0) {} }; typedef KeyT FloatKey; typedef KeyT Vector3Key; From 28048c0bf36e267320f6e4ca43d2998829be20d8 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Tue, 28 Apr 2015 23:07:42 +1000 Subject: [PATCH 176/185] Simple line numbering and fixed-width fonts for the script dialogue. Based on Qt examples. Should resolve Bugs #2505 and #2512. --- apps/opencs/view/world/scriptedit.cpp | 122 ++++++++++++++++++++++++++ apps/opencs/view/world/scriptedit.hpp | 29 +++++- 2 files changed, 150 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/world/scriptedit.cpp b/apps/opencs/view/world/scriptedit.cpp index 271b0316d3..991e58ae77 100644 --- a/apps/opencs/view/world/scriptedit.cpp +++ b/apps/opencs/view/world/scriptedit.cpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include "../../model/doc/document.hpp" @@ -72,6 +74,20 @@ CSVWorld::ScriptEdit::ScriptEdit (const CSMDoc::Document& document, ScriptHighli connect (&mUpdateTimer, SIGNAL (timeout()), this, SLOT (updateHighlighting())); mUpdateTimer.setSingleShot (true); + + // FIXME: make this configurable or provide a font selector dialogue + // FIXME: save QFontInfo somewhere before switching to a new one + QFont font("Monospace"); + font.setStyleHint(QFont::TypeWriter); + setFont(font); + + // FIXME: make this configurable + lineNumberArea = new LineNumberArea(this); + + connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int))); + connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int))); + + updateLineNumberAreaWidth(0); } bool CSVWorld::ScriptEdit::isChangeLocked() const @@ -157,3 +173,109 @@ void CSVWorld::ScriptEdit::updateHighlighting() mHighlighter->rehighlight(); } + +int CSVWorld::ScriptEdit::lineNumberAreaWidth() +{ + int digits = 1; + int max = qMax(1, blockCount()); + while (max >= 10) + { + max /= 10; + ++digits; + } + + int space = 3 + fontMetrics().width(QLatin1Char('9')) * digits; + + return space; +} + +void CSVWorld::ScriptEdit::updateLineNumberAreaWidth(int /* newBlockCount */) +{ + setViewportMargins(lineNumberAreaWidth(), 0, 0, 0); +} + +void CSVWorld::ScriptEdit::updateLineNumberArea(const QRect &rect, int dy) +{ + if (dy) + lineNumberArea->scroll(0, dy); + else + lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height()); + + if (rect.contains(viewport()->rect())) + updateLineNumberAreaWidth(0); +} + +void CSVWorld::ScriptEdit::resizeEvent(QResizeEvent *e) +{ + QPlainTextEdit::resizeEvent(e); + + QRect cr = contentsRect(); + lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height())); +} + +void CSVWorld::ScriptEdit::lineNumberAreaPaintEvent(QPaintEvent *event) +{ + QPainter painter(lineNumberArea); + + QTextBlock block = firstVisibleBlock(); + int blockNumber = block.blockNumber(); + int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top(); + int bottom = top + (int) blockBoundingRect(block).height(); + + int startBlock = textCursor().blockNumber(); + int endBlock = textCursor().blockNumber(); + if(textCursor().hasSelection()) + { + QString str = textCursor().selection().toPlainText(); + int selectedLines = str.count("\n")+1; + if(textCursor().position() < textCursor().anchor()) + endBlock += selectedLines; + else + startBlock -= selectedLines; + } + painter.setBackgroundMode(Qt::OpaqueMode); + QFont font = painter.font(); + QBrush background = painter.background(); + + while (block.isValid() && top <= event->rect().bottom()) + { + if (block.isVisible() && bottom >= event->rect().top()) + { + QFont newFont = painter.font(); + QString number = QString::number(blockNumber + 1); + if(blockNumber >= startBlock && blockNumber <= endBlock) + { + painter.setBackground(Qt::cyan); + painter.setPen(Qt::darkMagenta); + newFont.setBold(true); + } + else + { + painter.setBackground(background); + painter.setPen(Qt::black); + } + painter.setFont(newFont); + painter.drawText(0, top, lineNumberArea->width(), fontMetrics().height(), + Qt::AlignRight, number); + painter.setFont(font); + } + + block = block.next(); + top = bottom; + bottom = top + (int) blockBoundingRect(block).height(); + ++blockNumber; + } +} + +CSVWorld::LineNumberArea::LineNumberArea(ScriptEdit *editor) : QWidget(editor), mScriptEdit(editor) +{} + +QSize CSVWorld::LineNumberArea::sizeHint() const +{ + return QSize(mScriptEdit->lineNumberAreaWidth(), 0); +} + +void CSVWorld::LineNumberArea::paintEvent(QPaintEvent *event) +{ + mScriptEdit->lineNumberAreaPaintEvent(event); +} diff --git a/apps/opencs/view/world/scriptedit.hpp b/apps/opencs/view/world/scriptedit.hpp index 0192bc5503..90fe2917e5 100644 --- a/apps/opencs/view/world/scriptedit.hpp +++ b/apps/opencs/view/world/scriptedit.hpp @@ -2,6 +2,7 @@ #define SCRIPTEDIT_H #include +#include #include #include @@ -9,7 +10,6 @@ #include "scripthighlighter.hpp" -class QWidget; class QRegExp; namespace CSMDoc @@ -19,6 +19,8 @@ namespace CSMDoc namespace CSVWorld { + class LineNumberArea; + class ScriptEdit : public QPlainTextEdit { Q_OBJECT @@ -45,6 +47,7 @@ namespace CSVWorld int mChangeLocked; ScriptHighlighter *mHighlighter; QTimer mUpdateTimer; + QWidget *lineNumberArea; public: @@ -56,6 +59,13 @@ namespace CSVWorld /// \note This mechanism is used to avoid infinite update recursions bool isChangeLocked() const; + void lineNumberAreaPaintEvent(QPaintEvent *event); + int lineNumberAreaWidth(); + + protected: + + virtual void resizeEvent(QResizeEvent *e); + private: QVector mAllowedTypes; const CSMDoc::Document& mDocument; @@ -74,6 +84,23 @@ namespace CSVWorld void idListChanged(); void updateHighlighting(); + + void updateLineNumberAreaWidth(int newBlockCount); + void updateLineNumberArea(const QRect &, int); + }; + + class LineNumberArea : public QWidget + { + ScriptEdit *mScriptEdit; + + public: + + LineNumberArea(ScriptEdit *editor); + QSize sizeHint() const; + + protected: + + void paintEvent(QPaintEvent *event); }; } #endif // SCRIPTEDIT_H From 997347b01eb2f0ab8e0c73f7839613ce21b350a8 Mon Sep 17 00:00:00 2001 From: Rohit Nirmal Date: Sat, 25 Apr 2015 13:37:42 -0500 Subject: [PATCH 177/185] Silence -Wreorder warnings. --- apps/launcher/datafilespage.cpp | 4 ++-- apps/launcher/maindialog.cpp | 2 +- apps/opencs/view/settings/rangeview.cpp | 2 +- apps/opencs/view/settings/textview.cpp | 2 +- apps/openmw/engine.cpp | 14 ++++++------- apps/openmw/mwgui/hud.cpp | 12 +++++------ apps/openmw/mwgui/mainmenu.cpp | 4 ++-- apps/openmw/mwgui/spellicons.hpp | 4 ++-- apps/openmw/mwgui/spellmodel.hpp | 4 ++-- apps/openmw/mwgui/spellview.cpp | 4 ++-- apps/openmw/mwgui/tooltips.hpp | 6 +++--- apps/openmw/mwgui/tradewindow.cpp | 6 +++--- apps/openmw/mwgui/widgets.hpp | 14 ++++++------- apps/openmw/mwgui/windowmanagerimp.cpp | 6 +++--- apps/openmw/mwinput/inputmanagerimp.cpp | 24 +++++++++++----------- apps/openmw/mwmechanics/aicombataction.hpp | 2 +- apps/openmw/mwrender/animation.cpp | 2 +- apps/openmw/mwrender/characterpreview.cpp | 14 ++++++------- apps/openmw/mwrender/debugging.cpp | 6 +++--- apps/openmw/mwrender/localmap.cpp | 4 ++-- apps/openmw/mwrender/npcanimation.cpp | 10 ++++----- apps/openmw/mwrender/renderingmanager.cpp | 8 ++++---- apps/openmw/mwrender/sky.cpp | 24 +++++++++++----------- apps/openmw/mwrender/water.hpp | 6 +++--- apps/wizard/mainwizard.cpp | 4 ++-- components/esm/esmreader.cpp | 4 ++-- components/esm/esmwriter.cpp | 4 ++-- components/esm/loadcell.hpp | 4 ++-- components/esm/loadland.cpp | 2 +- components/files/fixedpath.hpp | 2 +- components/nif/nifstream.hpp | 2 +- components/nifbullet/bulletnifloader.hpp | 2 +- components/nifogre/ogrenifloader.hpp | 2 +- components/terrain/defaultworld.cpp | 14 ++++++------- components/terrain/quadtreenode.cpp | 4 ++-- components/terrain/world.cpp | 12 +++++------ components/widgets/list.cpp | 4 ++-- libs/openengine/bullet/physic.cpp | 14 ++++++------- libs/openengine/gui/manager.cpp | 2 +- 39 files changed, 129 insertions(+), 131 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 7861894b08..ec2e1246ef 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -24,10 +24,10 @@ const char *Launcher::DataFilesPage::mDefaultContentListName = "Default"; Launcher::DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, Config::GameSettings &gameSettings, Config::LauncherSettings &launcherSettings, QWidget *parent) - : mCfgMgr(cfg) + : QWidget(parent) + , mCfgMgr(cfg) , mGameSettings(gameSettings) , mLauncherSettings(launcherSettings) - , QWidget(parent) { ui.setupUi (this); setObjectName ("DataFilesPage"); diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index 4c142231d5..00e6a9aa29 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -25,7 +25,7 @@ using namespace Process; Launcher::MainDialog::MainDialog(QWidget *parent) - : mGameSettings(mCfgMgr), QMainWindow (parent) + : QMainWindow(parent), mGameSettings (mCfgMgr) { setupUi(this); diff --git a/apps/opencs/view/settings/rangeview.cpp b/apps/opencs/view/settings/rangeview.cpp index 246f7ece25..5893c5d0da 100644 --- a/apps/opencs/view/settings/rangeview.cpp +++ b/apps/opencs/view/settings/rangeview.cpp @@ -12,7 +12,7 @@ CSVSettings::RangeView::RangeView (CSMSettings::Setting *setting, Page *parent) - : mRangeWidget (0), mRangeType (setting->type()), View (setting, parent) + : View (setting, parent), mRangeWidget (0), mRangeType (setting->type()) { mRangeWidget = 0; diff --git a/apps/opencs/view/settings/textview.cpp b/apps/opencs/view/settings/textview.cpp index 6886732dbe..a6ab657fe2 100644 --- a/apps/opencs/view/settings/textview.cpp +++ b/apps/opencs/view/settings/textview.cpp @@ -5,7 +5,7 @@ #include "../../model/settings/setting.hpp" CSVSettings::TextView::TextView(CSMSettings::Setting *setting, Page *parent) - : mDelimiter (setting->delimiter()), View (setting, parent) + : View (setting, parent), mDelimiter (setting->delimiter()) { if (setting->isMultiLine()) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index a4bb8c5380..4496490d42 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -174,24 +174,24 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) } OMW::Engine::Engine(Files::ConfigurationManager& configurationManager) - : mOgre (0) + : mEncoding(ToUTF8::WINDOWS_1252) + , mEncoder(NULL) + , mOgre (0) , mVerboseScripts (false) , mSkipMenu (false) , mUseSound (true) , mCompileAll (false) , mCompileAllDialogue (false) , mWarningsMode (1) - , mScriptContext (0) - , mFSStrict (false) , mScriptConsoleMode (false) - , mCfgMgr(configurationManager) - , mEncoding(ToUTF8::WINDOWS_1252) - , mEncoder(NULL) , mActivationDistanceOverride(-1) , mGrab(true) - , mScriptBlacklistUse (true) , mExportFonts(false) + , mScriptContext (0) + , mFSStrict (false) + , mScriptBlacklistUse (true) , mNewGame (false) + , mCfgMgr(configurationManager) { OEngine::Misc::Rng::init(); std::srand ( static_cast(std::time(NULL)) ); diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index eb458be500..1f24b58d82 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -77,8 +77,6 @@ namespace MWGui , mMagicka(NULL) , mStamina(NULL) , mDrowning(NULL) - , mDrowningFrame(NULL) - , mDrowningFlash(NULL) , mWeapImage(NULL) , mSpellImage(NULL) , mWeapStatus(NULL) @@ -87,6 +85,9 @@ namespace MWGui , mMinimap(NULL) , mCompass(NULL) , mCrosshair(NULL) + , mCellNameBox(NULL) + , mDrowningFrame(NULL) + , mDrowningFlash(NULL) , mFpsBox(NULL) , mFpsCounter(NULL) , mTriangleCounter(NULL) @@ -94,19 +95,18 @@ namespace MWGui , mHealthManaStaminaBaseLeft(0) , mWeapBoxBaseLeft(0) , mSpellBoxBaseLeft(0) - , mEffectBoxBaseRight(0) , mMinimapBoxBaseRight(0) + , mEffectBoxBaseRight(0) , mDragAndDrop(dragAndDrop) , mCellNameTimer(0.0f) - , mCellNameBox(NULL) + , mWeaponSpellTimer(0.f) , mMapVisible(true) , mWeaponVisible(true) , mSpellVisible(true) , mWorldMouseOver(false) - , mEnemyHealthTimer(-1) , mEnemyActorId(-1) + , mEnemyHealthTimer(-1) , mIsDrowning(false) - , mWeaponSpellTimer(0.f) , mDrowningFlashTheta(0.f) { mMainWidget->setSize(MyGUI::RenderManager::getInstance().getViewSize()); diff --git a/apps/openmw/mwgui/mainmenu.cpp b/apps/openmw/mwgui/mainmenu.cpp index 6ad4da3bfb..9a737af64c 100644 --- a/apps/openmw/mwgui/mainmenu.cpp +++ b/apps/openmw/mwgui/mainmenu.cpp @@ -31,11 +31,11 @@ namespace MWGui MainMenu::MainMenu(int w, int h) : OEngine::GUI::Layout("openmw_mainmenu.layout") - , mButtonBox(0), mWidth (w), mHeight (h) - , mSaveGameDialog(NULL) + , mWidth (w), mHeight (h), mButtonBox(0) , mBackground(NULL) , mVideoBackground(NULL) , mVideo(NULL) + , mSaveGameDialog(NULL) { getWidget(mVersionText, "VersionText"); std::stringstream sstream; diff --git a/apps/openmw/mwgui/spellicons.hpp b/apps/openmw/mwgui/spellicons.hpp index 5099fc4d63..26761f2fc8 100644 --- a/apps/openmw/mwgui/spellicons.hpp +++ b/apps/openmw/mwgui/spellicons.hpp @@ -24,10 +24,10 @@ namespace MWGui struct MagicEffectInfo { MagicEffectInfo() - : mPermanent(false) - , mMagnitude(0) + : mMagnitude(0) , mRemainingTime(0.f) , mTotalTime(0.f) + , mPermanent(false) {} std::string mSource; // display name for effect source (e.g. potion name) MWMechanics::EffectKey mKey; diff --git a/apps/openmw/mwgui/spellmodel.hpp b/apps/openmw/mwgui/spellmodel.hpp index 7859c8a7b6..21fbc9a6e2 100644 --- a/apps/openmw/mwgui/spellmodel.hpp +++ b/apps/openmw/mwgui/spellmodel.hpp @@ -24,9 +24,9 @@ namespace MWGui bool mActive; // (Items only) is the item equipped? Spell() - : mSelected(false) + : mType(Type_Spell) + , mSelected(false) , mActive(false) - , mType(Type_Spell) { } }; diff --git a/apps/openmw/mwgui/spellview.cpp b/apps/openmw/mwgui/spellview.cpp index a7c1d781bd..6d86b4a23a 100644 --- a/apps/openmw/mwgui/spellview.cpp +++ b/apps/openmw/mwgui/spellview.cpp @@ -21,9 +21,9 @@ namespace MWGui } SpellView::SpellView() - : mShowCostColumn(true) + : mScrollView(NULL) + , mShowCostColumn(true) , mHighlightSelected(true) - , mScrollView(NULL) { } diff --git a/apps/openmw/mwgui/tooltips.hpp b/apps/openmw/mwgui/tooltips.hpp index 71b4a560f5..c50d47ef57 100644 --- a/apps/openmw/mwgui/tooltips.hpp +++ b/apps/openmw/mwgui/tooltips.hpp @@ -20,10 +20,10 @@ namespace MWGui { public: ToolTipInfo() - : isPotion(false) - , imageSize(32) - , wordWrap(true) + : imageSize(32) , remainingEnchantCharge(-1) + , isPotion(false) + , wordWrap(true) {} std::string caption; diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index 42491a5e87..aecfce98d0 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -54,10 +54,10 @@ namespace MWGui TradeWindow::TradeWindow() : WindowBase("openmw_trade_window.layout") - , mCurrentBalance(0) - , mItemToSell(-1) - , mTradeModel(NULL) , mSortModel(NULL) + , mTradeModel(NULL) + , mItemToSell(-1) + , mCurrentBalance(0) , mCurrentMerchantOffer(0) { getWidget(mFilterAll, "AllButton"); diff --git a/apps/openmw/mwgui/widgets.hpp b/apps/openmw/mwgui/widgets.hpp index 09a3c11acf..6d9c0a580c 100644 --- a/apps/openmw/mwgui/widgets.hpp +++ b/apps/openmw/mwgui/widgets.hpp @@ -36,17 +36,17 @@ namespace MWGui struct SpellEffectParams { SpellEffectParams() - : mMagnMin(-1) + : mNoTarget(false) + , mIsConstant(false) + , mKnown(true) + , mEffectID(-1) + , mSkill(-1) + , mAttribute(-1) + , mMagnMin(-1) , mMagnMax(-1) , mRange(-1) , mDuration(-1) - , mSkill(-1) , mArea(0) - , mAttribute(-1) - , mEffectID(-1) - , mNoTarget(false) - , mIsConstant(false) - , mKnown(true) { } diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 279c2f22ea..015af00432 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -102,6 +102,7 @@ namespace MWGui const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, ToUTF8::FromType encoding, bool exportFonts, const std::map& fallbackMap) : mConsoleOnlyScripts(consoleOnlyScripts) + , mCurrentModals() , mGuiManager(NULL) , mRendering(ogre) , mHud(NULL) @@ -135,8 +136,8 @@ namespace MWGui , mTrainingWindow(NULL) , mMerchantRepair(NULL) , mSoulgemDialog(NULL) - , mRecharge(NULL) , mRepair(NULL) + , mRecharge(NULL) , mCompanionWindow(NULL) , mVideoBackground(NULL) , mVideoWidget(NULL) @@ -159,8 +160,8 @@ namespace MWGui , mPlayerName() , mPlayerRaceId() , mPlayerAttributes() - , mPlayerMinorSkills() , mPlayerMajorSkills() + , mPlayerMinorSkills() , mPlayerSkillValues() , mGui(NULL) , mGuiModes() @@ -173,7 +174,6 @@ namespace MWGui , mFPS(0.0f) , mTriangleCount(0) , mBatchCount(0) - , mCurrentModals() , mFallbackMap(fallbackMap) { // Set up the GUI system diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 88d891a028..2e82faa6dc 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -102,32 +102,32 @@ namespace MWInput OMW::Engine& engine, const std::string& userFile, bool userFileExists, const std::string& controllerBindingsFile, bool grab) - : mOgre(ogre) + : mJoystickLastUsed(false) + , mOgre(ogre) , mPlayer(NULL) , mEngine(engine) - , mMouseLookEnabled(false) - , mMouseX(ogre.getWindow()->getWidth ()/2.f) - , mMouseY(ogre.getWindow()->getHeight ()/2.f) - , mMouseWheel(0) - , mDragDrop(false) - , mGuiCursorEnabled(true) , mUserFile(userFile) - , mUserFileExists(userFileExists) + , mDragDrop(false) + , mGrabCursor (Settings::Manager::getBool("grab cursor", "Input")) , mInvertY (Settings::Manager::getBool("invert y axis", "Input")) + , mControlsDisabled(false) , mCameraSensitivity (Settings::Manager::getFloat("camera sensitivity", "Input")) , mUISensitivity (Settings::Manager::getFloat("ui sensitivity", "Input")) , mCameraYMultiplier (Settings::Manager::getFloat("camera y multiplier", "Input")) - , mGrabCursor (Settings::Manager::getBool("grab cursor", "Input")) , mPreviewPOVDelay(0.f) , mTimeIdle(0.f) + , mMouseLookEnabled(false) + , mGuiCursorEnabled(true) + , mDetectingKeyboard(false) , mOverencumberedMessageDelay(0.f) + , mMouseX(ogre.getWindow()->getWidth ()/2.f) + , mMouseY(ogre.getWindow()->getHeight ()/2.f) + , mMouseWheel(0) + , mUserFileExists(userFileExists) , mAlwaysRunActive(Settings::Manager::getBool("always run", "Input")) , mSneakToggles(Settings::Manager::getBool("toggle sneak", "Input")) , mSneaking(false) , mAttemptJump(false) - , mControlsDisabled(false) - , mJoystickLastUsed(false) - , mDetectingKeyboard(false) , mFakeDeviceID(1) { diff --git a/apps/openmw/mwmechanics/aicombataction.hpp b/apps/openmw/mwmechanics/aicombataction.hpp index 1c7451c32b..a4a398d05f 100644 --- a/apps/openmw/mwmechanics/aicombataction.hpp +++ b/apps/openmw/mwmechanics/aicombataction.hpp @@ -66,7 +66,7 @@ namespace MWMechanics public: /// \a weapon may be empty for hand-to-hand combat ActionWeapon(const MWWorld::Ptr& weapon, const MWWorld::Ptr& ammo = MWWorld::Ptr()) - : mWeapon(weapon), mAmmunition(ammo) {} + : mAmmunition(ammo), mWeapon(weapon) {} /// Equips the given weapon. virtual void prepare(const MWWorld::Ptr& actor); virtual void getCombatRange (float& rangeAttack, float& rangeFollow); diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 871561bdcf..6dcd92b154 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -65,6 +65,7 @@ void Animation::EffectAnimationTime::setValue(Ogre::Real) Animation::Animation(const MWWorld::Ptr &ptr, Ogre::SceneNode *node) : mPtr(ptr) + , mGlowLight(NULL) , mInsert(node) , mSkelBase(NULL) , mAccumRoot(NULL) @@ -72,7 +73,6 @@ Animation::Animation(const MWWorld::Ptr &ptr, Ogre::SceneNode *node) , mNonAccumCtrl(NULL) , mAccumulate(0.0f) , mNullAnimationTimePtr(OGRE_NEW NullAnimationTime) - , mGlowLight(NULL) { for(size_t i = 0;i < sNumGroups;i++) mAnimationTimePtr[i].bind(OGRE_NEW AnimationTime(this)); diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index 8071dd5fda..7d61e3b6c1 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -25,7 +25,12 @@ namespace MWRender CharacterPreview::CharacterPreview(MWWorld::Ptr character, int sizeX, int sizeY, const std::string& name, Ogre::Vector3 position, Ogre::Vector3 lookAt) - : mSceneMgr (0) + : mRecover(false) + , mRenderTarget(NULL) + , mViewport(NULL) + , mCamera(NULL) + , mSceneMgr (0) + , mNode(NULL) , mPosition(position) , mLookAt(lookAt) , mCharacter(character) @@ -33,11 +38,6 @@ namespace MWRender , mName(name) , mSizeX(sizeX) , mSizeY(sizeY) - , mRenderTarget(NULL) - , mViewport(NULL) - , mCamera(NULL) - , mNode(NULL) - , mRecover(false) { mCharacter.mCell = NULL; } @@ -161,9 +161,9 @@ namespace MWRender InventoryPreview::InventoryPreview(MWWorld::Ptr character) : CharacterPreview(character, 512, 1024, "CharacterPreview", Ogre::Vector3(0, 71, -700), Ogre::Vector3(0,71,0)) - , mSelectionBuffer(NULL) , mSizeX(0) , mSizeY(0) + , mSelectionBuffer(NULL) { } diff --git a/apps/openmw/mwrender/debugging.cpp b/apps/openmw/mwrender/debugging.cpp index 79eeff2d04..49e65490d5 100644 --- a/apps/openmw/mwrender/debugging.cpp +++ b/apps/openmw/mwrender/debugging.cpp @@ -155,10 +155,10 @@ ManualObject *Debugging::createPathgridPoints(const ESM::Pathgrid *pathgrid) } Debugging::Debugging(SceneNode *root, OEngine::Physic::PhysicEngine *engine) : - mRootNode(root), mEngine(engine), - mSceneMgr(root->getCreator()), + mEngine(engine), mSceneMgr(root->getCreator()), mPathgridEnabled(false), - mInteriorPathgridNode(NULL), mPathGridRoot(NULL), + mRootNode(root), + mPathGridRoot(NULL), mInteriorPathgridNode(NULL), mGridMatsCreated(false) { ResourceGroupManager::getSingleton().createResourceGroup(DEBUGGING_GROUP); diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index 0299dc493c..b692226642 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -25,9 +25,9 @@ using namespace MWRender; using namespace Ogre; LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWRender::RenderingManager* rendering) - : mInterior(false) + : mMapResolution(Settings::Manager::getInt("local map resolution", "Map")) , mAngle(0.f) - , mMapResolution(Settings::Manager::getInt("local map resolution", "Map")) + , mInterior(false) { mRendering = rend; mRenderingManager = rendering; diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index a724644a70..6a6d52e262 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -91,7 +91,7 @@ namespace MWRender { HeadAnimationTime::HeadAnimationTime(MWWorld::Ptr reference) - : mReference(reference), mTalkStart(0), mTalkStop(0), mBlinkStart(0), mBlinkStop(0), mValue(0), mEnabled(true) + : mReference(reference), mTalkStart(0), mTalkStop(0), mBlinkStart(0), mBlinkStop(0), mEnabled(true), mValue(0) { resetBlinkTimer(); } @@ -203,17 +203,17 @@ NpcAnimation::~NpcAnimation() NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, int visibilityFlags, bool disableListener, bool disableSounds, ViewMode viewMode) : Animation(ptr, node), - mVisibilityFlags(visibilityFlags), mListenerDisabled(disableListener), mViewMode(viewMode), mShowWeapons(false), mShowCarriedLeft(true), + mNpcType(Type_Normal), + mVisibilityFlags(visibilityFlags), mFirstPersonOffset(0.f, 0.f, 0.f), mAlpha(1.f), - mNpcType(Type_Normal), mSoundsDisabled(disableSounds), - mHeadPitch(0.f), - mHeadYaw(0.f) + mHeadYaw(0.f), + mHeadPitch(0.f) { mNpc = mPtr.get()->mBase; diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 8fb1ee53c5..f00ebb3039 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -56,14 +56,14 @@ namespace MWRender { RenderingManager::RenderingManager(OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine, MWWorld::Fallback* fallback) - : mRendering(_rend) + : mSunEnabled(0) , mFallback(fallback) + , mTerrain(NULL) + , mRendering(_rend) + , mEffectManager(NULL) , mPlayerAnimation(NULL) , mAmbientMode(0) - , mSunEnabled(0) , mPhysicsEngine(engine) - , mTerrain(NULL) - , mEffectManager(NULL) , mRenderWorld(true) { mActors = new MWRender::Actors(mRendering, this); diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index d591cca2ea..fd439050c5 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -247,9 +247,13 @@ unsigned int Moon::getPhaseInt() const } SkyManager::SkyManager(Ogre::SceneNode *root, Ogre::Camera *pCamera) - : mHour(0.0f) + : mCreated(false) + , mMoonRed(false) + , mIsStorm(false) + , mHour(0.0f) , mDay(0) , mMonth(0) + , mCloudAnimationTimer(0.f) , mSun(NULL) , mSunGlare(NULL) , mMasser(NULL) @@ -260,6 +264,9 @@ SkyManager::SkyManager(Ogre::SceneNode *root, Ogre::Camera *pCamera) , mAtmosphereDay(NULL) , mAtmosphereNight(NULL) , mCloudNode(NULL) + , mParticleNode(NULL) + , mRainTimer(0) + , mStormDirection(0,-1,0) , mClouds() , mNextClouds() , mCloudBlendFactor(0.0f) @@ -268,22 +275,15 @@ SkyManager::SkyManager(Ogre::SceneNode *root, Ogre::Camera *pCamera) , mStarsOpacity(0.0f) , mLightning(NULL) , mRemainingTransitionTime(0.0f) - , mGlareFade(0.0f) , mGlare(0.0f) + , mGlareFade(0.0f) + , mRainEnabled(false) + , mRainSpeed(0) + , mRainFrequency(1) , mEnabled(true) , mSunEnabled(true) , mMasserEnabled(true) , mSecundaEnabled(true) - , mCreated(false) - , mCloudAnimationTimer(0.f) - , mMoonRed(false) - , mParticleNode(NULL) - , mRainEnabled(false) - , mRainTimer(0) - , mRainSpeed(0) - , mRainFrequency(1) - , mStormDirection(0,-1,0) - , mIsStorm(false) { mSceneMgr = root->getCreator(); mRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index 775950431e..53d54cdc92 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -46,10 +46,10 @@ namespace MWRender { { public: Reflection(Ogre::SceneManager* sceneManager) - : mSceneMgr(sceneManager) - , mIsUnderwater(false) - , mCamera(NULL) + : mCamera(NULL) , mParentCamera(NULL) + , mSceneMgr(sceneManager) + , mIsUnderwater(false) {} virtual ~Reflection() {} diff --git a/apps/wizard/mainwizard.cpp b/apps/wizard/mainwizard.cpp index a61daa5a4c..7538511fe9 100644 --- a/apps/wizard/mainwizard.cpp +++ b/apps/wizard/mainwizard.cpp @@ -25,10 +25,10 @@ using namespace Process; Wizard::MainWizard::MainWizard(QWidget *parent) : - mGameSettings(mCfgMgr), QWizard(parent), + mInstallations(), mError(false), - mInstallations() + mGameSettings(mCfgMgr) { #ifndef Q_OS_MAC setWizardStyle(QWizard::ModernStyle); diff --git a/components/esm/esmreader.cpp b/components/esm/esmreader.cpp index bbe475ff74..2804f89d41 100644 --- a/components/esm/esmreader.cpp +++ b/components/esm/esmreader.cpp @@ -21,9 +21,9 @@ ESM_Context ESMReader::getContext() } ESMReader::ESMReader() - : mBuffer(50*1024) + : mIdx(0) , mRecordFlags(0) - , mIdx(0) + , mBuffer(50*1024) , mGlobalReaderList(NULL) , mEncoder(NULL) { diff --git a/components/esm/esmwriter.cpp b/components/esm/esmwriter.cpp index 14951608d2..c64678e702 100644 --- a/components/esm/esmwriter.cpp +++ b/components/esm/esmwriter.cpp @@ -9,10 +9,10 @@ namespace ESM { ESMWriter::ESMWriter() - : mEncoder (0) + : mStream(NULL) + , mEncoder (0) , mRecordCount (0) , mCounting (true) - , mStream(NULL) {} unsigned int ESMWriter::getVersion() const diff --git a/components/esm/loadcell.hpp b/components/esm/loadcell.hpp index b78d4075a7..1aef97d9f5 100644 --- a/components/esm/loadcell.hpp +++ b/components/esm/loadcell.hpp @@ -78,9 +78,9 @@ struct Cell float mFogDensity; }; - Cell() : mWater(0), - mName(""), + Cell() : mName(""), mRegion(""), + mWater(0), mWaterInt(false), mMapColor(0), mRefNumCounter(0) diff --git a/components/esm/loadland.cpp b/components/esm/loadland.cpp index b1c01fcba6..b0897ec67d 100644 --- a/components/esm/loadland.cpp +++ b/components/esm/loadland.cpp @@ -67,11 +67,11 @@ Land::Land() : mFlags(0) , mX(0) , mY(0) + , mPlugin(0) , mEsm(NULL) , mDataTypes(0) , mDataLoaded(false) , mLandData(NULL) - , mPlugin(0) { } diff --git a/components/files/fixedpath.hpp b/components/files/fixedpath.hpp index 9fb36d9845..5e0ea6c867 100644 --- a/components/files/fixedpath.hpp +++ b/components/files/fixedpath.hpp @@ -57,8 +57,8 @@ struct FixedPath , mGlobalConfigPath(mPath.getGlobalConfigPath()) , mLocalPath(mPath.getLocalPath()) , mGlobalDataPath(mPath.getGlobalDataPath()) - , mInstallPath(mPath.getInstallPath()) , mCachePath(mPath.getCachePath()) + , mInstallPath(mPath.getInstallPath()) { } diff --git a/components/nif/nifstream.hpp b/components/nif/nifstream.hpp index 6c5e83eebd..aee16f2804 100644 --- a/components/nif/nifstream.hpp +++ b/components/nif/nifstream.hpp @@ -35,7 +35,7 @@ public: NIFFile * const file; - NIFStream (NIFFile * file, Ogre::DataStreamPtr inp): file (file), inp (inp) {} + NIFStream (NIFFile * file, Ogre::DataStreamPtr inp): inp (inp), file (file) {} void skip(size_t size) { inp->skip(size); } diff --git a/components/nifbullet/bulletnifloader.hpp b/components/nifbullet/bulletnifloader.hpp index 0d81d84b6b..f4126b7a73 100644 --- a/components/nifbullet/bulletnifloader.hpp +++ b/components/nifbullet/bulletnifloader.hpp @@ -69,8 +69,8 @@ class ManualBulletShapeLoader : public OEngine::Physic::BulletShapeLoader public: ManualBulletShapeLoader(bool showMarkers=false) : mShape(NULL) - , mStaticMesh(NULL) , mCompoundShape(NULL) + , mStaticMesh(NULL) , mBoundingBox(NULL) , mShowMarkers(showMarkers) { diff --git a/components/nifogre/ogrenifloader.hpp b/components/nifogre/ogrenifloader.hpp index c135326448..b583429dd1 100644 --- a/components/nifogre/ogrenifloader.hpp +++ b/components/nifogre/ogrenifloader.hpp @@ -75,7 +75,7 @@ struct ObjectScene { std::vector > mControllers; - ObjectScene(Ogre::SceneManager* sceneMgr) : mSkelBase(0), mMaxControllerLength(0), mSceneMgr(sceneMgr) + ObjectScene(Ogre::SceneManager* sceneMgr) : mSkelBase(0), mSceneMgr(sceneMgr), mMaxControllerLength(0) { } ~ObjectScene(); diff --git a/components/terrain/defaultworld.cpp b/components/terrain/defaultworld.cpp index c6f0f7136c..7bc73ddda8 100644 --- a/components/terrain/defaultworld.cpp +++ b/components/terrain/defaultworld.cpp @@ -78,15 +78,15 @@ namespace Terrain DefaultWorld::DefaultWorld(Ogre::SceneManager* sceneMgr, Storage* storage, int visibilityFlags, bool shaders, Alignment align, float minBatchSize, float maxBatchSize) : World(sceneMgr, storage, visibilityFlags, shaders, align) + , mWorkQueueChannel(0) + , mVisible(true) + , mChunksLoading(0) + , mMinX(0) + , mMaxX(0) + , mMinY(0) + , mMaxY(0) , mMinBatchSize(minBatchSize) , mMaxBatchSize(maxBatchSize) - , mVisible(true) - , mMaxX(0) - , mMinX(0) - , mMaxY(0) - , mMinY(0) - , mChunksLoading(0) - , mWorkQueueChannel(0) , mLayerLoadPending(true) { #if TERRAIN_USE_SHADER == 0 diff --git a/components/terrain/quadtreenode.cpp b/components/terrain/quadtreenode.cpp index 6a99642132..89e5e34a36 100644 --- a/components/terrain/quadtreenode.cpp +++ b/components/terrain/quadtreenode.cpp @@ -133,6 +133,7 @@ namespace QuadTreeNode::QuadTreeNode(DefaultWorld* terrain, ChildDirection dir, float size, const Ogre::Vector2 ¢er, QuadTreeNode* parent) : mMaterialGenerator(NULL) + , mLoadState(LS_Unloaded) , mIsDummy(false) , mSize(size) , mLodLevel(Log2(static_cast(mSize))) @@ -142,9 +143,8 @@ QuadTreeNode::QuadTreeNode(DefaultWorld* terrain, ChildDirection dir, float size , mCenter(center) , mSceneNode(NULL) , mParent(parent) - , mTerrain(terrain) , mChunk(NULL) - , mLoadState(LS_Unloaded) + , mTerrain(terrain) { mBounds.setNull(); for (int i=0; i<4; ++i) diff --git a/components/terrain/world.cpp b/components/terrain/world.cpp index 5cc2647c67..3baaaed44e 100644 --- a/components/terrain/world.cpp +++ b/components/terrain/world.cpp @@ -30,14 +30,14 @@ namespace Terrain World::World(Ogre::SceneManager* sceneMgr, Storage* storage, int visibilityFlags, bool shaders, Alignment align) - : mStorage(storage) - , mSceneMgr(sceneMgr) - , mVisibilityFlags(visibilityFlags) - , mShaders(shaders) - , mAlign(align) - , mCache(storage->getCellVertices()) + : mShaders(shaders) , mShadows(false) , mSplitShadows(false) + , mAlign(align) + , mStorage(storage) + , mVisibilityFlags(visibilityFlags) + , mSceneMgr(sceneMgr) + , mCache(storage->getCellVertices()) { } diff --git a/components/widgets/list.cpp b/components/widgets/list.cpp index 8517a0303e..5a79de3d1a 100644 --- a/components/widgets/list.cpp +++ b/components/widgets/list.cpp @@ -9,8 +9,8 @@ namespace Gui { MWList::MWList() : - mClient(0) - , mScrollView(0) + mScrollView(0) + ,mClient(0) , mItemHeight(0) { } diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 013ef1003e..15be7665a8 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -74,13 +74,11 @@ namespace Physic { PhysicActor::PhysicActor(const std::string &name, const std::string &mesh, PhysicEngine *engine, const Ogre::Vector3 &position, const Ogre::Quaternion &rotation, float scale) - : mName(name), mEngine(engine), mMesh(mesh) - , mBody(0), mOnGround(false), mInternalCollisionMode(true) + : mCanWaterWalk(false), mWalkingOnWater(false) + , mBody(0), mScale(scale), mForce(0.0f), mOnGround(false) + , mInternalCollisionMode(true) , mExternalCollisionMode(true) - , mForce(0.0f) - , mScale(scale) - , mWalkingOnWater(false) - , mCanWaterWalk(false) + , mMesh(mesh), mName(name), mEngine(engine) { if (!NifBullet::getBoundingBox(mMesh, mHalfExtents, mMeshTranslation, mMeshOrientation)) { @@ -239,8 +237,8 @@ namespace Physic PhysicEngine::PhysicEngine(BulletShapeLoader* shapeLoader) : - mDebugActive(0) - , mSceneMgr(NULL) + mSceneMgr(NULL) + , mDebugActive(0) { // Set up the collision configuration and dispatcher collisionConfiguration = new btDefaultCollisionConfiguration(); diff --git a/libs/openengine/gui/manager.cpp b/libs/openengine/gui/manager.cpp index 3496478929..5fa284c007 100644 --- a/libs/openengine/gui/manager.cpp +++ b/libs/openengine/gui/manager.cpp @@ -99,8 +99,8 @@ public: mManualRender(false), mCountBatch(0), mVertexProgramNoTexture(NULL), - mFragmentProgramNoTexture(NULL), mVertexProgramOneTexture(NULL), + mFragmentProgramNoTexture(NULL), mFragmentProgramOneTexture(NULL) { mTextureAddressMode.u = Ogre::TextureUnitState::TAM_CLAMP; From 7f2bd01f79749d05d18e563c013153376338118e Mon Sep 17 00:00:00 2001 From: cc9cii Date: Wed, 29 Apr 2015 12:08:11 +1000 Subject: [PATCH 178/185] Handle plugins that has 0x00 for levelled list types, for example Ravenloft v5.02d, to use 0x01. --- apps/opencs/model/world/refidadapterimp.hpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 41d8c65d56..e385543838 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -2,6 +2,7 @@ #define CSM_WOLRD_REFIDADAPTERIMP_H #include +#include #include @@ -1895,6 +1896,20 @@ namespace CSMWorld { return QString("All Levels"); } + else if (mType == CSMWorld::UniversalId::Type_CreatureLevelledList && + record.get().mFlags == 0x00) + { + std::cerr << "Unknown creature leveled list type: " << record.get().mFlags + << ", Using \"All Levels\""<< std::endl; + return QString("All Levels"); + } + else if (mType == CSMWorld::UniversalId::Type_ItemLevelledList && + record.get().mFlags == 0x00) + { + std::cerr << "Unknown item leveled list type: " << record.get().mFlags + << ", Using \"Each\""<< std::endl; + return QString("Each"); + } else throw std::runtime_error("unknown leveled list type"); } From 607a16eb01387aad3239d13378f9a7b294cd840a Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 29 Apr 2015 11:36:56 +0200 Subject: [PATCH 179/185] removed leftover ignoreRefNum argument --- components/esm/cellref.cpp | 9 ++++----- components/esm/cellref.hpp | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/components/esm/cellref.cpp b/components/esm/cellref.cpp index ef33f495f1..c3b889df59 100644 --- a/components/esm/cellref.cpp +++ b/components/esm/cellref.cpp @@ -25,13 +25,13 @@ void ESM::RefNum::save (ESMWriter &esm, bool wide, const std::string& tag) const } -void ESM::CellRef::load (ESMReader& esm, bool wideRefNum, bool ignoreRefNum) +void ESM::CellRef::load (ESMReader& esm, bool wideRefNum) { - loadId(esm, wideRefNum, ignoreRefNum); + loadId(esm, wideRefNum); loadData(esm); } -void ESM::CellRef::loadId (ESMReader& esm, bool wideRefNum, bool ignoreRefNum) +void ESM::CellRef::loadId (ESMReader& esm, bool wideRefNum) { // According to Hrnchamd, this does not belong to the actual ref. Instead, it is a marker indicating that // the following refs are part of a "temp refs" section. A temp ref is not being tracked by the moved references system. @@ -40,8 +40,7 @@ void ESM::CellRef::loadId (ESMReader& esm, bool wideRefNum, bool ignoreRefNum) if (esm.isNextSub ("NAM0")) esm.skipHSub(); - if (!ignoreRefNum) - mRefNum.load (esm, wideRefNum); + mRefNum.load (esm, wideRefNum); mRefID = esm.getHNString ("NAME"); } diff --git a/components/esm/cellref.hpp b/components/esm/cellref.hpp index 0fb449e161..e9959611b3 100644 --- a/components/esm/cellref.hpp +++ b/components/esm/cellref.hpp @@ -100,9 +100,9 @@ namespace ESM Position mPos; /// Calls loadId and loadData - void load (ESMReader& esm, bool wideRefNum = false, bool ignoreRefNum = false); + void load (ESMReader& esm, bool wideRefNum = false); - void loadId (ESMReader& esm, bool wideRefNum = false, bool ignoreRefNum = false); + void loadId (ESMReader& esm, bool wideRefNum = false); /// Implicitly called by load void loadData (ESMReader& esm); From 8e49ccc2f4f7c6a510f7416226623ea0313e3d73 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Wed, 29 Apr 2015 20:24:17 +1000 Subject: [PATCH 180/185] Added user setting options. --- apps/opencs/model/settings/usersettings.cpp | 6 ++- apps/opencs/view/world/scriptedit.cpp | 50 +++++++++++++++------ apps/opencs/view/world/scriptedit.hpp | 5 ++- apps/opencs/view/world/scriptsubview.cpp | 45 +++++++++++++++++-- apps/opencs/view/world/scriptsubview.hpp | 9 ++++ 5 files changed, 96 insertions(+), 19 deletions(-) diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index 6e240c9987..d9db95c710 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -143,6 +143,10 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() minWidth->setDefaultValue (325); minWidth->setRange (50, 10000); minWidth->setToolTip ("Minimum width of subviews."); + + Setting *monoFont = createSetting (Type_CheckBox, "mono-font", "Use monospace font"); + monoFont->setDefaultValue ("true"); + monoFont->setToolTip ("Whether to use monospaced fonts on script edit subview."); } declareSection ("records", "Records"); @@ -225,7 +229,7 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() Setting *autoDelete = createSetting (Type_CheckBox, "auto-delete", "Delete row from result table after a successful replace"); autoDelete->setDefaultValue ("true"); } - + { /****************************************************************** * There are three types of values: diff --git a/apps/opencs/view/world/scriptedit.cpp b/apps/opencs/view/world/scriptedit.cpp index 991e58ae77..9e0a7e95ad 100644 --- a/apps/opencs/view/world/scriptedit.cpp +++ b/apps/opencs/view/world/scriptedit.cpp @@ -12,6 +12,7 @@ #include "../../model/world/universalid.hpp" #include "../../model/world/tablemimedata.hpp" +#include "../../model/settings/usersettings.hpp" CSVWorld::ScriptEdit::ChangeLock::ChangeLock (ScriptEdit& edit) : mEdit (edit) @@ -30,7 +31,9 @@ CSVWorld::ScriptEdit::ScriptEdit (const CSMDoc::Document& document, ScriptHighli : QPlainTextEdit (parent), mDocument (document), mWhiteListQoutes("^[a-z|_]{1}[a-z|0-9|_]{0,}$", Qt::CaseInsensitive), - mChangeLocked (0) + mChangeLocked (0), + mLineNumberArea(0), + mShowLineNum(false) { // setAcceptRichText (false); setLineWrapMode (QPlainTextEdit::NoWrap); @@ -75,19 +78,35 @@ CSVWorld::ScriptEdit::ScriptEdit (const CSMDoc::Document& document, ScriptHighli mUpdateTimer.setSingleShot (true); - // FIXME: make this configurable or provide a font selector dialogue - // FIXME: save QFontInfo somewhere before switching to a new one - QFont font("Monospace"); - font.setStyleHint(QFont::TypeWriter); - setFont(font); + // TODO: provide a font selector dialogue + std::string useMonoFont = + CSMSettings::UserSettings::instance().setting("window/mono-font", "true").toStdString(); + if (useMonoFont == "true") + { + QFont font("Monospace"); + font.setStyleHint(QFont::TypeWriter); + setFont(font); + } - // FIXME: make this configurable - lineNumberArea = new LineNumberArea(this); + mLineNumberArea = new LineNumberArea(this); + updateLineNumberAreaWidth(0); connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int))); connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int))); - updateLineNumberAreaWidth(0); + std::string showStatusBar = + CSMSettings::UserSettings::instance().settingValue("window/show-statusbar").toStdString(); + + showLineNum(showStatusBar == "true"); +} + +void CSVWorld::ScriptEdit::showLineNum(bool show) +{ + if(show!=mShowLineNum) + { + mShowLineNum = show; + updateLineNumberAreaWidth(0); + } } bool CSVWorld::ScriptEdit::isChangeLocked() const @@ -176,6 +195,9 @@ void CSVWorld::ScriptEdit::updateHighlighting() int CSVWorld::ScriptEdit::lineNumberAreaWidth() { + if(!mShowLineNum) + return 0; + int digits = 1; int max = qMax(1, blockCount()); while (max >= 10) @@ -197,9 +219,9 @@ void CSVWorld::ScriptEdit::updateLineNumberAreaWidth(int /* newBlockCount */) void CSVWorld::ScriptEdit::updateLineNumberArea(const QRect &rect, int dy) { if (dy) - lineNumberArea->scroll(0, dy); + mLineNumberArea->scroll(0, dy); else - lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height()); + mLineNumberArea->update(0, rect.y(), mLineNumberArea->width(), rect.height()); if (rect.contains(viewport()->rect())) updateLineNumberAreaWidth(0); @@ -210,12 +232,12 @@ void CSVWorld::ScriptEdit::resizeEvent(QResizeEvent *e) QPlainTextEdit::resizeEvent(e); QRect cr = contentsRect(); - lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height())); + mLineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height())); } void CSVWorld::ScriptEdit::lineNumberAreaPaintEvent(QPaintEvent *event) { - QPainter painter(lineNumberArea); + QPainter painter(mLineNumberArea); QTextBlock block = firstVisibleBlock(); int blockNumber = block.blockNumber(); @@ -255,7 +277,7 @@ void CSVWorld::ScriptEdit::lineNumberAreaPaintEvent(QPaintEvent *event) painter.setPen(Qt::black); } painter.setFont(newFont); - painter.drawText(0, top, lineNumberArea->width(), fontMetrics().height(), + painter.drawText(0, top, mLineNumberArea->width(), fontMetrics().height(), Qt::AlignRight, number); painter.setFont(font); } diff --git a/apps/opencs/view/world/scriptedit.hpp b/apps/opencs/view/world/scriptedit.hpp index 90fe2917e5..3355d40c16 100644 --- a/apps/opencs/view/world/scriptedit.hpp +++ b/apps/opencs/view/world/scriptedit.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "../../model/world/universalid.hpp" @@ -47,7 +48,8 @@ namespace CSVWorld int mChangeLocked; ScriptHighlighter *mHighlighter; QTimer mUpdateTimer; - QWidget *lineNumberArea; + bool mShowLineNum; + LineNumberArea *mLineNumberArea; public: @@ -61,6 +63,7 @@ namespace CSVWorld void lineNumberAreaPaintEvent(QPaintEvent *event); int lineNumberAreaWidth(); + void showLineNum(bool show); protected: diff --git a/apps/opencs/view/world/scriptsubview.cpp b/apps/opencs/view/world/scriptsubview.cpp index ea9dcee8cd..335cb97af3 100644 --- a/apps/opencs/view/world/scriptsubview.cpp +++ b/apps/opencs/view/world/scriptsubview.cpp @@ -1,8 +1,11 @@ - #include "scriptsubview.hpp" #include +#include +#include +#include + #include "../../model/doc/document.hpp" #include "../../model/world/universalid.hpp" #include "../../model/world/data.hpp" @@ -13,9 +16,26 @@ #include "scriptedit.hpp" CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) -: SubView (id), mDocument (document), mColumn (-1) +: SubView (id), mDocument (document), mColumn (-1), mBottom(0), mStatus(0) { - setWidget (mEditor = new ScriptEdit (mDocument, ScriptHighlighter::Mode_General, this)); + QVBoxLayout *layout = new QVBoxLayout; + layout->setContentsMargins (QMargins (0, 0, 0, 0)); + + mBottom = new QWidget(this); + QStackedLayout *bottmLayout = new QStackedLayout(mBottom); + bottmLayout->setContentsMargins (0, 0, 0, 0); + QStatusBar *statusBar = new QStatusBar(mBottom); + mStatus = new QLabel(mBottom); + statusBar->addWidget (mStatus); + bottmLayout->addWidget (statusBar); + mBottom->setLayout (bottmLayout); + + layout->addWidget (mBottom, 0); + layout->insertWidget (0, mEditor = new ScriptEdit (mDocument, ScriptHighlighter::Mode_General, this), 2); + + QWidget *widget = new QWidget; + widget->setLayout (layout); + setWidget (widget); mModel = &dynamic_cast ( *document.getData().getTableModel (CSMWorld::UniversalId::Type_Scripts)); @@ -40,6 +60,25 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc: connect (mModel, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), this, SLOT (rowsAboutToBeRemoved (const QModelIndex&, int, int))); + + updateStatusBar(); + connect(mEditor, SIGNAL(cursorPositionChanged()), this, SLOT(updateStatusBar())); +} + +void CSVWorld::ScriptSubView::setStatusBar (bool show) +{ + mEditor->showLineNum(show); + mBottom->setVisible(show); +} + +void CSVWorld::ScriptSubView::updateStatusBar () +{ + std::ostringstream stream; + + stream << "(" << mEditor->textCursor().blockNumber() + 1 << ", " + << mEditor->textCursor().columnNumber() + 1 << ")"; + + mStatus->setText (QString::fromUtf8 (stream.str().c_str())); } void CSVWorld::ScriptSubView::setEditLock (bool locked) diff --git a/apps/opencs/view/world/scriptsubview.hpp b/apps/opencs/view/world/scriptsubview.hpp index 561476577a..5d85891cf7 100644 --- a/apps/opencs/view/world/scriptsubview.hpp +++ b/apps/opencs/view/world/scriptsubview.hpp @@ -4,6 +4,7 @@ #include "../doc/subview.hpp" class QModelIndex; +class QLabel; namespace CSMDoc { @@ -27,6 +28,8 @@ namespace CSVWorld CSMDoc::Document& mDocument; CSMWorld::IdTable *mModel; int mColumn; + QWidget *mBottom; + QLabel *mStatus; public: @@ -36,6 +39,8 @@ namespace CSVWorld virtual void useHint (const std::string& hint); + virtual void setStatusBar (bool show); + public slots: void textChanged(); @@ -43,6 +48,10 @@ namespace CSVWorld void dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); void rowsAboutToBeRemoved (const QModelIndex& parent, int start, int end); + + private slots: + + void updateStatusBar(); }; } From 7b4a9f1ea1d8b8a43674bc914d99960ef5581356 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Thu, 30 Apr 2015 06:32:03 +1000 Subject: [PATCH 181/185] Moved script editor settings to its own section. --- apps/opencs/model/settings/usersettings.cpp | 16 ++++++++++++---- apps/opencs/view/world/scriptedit.cpp | 4 ++-- apps/opencs/view/world/scriptsubview.cpp | 13 ++++++++++--- apps/opencs/view/world/scriptsubview.hpp | 2 +- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index d9db95c710..9e00b7d1aa 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -143,10 +143,6 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() minWidth->setDefaultValue (325); minWidth->setRange (50, 10000); minWidth->setToolTip ("Minimum width of subviews."); - - Setting *monoFont = createSetting (Type_CheckBox, "mono-font", "Use monospace font"); - monoFont->setDefaultValue ("true"); - monoFont->setToolTip ("Whether to use monospaced fonts on script edit subview."); } declareSection ("records", "Records"); @@ -230,6 +226,18 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() autoDelete->setDefaultValue ("true"); } + declareSection ("script-editor", "Script Editor"); + { + Setting *lineNum = createSetting (Type_CheckBox, "show-linenum", "Show Line Numbers"); + lineNum->setDefaultValue ("true"); + lineNum->setToolTip ("Show line numbers to the left of the script editor window." + "The current row and column numbers of the text cursor are shown at the bottom."); + + Setting *monoFont = createSetting (Type_CheckBox, "mono-font", "Use monospace font"); + monoFont->setDefaultValue ("true"); + monoFont->setToolTip ("Whether to use monospaced fonts on script edit subview."); + } + { /****************************************************************** * There are three types of values: diff --git a/apps/opencs/view/world/scriptedit.cpp b/apps/opencs/view/world/scriptedit.cpp index 9e0a7e95ad..0909c00f9e 100644 --- a/apps/opencs/view/world/scriptedit.cpp +++ b/apps/opencs/view/world/scriptedit.cpp @@ -80,7 +80,7 @@ CSVWorld::ScriptEdit::ScriptEdit (const CSMDoc::Document& document, ScriptHighli // TODO: provide a font selector dialogue std::string useMonoFont = - CSMSettings::UserSettings::instance().setting("window/mono-font", "true").toStdString(); + CSMSettings::UserSettings::instance().setting("script-editor/mono-font", "true").toStdString(); if (useMonoFont == "true") { QFont font("Monospace"); @@ -95,7 +95,7 @@ CSVWorld::ScriptEdit::ScriptEdit (const CSMDoc::Document& document, ScriptHighli connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int))); std::string showStatusBar = - CSMSettings::UserSettings::instance().settingValue("window/show-statusbar").toStdString(); + CSMSettings::UserSettings::instance().settingValue("script-editor/show-linenum").toStdString(); showLineNum(showStatusBar == "true"); } diff --git a/apps/opencs/view/world/scriptsubview.cpp b/apps/opencs/view/world/scriptsubview.cpp index 335cb97af3..c7ddcd82a1 100644 --- a/apps/opencs/view/world/scriptsubview.cpp +++ b/apps/opencs/view/world/scriptsubview.cpp @@ -12,6 +12,7 @@ #include "../../model/world/columnbase.hpp" #include "../../model/world/commands.hpp" #include "../../model/world/idtable.hpp" +#include "../../model/settings/usersettings.hpp" #include "scriptedit.hpp" @@ -65,10 +66,16 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc: connect(mEditor, SIGNAL(cursorPositionChanged()), this, SLOT(updateStatusBar())); } -void CSVWorld::ScriptSubView::setStatusBar (bool show) +void CSVWorld::ScriptSubView::updateUserSetting (const QString& name, const QStringList& value) { - mEditor->showLineNum(show); - mBottom->setVisible(show); + if (name != "script-editor/show-linenum") + return; + + std::string showLinenum = + CSMSettings::UserSettings::instance().settingValue("script-editor/show-linenum").toStdString(); + + mEditor->showLineNum(showLinenum == "true"); + mBottom->setVisible(showLinenum == "true"); } void CSVWorld::ScriptSubView::updateStatusBar () diff --git a/apps/opencs/view/world/scriptsubview.hpp b/apps/opencs/view/world/scriptsubview.hpp index 5d85891cf7..1c6474e542 100644 --- a/apps/opencs/view/world/scriptsubview.hpp +++ b/apps/opencs/view/world/scriptsubview.hpp @@ -39,7 +39,7 @@ namespace CSVWorld virtual void useHint (const std::string& hint); - virtual void setStatusBar (bool show); + virtual void updateUserSetting (const QString& name, const QStringList& value); public slots: From 081f3ed263f5077be9e2853d6e5f1b2ec9e468aa Mon Sep 17 00:00:00 2001 From: cc9cii Date: Fri, 1 May 2015 06:08:04 +1000 Subject: [PATCH 182/185] Make font setting selection immediate. --- apps/opencs/view/world/scriptedit.cpp | 19 +++++++++++++------ apps/opencs/view/world/scriptedit.hpp | 3 +++ apps/opencs/view/world/scriptsubview.cpp | 18 ++++++++++-------- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/apps/opencs/view/world/scriptedit.cpp b/apps/opencs/view/world/scriptedit.cpp index 0909c00f9e..b4f4234f19 100644 --- a/apps/opencs/view/world/scriptedit.cpp +++ b/apps/opencs/view/world/scriptedit.cpp @@ -33,7 +33,9 @@ CSVWorld::ScriptEdit::ScriptEdit (const CSMDoc::Document& document, ScriptHighli mWhiteListQoutes("^[a-z|_]{1}[a-z|0-9|_]{0,}$", Qt::CaseInsensitive), mChangeLocked (0), mLineNumberArea(0), - mShowLineNum(false) + mShowLineNum(false), + mDefaultFont(font()), + mMonoFont(QFont("Monospace")) { // setAcceptRichText (false); setLineWrapMode (QPlainTextEdit::NoWrap); @@ -79,14 +81,11 @@ CSVWorld::ScriptEdit::ScriptEdit (const CSMDoc::Document& document, ScriptHighli mUpdateTimer.setSingleShot (true); // TODO: provide a font selector dialogue + mMonoFont.setStyleHint(QFont::TypeWriter); std::string useMonoFont = CSMSettings::UserSettings::instance().setting("script-editor/mono-font", "true").toStdString(); if (useMonoFont == "true") - { - QFont font("Monospace"); - font.setStyleHint(QFont::TypeWriter); - setFont(font); - } + setFont(mMonoFont); mLineNumberArea = new LineNumberArea(this); updateLineNumberAreaWidth(0); @@ -109,6 +108,14 @@ void CSVWorld::ScriptEdit::showLineNum(bool show) } } +void CSVWorld::ScriptEdit::setMonoFont(bool show) +{ + if(show) + setFont(mMonoFont); + else + setFont(mDefaultFont); +} + bool CSVWorld::ScriptEdit::isChangeLocked() const { return mChangeLocked!=0; diff --git a/apps/opencs/view/world/scriptedit.hpp b/apps/opencs/view/world/scriptedit.hpp index 3355d40c16..a19cee486b 100644 --- a/apps/opencs/view/world/scriptedit.hpp +++ b/apps/opencs/view/world/scriptedit.hpp @@ -50,6 +50,8 @@ namespace CSVWorld QTimer mUpdateTimer; bool mShowLineNum; LineNumberArea *mLineNumberArea; + QFont mDefaultFont; + QFont mMonoFont; public: @@ -64,6 +66,7 @@ namespace CSVWorld void lineNumberAreaPaintEvent(QPaintEvent *event); int lineNumberAreaWidth(); void showLineNum(bool show); + void setMonoFont(bool show); protected: diff --git a/apps/opencs/view/world/scriptsubview.cpp b/apps/opencs/view/world/scriptsubview.cpp index c7ddcd82a1..411eb3660d 100644 --- a/apps/opencs/view/world/scriptsubview.cpp +++ b/apps/opencs/view/world/scriptsubview.cpp @@ -68,14 +68,16 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc: void CSVWorld::ScriptSubView::updateUserSetting (const QString& name, const QStringList& value) { - if (name != "script-editor/show-linenum") - return; - - std::string showLinenum = - CSMSettings::UserSettings::instance().settingValue("script-editor/show-linenum").toStdString(); - - mEditor->showLineNum(showLinenum == "true"); - mBottom->setVisible(showLinenum == "true"); + if (name == "script-editor/show-linenum") + { + std::string showLinenum = value.at(0).toStdString(); + mEditor->showLineNum(showLinenum == "true"); + mBottom->setVisible(showLinenum == "true"); + } + else if (name == "script-editor/mono-font") + { + mEditor->setMonoFont(value.at(0).toStdString() == "true"); + } } void CSVWorld::ScriptSubView::updateStatusBar () From b04aeb6aad5ca7441d3091a85fc871049db0c8e8 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Fri, 1 May 2015 12:14:09 +1000 Subject: [PATCH 183/185] Fixed levelled lists flags - now bit masks represented by tick boxes in the dialogue subview. --- apps/opencs/model/world/columns.cpp | 5 +- apps/opencs/model/world/columns.hpp | 11 +- apps/opencs/model/world/commands.cpp | 7 +- apps/opencs/model/world/refidadapterimp.hpp | 134 +++++++++++--------- apps/opencs/model/world/refidcollection.cpp | 4 +- apps/opencs/view/world/dialoguesubview.cpp | 5 +- 6 files changed, 93 insertions(+), 73 deletions(-) diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 3d735ddcaf..3172e72e4e 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -222,7 +222,6 @@ namespace CSMWorld { ColumnId_HitSound, "Hit Sound" }, { ColumnId_AreaSound, "Area Sound" }, { ColumnId_BoltSound, "Bolt Sound" }, - { ColumnId_OriginalCell, "Original Cell" }, { ColumnId_PathgridPoints, "Points" }, { ColumnId_PathgridIndex, "Index" }, @@ -267,13 +266,15 @@ namespace CSMWorld { ColumnId_LevelledList,"Levelled List" }, { ColumnId_LevelledItemId,"Item ID" }, { ColumnId_LevelledItemLevel,"Level" }, - { ColumnId_LevelledItemType, "Type" }, + { ColumnId_LevelledItemType, "Calculate all levels <= player" }, + { ColumnId_LevelledItemTypeEach, "Select a new item each instance" }, { ColumnId_LevelledItemChanceNone, "Chance None" }, { ColumnId_PowerList, "Powers" }, { ColumnId_SkillImpact, "Skills" }, { ColumnId_InfoList, "Info List" }, + { ColumnId_OriginalCell, "Original Cell" }, { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 0c525fd11f..b87f6c53d0 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -257,14 +257,15 @@ namespace CSMWorld ColumnId_LevelledItemId = 234, ColumnId_LevelledItemLevel = 235, ColumnId_LevelledItemType = 236, - ColumnId_LevelledItemChanceNone = 237, + ColumnId_LevelledItemTypeEach = 237, + ColumnId_LevelledItemChanceNone = 238, - ColumnId_PowerList = 238, - ColumnId_SkillImpact = 239, // impact from magic effects + ColumnId_PowerList = 239, + ColumnId_SkillImpact = 240, // impact from magic effects - ColumnId_InfoList = 240, + ColumnId_InfoList = 241, - ColumnId_OriginalCell = 241, + ColumnId_OriginalCell = 242, // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. diff --git a/apps/opencs/model/world/commands.cpp b/apps/opencs/model/world/commands.cpp index 2329597279..9a0401081b 100644 --- a/apps/opencs/model/world/commands.cpp +++ b/apps/opencs/model/world/commands.cpp @@ -21,9 +21,12 @@ CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelI // Replace proxy with actual model mIndex = proxy->mapToSource (index); mModel = proxy->sourceModel(); - } - setText ("Modify " + mModel->headerData (mIndex.column(), Qt::Horizontal, Qt::DisplayRole).toString()); + setText ("Modify " + dynamic_cast(mModel)->nestedHeaderData ( + mIndex.parent().column(), mIndex.column(), Qt::Horizontal, Qt::DisplayRole).toString()); + } + else + setText ("Modify " + mModel->headerData (mIndex.column(), Qt::Horizontal, Qt::DisplayRole).toString()); } void CSMWorld::ModifyCommand::redo() diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index e385543838..61e8115c0e 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -1830,10 +1830,10 @@ namespace CSMWorld } + // for non-tables template class NestedListLevListRefIdAdapter : public NestedRefIdAdapterBase { - UniversalId::Type mType; // not implemented @@ -1877,45 +1877,27 @@ namespace CSMWorld const Record& record = static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); - switch (subColIndex) + if (mType == UniversalId::Type_CreatureLevelledList) { - case 0: + switch (subColIndex) { - if (mType == CSMWorld::UniversalId::Type_CreatureLevelledList && - record.get().mFlags == 0x01) - { - return QString("All Levels"); - } - else if(mType == CSMWorld::UniversalId::Type_ItemLevelledList && - record.get().mFlags == 0x01) - { - return QString("Each"); - } - else if(mType == CSMWorld::UniversalId::Type_ItemLevelledList && - record.get().mFlags == 0x02) - { - return QString("All Levels"); - } - else if (mType == CSMWorld::UniversalId::Type_CreatureLevelledList && - record.get().mFlags == 0x00) - { - std::cerr << "Unknown creature leveled list type: " << record.get().mFlags - << ", Using \"All Levels\""<< std::endl; - return QString("All Levels"); - } - else if (mType == CSMWorld::UniversalId::Type_ItemLevelledList && - record.get().mFlags == 0x00) - { - std::cerr << "Unknown item leveled list type: " << record.get().mFlags - << ", Using \"Each\""<< std::endl; - return QString("Each"); - } - else - throw std::runtime_error("unknown leveled list type"); + case 0: return QVariant(); // don't allow checkbox editor to be created + case 1: return record.get().mFlags & ESM::CreatureLevList::AllLevels; + case 2: return static_cast (record.get().mChanceNone); + default: + throw std::runtime_error("Trying to access non-existing column in levelled creatues!"); + } + } + else + { + switch (subColIndex) + { + case 0: return record.get().mFlags & ESM::ItemLevList::Each; + case 1: return record.get().mFlags & ESM::ItemLevList::AllLevels; + case 2: return static_cast (record.get().mChanceNone); + default: + throw std::runtime_error("Trying to access non-existing column in levelled items!"); } - case 1: return static_cast (record.get().mChanceNone); - default: - throw std::runtime_error("Trying to access non-existing column in the nested table!"); } } @@ -1926,34 +1908,63 @@ namespace CSMWorld static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); ESXRecordT leveled = record.get(); - switch(subColIndex) + if (mType == UniversalId::Type_CreatureLevelledList) { - case 0: + switch(subColIndex) { - if (mType == CSMWorld::UniversalId::Type_CreatureLevelledList && - value.toString().toStdString() == "All Levels") + case 0: return; // return without saving + case 1: { - leveled.mFlags = 0x01; - break; + if(value.toBool()) + { + leveled.mFlags |= ESM::CreatureLevList::AllLevels; + break; + } + else + { + leveled.mFlags &= ~ESM::CreatureLevList::AllLevels; + break; + } } - else if(mType == CSMWorld::UniversalId::Type_ItemLevelledList && - value.toString().toStdString() == "Each") - { - leveled.mFlags = 0x01; - break; - } - else if(mType == CSMWorld::UniversalId::Type_ItemLevelledList && - value.toString().toStdString() == "All Levels") - { - leveled.mFlags = 0x02; - break; - } - else - return; // return without saving + case 2: leveled.mChanceNone = static_cast(value.toInt()); break; + default: + throw std::runtime_error("Trying to set non-existing column in levelled creatures!"); + } + } + else + { + switch(subColIndex) + { + case 0: + { + if(value.toBool()) + { + leveled.mFlags |= ESM::ItemLevList::Each; + break; + } + else + { + leveled.mFlags &= ~ESM::ItemLevList::Each; + break; + } + } + case 1: + { + if(value.toBool()) + { + leveled.mFlags |= ESM::ItemLevList::AllLevels; + break; + } + else + { + leveled.mFlags &= ~ESM::ItemLevList::AllLevels; + break; + } + } + case 2: leveled.mChanceNone = static_cast(value.toInt()); break; + default: + throw std::runtime_error("Trying to set non-existing column in levelled items!"); } - case 1: leveled.mChanceNone = static_cast(value.toInt()); break; - default: - throw std::runtime_error("Trying to access non-existing column in the nested table!"); } record.setModified (leveled); @@ -1961,7 +1972,7 @@ namespace CSMWorld virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const { - return 2; + return 3; } virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const @@ -1970,6 +1981,7 @@ namespace CSMWorld } }; + // for tables template class NestedLevListRefIdAdapter : public NestedRefIdAdapterBase { diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 4a8f398cd0..1941c505a2 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -514,7 +514,9 @@ CSMWorld::RefIdCollection::RefIdCollection() new NestedListLevListRefIdAdapter (UniversalId::Type_ItemLevelledList))); mNestedAdapters.push_back (std::make_pair(&mColumns.back(), nestedListLevListMap)); mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_LevelledItemType, CSMWorld::ColumnBase::Display_String)); + new RefIdColumn (Columns::ColumnId_LevelledItemTypeEach, CSMWorld::ColumnBase::Display_Boolean)); + mColumns.back().addColumn( + new RefIdColumn (Columns::ColumnId_LevelledItemType, CSMWorld::ColumnBase::Display_Boolean)); mColumns.back().addColumn( new RefIdColumn (Columns::ColumnId_LevelledItemChanceNone, CSMWorld::ColumnBase::Display_Integer)); diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index cf3653c1b2..0d0e82dbf3 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -29,8 +29,8 @@ #include "../../model/world/record.hpp" #include "../../model/world/tablemimedata.hpp" #include "../../model/world/idtree.hpp" -#include "../../model/doc/document.hpp" #include "../../model/world/commands.hpp" +#include "../../model/doc/document.hpp" #include "recordstatusdelegate.hpp" #include "util.hpp" @@ -444,7 +444,8 @@ void CSVWorld::EditWidget::remake(int row) if (mTable->hasChildren(mTable->index(row, i)) && !(flags & CSMWorld::ColumnBase::Flag_Dialogue_List)) { - mNestedModels.push_back(new CSMWorld::NestedTableProxyModel (mTable->index(row, i), display, dynamic_cast(mTable))); + mNestedModels.push_back(new CSMWorld::NestedTableProxyModel ( + mTable->index(row, i), display, dynamic_cast(mTable))); int idColumn = mTable->findColumnIndex (CSMWorld::Columns::ColumnId_Id); int typeColumn = mTable->findColumnIndex (CSMWorld::Columns::ColumnId_RecordType); From d873c2c6032c5091ce3ab8172573c87435b18b10 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 2 May 2015 13:20:42 +0200 Subject: [PATCH 184/185] focus main input widget when bringing up creator bar (Fixes #2514) --- apps/opencs/view/world/creator.hpp | 3 +++ apps/opencs/view/world/genericcreator.cpp | 5 +++++ apps/opencs/view/world/genericcreator.hpp | 3 +++ apps/opencs/view/world/infocreator.cpp | 5 +++++ apps/opencs/view/world/infocreator.hpp | 5 ++++- apps/opencs/view/world/referencecreator.cpp | 5 +++++ apps/opencs/view/world/referencecreator.hpp | 3 +++ apps/opencs/view/world/tablebottombox.cpp | 2 ++ 8 files changed, 30 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/world/creator.hpp b/apps/opencs/view/world/creator.hpp index 7c0422c882..506bdab2c9 100644 --- a/apps/opencs/view/world/creator.hpp +++ b/apps/opencs/view/world/creator.hpp @@ -40,6 +40,9 @@ namespace CSVWorld /// Default implementation: Throw an exception if scope!=Scope_Content. virtual void setScope (unsigned int scope); + /// Focus main input widget + virtual void focus() = 0; + signals: void done(); diff --git a/apps/opencs/view/world/genericcreator.cpp b/apps/opencs/view/world/genericcreator.cpp index b4cf460403..4269679bfd 100644 --- a/apps/opencs/view/world/genericcreator.cpp +++ b/apps/opencs/view/world/genericcreator.cpp @@ -225,6 +225,11 @@ void CSVWorld::GenericCreator::toggleWidgets(bool active) { } +void CSVWorld::GenericCreator::focus() +{ + mId->setFocus(); +} + void CSVWorld::GenericCreator::setScope (unsigned int scope) { mScopes = scope; diff --git a/apps/opencs/view/world/genericcreator.hpp b/apps/opencs/view/world/genericcreator.hpp index 6780050825..1f854c69ed 100644 --- a/apps/opencs/view/world/genericcreator.hpp +++ b/apps/opencs/view/world/genericcreator.hpp @@ -101,6 +101,9 @@ namespace CSVWorld virtual void setScope (unsigned int scope); + /// Focus main input widget + virtual void focus(); + private slots: void textChanged (const QString& text); diff --git a/apps/opencs/view/world/infocreator.cpp b/apps/opencs/view/world/infocreator.cpp index 14034ea7f4..f88b9f0b9a 100644 --- a/apps/opencs/view/world/infocreator.cpp +++ b/apps/opencs/view/world/infocreator.cpp @@ -91,6 +91,11 @@ std::string CSVWorld::InfoCreator::getErrors() const return errors; } +void CSVWorld::InfoCreator::focus() +{ + mTopic->setFocus(); +} + void CSVWorld::InfoCreator::topicChanged() { update(); diff --git a/apps/opencs/view/world/infocreator.hpp b/apps/opencs/view/world/infocreator.hpp index 2296a82973..edc12975cb 100644 --- a/apps/opencs/view/world/infocreator.hpp +++ b/apps/opencs/view/world/infocreator.hpp @@ -35,7 +35,10 @@ namespace CSVWorld virtual std::string getErrors() const; ///< Return formatted error descriptions for the current state of the creator. if an empty /// string is returned, there is no error. - + + /// Focus main input widget + virtual void focus(); + private slots: void topicChanged(); diff --git a/apps/opencs/view/world/referencecreator.cpp b/apps/opencs/view/world/referencecreator.cpp index 1e3cc00d7d..e9bb04ba7e 100644 --- a/apps/opencs/view/world/referencecreator.cpp +++ b/apps/opencs/view/world/referencecreator.cpp @@ -118,6 +118,11 @@ std::string CSVWorld::ReferenceCreator::getErrors() const return errors; } +void CSVWorld::ReferenceCreator::focus() +{ + mCell->setFocus(); +} + void CSVWorld::ReferenceCreator::cellChanged() { update(); diff --git a/apps/opencs/view/world/referencecreator.hpp b/apps/opencs/view/world/referencecreator.hpp index 002a62d879..877307c29e 100644 --- a/apps/opencs/view/world/referencecreator.hpp +++ b/apps/opencs/view/world/referencecreator.hpp @@ -39,6 +39,9 @@ namespace CSVWorld ///< Return formatted error descriptions for the current state of the creator. if an empty /// string is returned, there is no error. + /// Focus main input widget + virtual void focus(); + private slots: void cellChanged(); diff --git a/apps/opencs/view/world/tablebottombox.cpp b/apps/opencs/view/world/tablebottombox.cpp index 239c7410fb..e9d644f61e 100644 --- a/apps/opencs/view/world/tablebottombox.cpp +++ b/apps/opencs/view/world/tablebottombox.cpp @@ -157,6 +157,7 @@ void CSVWorld::TableBottomBox::createRequest() mLayout->setCurrentWidget (mCreator); setVisible (true); mCreating = true; + mCreator->focus(); } void CSVWorld::TableBottomBox::cloneRequest(const std::string& id, @@ -168,4 +169,5 @@ void CSVWorld::TableBottomBox::cloneRequest(const std::string& id, mCreator->toggleWidgets(false); setVisible (true); mCreating = true; + mCreator->focus(); } From 048d7be87c4a1555f27b08f4efa67722bfdcc56d Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 3 May 2015 16:35:10 +0200 Subject: [PATCH 185/185] Adjusted terminology for references/referenceables in OpenMW-CS user-interface (Fixes #2516) --- apps/opencs/model/tools/referencecheck.cpp | 2 +- apps/opencs/model/world/universalid.cpp | 8 ++++---- apps/opencs/view/doc/view.cpp | 4 ++-- apps/opencs/view/render/worldspacewidget.cpp | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/apps/opencs/model/tools/referencecheck.cpp b/apps/opencs/model/tools/referencecheck.cpp index 198c3627f4..be9663e7aa 100644 --- a/apps/opencs/model/tools/referencecheck.cpp +++ b/apps/opencs/model/tools/referencecheck.cpp @@ -28,7 +28,7 @@ void CSMTools::ReferenceCheckStage::perform(int stage, CSMDoc::Messages &message // Check for empty reference id if (cellRef.mRefID.empty()) { - messages.push_back(std::make_pair(id, " is an empty reference")); + messages.push_back(std::make_pair(id, " is an empty instance (not based on an object)")); } else { // Check for non existing referenced object if (mReferencables.searchId(cellRef.mRefID) == -1) { diff --git a/apps/opencs/model/world/universalid.cpp b/apps/opencs/model/world/universalid.cpp index fbc942f8e2..e496fe79bb 100644 --- a/apps/opencs/model/world/universalid.cpp +++ b/apps/opencs/model/world/universalid.cpp @@ -38,9 +38,9 @@ namespace { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Enchantments, "Enchantments", 0 }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_BodyParts, "Body Parts", 0 }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Referenceables, - "Referenceables", 0 }, + "Objects", 0 }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_References, - "References", 0 }, + "Instances", 0 }, { CSMWorld::UniversalId::Class_NonRecord, CSMWorld::UniversalId::Type_RegionMap, "Region Map", 0 }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Filters, "Filters", 0 }, @@ -79,7 +79,7 @@ namespace { CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_JournalInfo, "JournalInfo", 0 }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell, "Cell", ":./cell.png" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell_Missing, "Cell", ":./cell.png" }, - { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Referenceable, "Referenceables", 0 }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Referenceable, "Object", 0 }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Activator, "Activator", ":./activator.png" }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Potion, "Potion", ":./potion.png" }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Apparatus, "Apparatus", ":./apparatus.png" }, @@ -103,7 +103,7 @@ namespace { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Repair, "Repair", ":./repair.png" }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Static, "Static", ":./static.png" }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Weapon, "Weapon", ":./weapon.png" }, - { CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Reference, "Reference", 0 }, + { CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Reference, "Instance", 0 }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Filter, "Filter", ":./filter.png" }, { CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Scene, "Scene", 0 }, { CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Preview, "Preview", 0 }, diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index e430bfa5e3..5636fff943 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -131,11 +131,11 @@ void CSVDoc::View::setupWorldMenu() connect (cells, SIGNAL (triggered()), this, SLOT (addCellsSubView())); world->addAction (cells); - QAction *referenceables = new QAction (tr ("Referenceables"), this); + QAction *referenceables = new QAction (tr ("Objects"), this); connect (referenceables, SIGNAL (triggered()), this, SLOT (addReferenceablesSubView())); world->addAction (referenceables); - QAction *references = new QAction (tr ("References"), this); + QAction *references = new QAction (tr ("Instances"), this); connect (references, SIGNAL (triggered()), this, SLOT (addReferencesSubView())); world->addAction (references); diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 582ccea643..e3e5ce50e6 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -258,7 +258,7 @@ unsigned int CSVRender::WorldspaceWidget::getInteractionMask() const void CSVRender::WorldspaceWidget::addVisibilitySelectorButtons ( CSVWidget::SceneToolToggle2 *tool) { - tool->addButton (Element_Reference, "References"); + tool->addButton (Element_Reference, "Instances"); tool->addButton (Element_Water, "Water"); tool->addButton (Element_Pathgrid, "Pathgrid"); } @@ -267,7 +267,7 @@ void CSVRender::WorldspaceWidget::addEditModeSelectorButtons (CSVWidget::SceneTo { /// \todo replace EditMode with suitable subclasses tool->addButton ( - new EditMode (this, QIcon (":placeholder"), Element_Reference, "Reference editing"), + new EditMode (this, QIcon (":placeholder"), Element_Reference, "Instance editing"), "object"); tool->addButton ( new EditMode (this, QIcon (":placeholder"), Element_Pathgrid, "Pathgrid editing"),