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 392fdfc66..9168d9a5a 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 855e89cad..fa9c92e7d 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 50998c36f..31797d081 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 f00e9fc77..afb61acc6 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 bd509a86b..59c8c6461 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 f515e34d8..1745ce957 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 1b600364c..535e914ee 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 94ae38c3c..283f062fe 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 0870a2d3e..673b1f5a4 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 afb61acc6..df64e9f05 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 59c8c6461..f29501698 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 df64e9f05..8c98e1808 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 cbe90b1d3..d41a015ca 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 1fb3e1f1d..88ef59ace 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 241f198cb..7b6912575 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 442055d5f..19017047b 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 fe310d0aa..c8670a03b 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 31797d081..04d1b333b 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 8b5462825..deb07a1b2 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 283f062fe..2259a6e44 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 673b1f5a4..c9c778020 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 8c98e1808..750e4af87 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 f29501698..eab0151b5 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 1745ce957..74aa67e3b 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 dd6213677..d03b45814 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 abdc33103..4ac8e8780 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()); - - mDispatcher.makeDelegate(display); - QWidget *editor = mDispatcher.makeEditor(display, (mTable->index (row, i))); + (mTable->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); - 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)) - { - lockedLayout->addWidget (label, locked, 0); - lockedLayout->addWidget (editor, locked, 1); - ++locked; - } else + mDispatcher.makeDelegate (display); + QWidget* editor = mDispatcher.makeEditor (display, (mTable->index (row, i))); + + if (editor) { - 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 b2a32b551..5fa93fe79 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 4ac8e8780..d537ac4f1 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 5642f46a0..dd14b3095 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 1fb3e1f1d..3f110b4dd 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 241f198cb..eed157a7b 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 442055d5f..4c3afc092 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 50998c36f..59fc3a508 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 8b5462825..bf9f4a555 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 94ae38c3c..785e98d5e 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 0870a2d3e..3a9d02dca 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 f00e9fc77..b67b26cdb 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 bd509a86b..ed6c50fe3 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 f515e34d8..c9d6700b5 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 dd6213677..f4ac556cf 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 d537ac4f1..03321728b 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 874d65af3..3632f1e08 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 | 41 +++++++--------------- 1 file changed, 13 insertions(+), 28 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 523b358ae..db80af025 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)); + QModelIndex currentIndex(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 (state==CSMWorld::RecordBase::State_Deleted || locked); + + if (currentIndex.isValid()) { - mEditWidget->setDisabled(mLocked); - } - - CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (mRow, 1)).toInt()); + 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); + } - 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 db80af025..8ffc0da56 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 8ffc0da56..9d6538c1c 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 9d6538c1c..e9910f42b 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 e9910f42b..0f2ae73dd 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 2a9dd2e4f..2fdceacb1 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 0f2ae73dd..e798c8320 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 2fdceacb1..050aad947 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 e798c8320..bc2a6048a 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 59fc3a508..cbfb7f923 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 2a0ba43ea..7db4662ba 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 cde5dc455..a01e59371 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 7db4662ba..49d23bed4 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 ad7fbd049..936663399 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 a9a1bb96e..08bac8b08 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 050aad947..f36785e88 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 f6363fe2e..e81943843 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 c8670a03b..9761b95aa 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 49d23bed4..6aba322c1 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 936663399..a8fac216b 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 cb0baa45b..fec621ac1 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 d9cac95f3..e76e64610 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 fa9c92e7d..e824c4392 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 000000000..20a68faad --- /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 000000000..acab1f851 --- /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 20a68faad..9a685557e 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 acab1f851..be29be2ca 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 08bac8b08..7a0e2efec 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 f36785e88..90a365592 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 9a685557e..9ae4bdfd3 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 be29be2ca..80c7f5a8e 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 7a0e2efec..109f0c3fa 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 9761b95aa..164ca4302 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 e81943843..c0a264a1f 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 164ca4302..0cd1f722f 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 7410780e0..e39badeb5 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 e824c4392..436ca1334 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 6aba322c1..fd2547ecf 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 6dc6f3e33..29d1f134a 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 9ae4bdfd3..534ec5d10 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 80c7f5a8e..404051efc 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 a8fac216b..47c8ec800 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 c0a264a1f..59ee39126 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 0cd1f722f..1cc45780f 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 e39badeb5..1898277a5 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 436ca1334..5d8ddb87d 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 47c8ec800..9fe42af96 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 039f44a5e..928c0eaab 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 19b8b06b8..6377db040 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 a01e59371..eeb859d84 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 7ea25770a..70f1fdf9f 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 b6aad7eff..01fde1c8c 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 fd2547ecf..6e43cfeac 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 928c0eaab..fddb073a2 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 6377db040..01652ea7e 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 eeb859d84..1f3a07dc0 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 9fe42af96..47e52289f 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 fec621ac1..08fb410a5 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 535e914ee..bfdd4f9ee 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 b60ffeb29..019a3d397 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 ec6350658..192b161ef 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 6e43cfeac..90d7e35b5 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 70f1fdf9f..a1f4f4a70 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 01fde1c8c..aad40d36b 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 90d7e35b5..a4e4972b4 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 29d1f134a..bf72b8026 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 fddb073a2..068347fda 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 01652ea7e..5b92ae941 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 1f3a07dc0..6fc56271b 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 47e52289f..57a42d9fb 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 08fb410a5..7801811ff 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 019a3d397..42a5a7f7e 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 192b161ef..9cfc0b293 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 42a5a7f7e..012736697 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 90a365592..a6b944d7a 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 000000000..beeafed90 --- /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 000000000..200a73798 --- /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 e76e64610..eec1b653d 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 109f0c3fa..122b173e6 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 beeafed90..bfadfc08c 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 200a73798..fe6214151 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 534ec5d10..20fbd81e1 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 404051efc..0af261f4d 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 bfadfc08c..b4bb63f3a 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 b4bb63f3a..ec5d01bbe 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 fe6214151..14a46480e 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 ec5d01bbe..ffb1aaa47 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 14a46480e..bdd3db3fa 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 9cfc0b293..e6f2d9724 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 20fbd81e1..133520d1d 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 0af261f4d..18563b389 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 ffb1aaa47..ebcce15d5 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 bdd3db3fa..eb73cd885 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 a4e4972b4..29d2a543e 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 ebcce15d5..2eef2e915 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 eb73cd885..35fa22494 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 29d2a543e..f71c367f0 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 133520d1d..17bf7b30c 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 18563b389..2263524cf 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 2eef2e915..a185fc7ce 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 | 11 ++++++---- apps/opencs/model/world/nestedtablemodel.cpp | 21 ++++++++++++++++++++ apps/opencs/model/world/nestedtablemodel.hpp | 4 ++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index f71c367f0..a74bd629b 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -125,18 +125,21 @@ 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); + beginRemoveRows (parent, row, row+count-1); - mIdCollection->removeRows (row, count); + mIdCollection->removeRows (row, count); + } endRemoveRows(); diff --git a/apps/opencs/model/world/nestedtablemodel.cpp b/apps/opencs/model/world/nestedtablemodel.cpp index 17bf7b30c..6d6618590 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 2263524cf..dfb231124 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 6d6618590..cb7943f5e 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 cb7943f5e..d0648e5e9 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 122b173e6..673d3573f 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 a6b944d7a..c1bc96211 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 | 38 +++++++++++++++++--------- apps/opencs/view/world/nestedtable.cpp | 3 +- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index a74bd629b..c2eb32fa5 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()); + + emit dataChanged (CSMWorld::IdTable::index (parentAdress.first, 0), + CSMWorld::IdTable::index (parentAdress.second, mIdCollection->getColumns()-1)); + + return true; + } else + { + return false; } - return true; } - + + 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 a185fc7ce..21bef504b 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 c2eb32fa5..0b5f9c5a3 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 3f9e7e1a3..bf03ab563 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 | 40 +++++++++++++-------- apps/opencs/model/world/columnbase.hpp | 37 ++++++++++++++----- 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, 66 insertions(+), 36 deletions(-) diff --git a/apps/opencs/model/world/columnbase.cpp b/apps/opencs/model/world/columnbase.cpp index 59ee39126..60e201ba4 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); + if (!mCanNest) + throw std::logic_error("Tried to access number of the subcolumns in the non-nest column"); + + return mNestedColumns.size(); +} - mNestedColumnId.push_back(columnId); +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 bf03ab563..096491f1e 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; + virtual int getId() const; + }; - void addNestedColumnDisplay(Display displayDefinition); + class NestedColumn; - void addNestedColumnId(int columnId); + class NestColumn : public ColumnBase + { + std::vector mNestedColumns; - virtual int getId() const; + 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 00cfbd145..a3435180c 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 7033140ca..8d6ab838d 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 7aa1d7753..62daef903 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 7801811ff..d1bb197e8 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 d1bb197e8..02b77400b 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 62daef903..1a164d12f 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 d0648e5e9..f0b510244 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 3b39dc6f9..904587eaf 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 3871a4d5a..bcc64b60a 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 904587eaf..ac4351986 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 aad40d36b..62f4079fc 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 012736697..5e886bdb4 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 e6f2d9724..214a5157e 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 a3435180c..df0f4546d 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 fcb87c8b2..fd3f699ba 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 000000000..387bc6e7b --- /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 000000000..9fc21f8e0 --- /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 068347fda..f4aa769fd 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 8d6ab838d..cb078ab74 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 500b18ef8..4198fb367 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 1a164d12f..6ff0df802 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 02b77400b..927331c93 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 9fc21f8e0..c13a12c62 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 cb078ab74..d669a369c 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 ac4351986..591074372 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 62f4079fc..a6ee34e56 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 5e886bdb4..f464d75c8 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 214a5157e..d45ec1e36 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 df0f4546d..dd045cb78 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 fd3f699ba..b7ba8c342 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 c13a12c62..70e35f68a 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 f4aa769fd..f7064ab66 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 d669a369c..173e89f56 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 4198fb367..ab05cfbc5 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 6ff0df802..80ac1cc3b 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 927331c93..cc7609a58 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 bcc64b60a..a9c56f9fa 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 dd045cb78..be31d0503 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 b7ba8c342..d755822b5 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 f0b510244..734047b8d 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 dfb231124..5fea5c006 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 387bc6e7b..3966dbc57 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 70e35f68a..f0ca00dbe 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 f464d75c8..0d9f6c773 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 d45ec1e36..d868ccf46 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 a9c56f9fa..08c105c92 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 000000000..8ed1819b8 --- /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 000000000..c0ca9744c --- /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 173e89f56..08d890957 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 ab05cfbc5..aac2ba807 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 c0ca9744c..d5edf3358 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 08d890957..3622c77af 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 d5edf3358..8f82482d8 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 3622c77af..3600562d3 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 3600562d3..f85138d97 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 8f82482d8..a961d19e4 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 f85138d97..2a8fec01d 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 a961d19e4..9e747164a 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 2a8fec01d..5681b8bae 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 8ed1819b8..1e8425229 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 9e747164a..806dc587d 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; + + 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; - InventoryHelper(CSMWorld::UniversalId::Type type) : mType(type) {}; + virtual int getNestedColumnsCount(const RefIdData& data) const = 0; - void setNestedTable(const RefIdColumn* column, - RefIdData& data, - int index, - const NestedTableWrapperBase& nestedTable) + 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 50314e7a2..631c192fd 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::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; +} -CSMWorld::NestedRefIdAdapter::~NestedRefIdAdapter() {} \ No newline at end of file +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 f7064ab66..dd2248e92 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 5681b8bae..18287d596 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 -{ - assert(column==mContent); - - return 2; -} - -int CSMWorld::ContainerRefIdAdapter::getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const + mOrganic (organic), mRespawn (respawn), mContent(content) { - assert(column==mContent); - - const Record& record = static_cast&> ( - data.getRecord(RefIdData::LocalIndex (index, UniversalId::Type_Container))); + std::vector > assoCol; - return record.get().mInventory.mList.size(); + assoCol.push_back(std::make_pair(content, new InventoryHelper(UniversalId::Type_Container))); + + setAssocColumns(assoCol); } -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 aac2ba807..ee069dd38 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 283e15db7..6812bbae9 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 ee069dd38..6fe479150 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 80ac1cc3b..493b716eb 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 806dc587d..3807f0219 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(); - } - - private: - - const Record& getRecord(const RefIdData& data, int index) const - { - return dynamic_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, mType))); + return CastableHelper::getRecord(data, index).get().mInventory.mList.size(); } - 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 3807f0219..0bb998316 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 dd2248e92..22941fd9f 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 83d0ccc79..1f13645da 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 6812bbae9..908165e9d 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 6fe479150..ee2a58624 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 493b716eb..89469feac 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 096491f1e..5e4dac3ce 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 0bb998316..095bcdf95 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 ee2a58624..4c65da85c 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 89469feac..eb25b277e 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 5e4dac3ce..05fecaec0 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 1f13645da..212772450 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 908165e9d..7efaf2bd0 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 095bcdf95..319fe1569 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 631c192fd..58b775f47 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 22941fd9f..d18e7f02e 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 18287d596..ac546db51 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 4c65da85c..6fd42b00e 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 eb25b277e..d776931f8 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 23a47b313..644d32e84 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 644d32e84..eb03be085 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 212772450..0c44c2dcb 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 7efaf2bd0..b06018dd4 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 0d9f6c773..30c4bb892 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 319fe1569..6e3d447b2 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 377f479bf..16f38938d 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 591074372..252e84c38 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 a1f4f4a70..5b0c359c9 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 a6ee34e56..29ac33bc8 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 be31d0503..4e4ccb1c1 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 cc7609a58..62616d369 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 252e84c38..5c32e7716 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 3fad05f65..e416c332b 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 4e4ccb1c1..410e0d3f0 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 eba73cf0b..95023f49d 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 67f6822c7..b925a66b3 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 95023f49d..ed2cfc310 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 8349eb515..d85125bd5 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 ca0326655..d3476f7b2 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 b925a66b3..e8905b925 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 eb62434cf..411024691 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 47f0276c6..1a0dd1e5b 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 f3c1b0b73..63594acc8 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 411024691..dae9488f0 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 1a0dd1e5b..19dfae57d 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 19dfae57d..dcb295626 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 4e146d87c..a0b7a9fa0 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 50085b1a1..1d29e48c1 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 4cd11925e..6ab470a02 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 46ca17a29..b9df52bf7 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 73790e3c6..f6e4c2688 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 8790601ea..497ce7acd 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 4c260170f..f45ed40c4 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 168e5cb0a..95b120e9a 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 3b440ff71..34c8d12cd 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 e9a0af68c..d0ed6997b 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 708a78015..58a5c0177 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 fbdaed538..acaf872a6 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 e864e4ed2..794510f42 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 c65e12c60..8039034a2 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 b4d972bf3..df9d61dad 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 c3c98b800..90a686a67 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 c86b936f6..a8f39c318 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 db9b8b3c6..03e373904 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 c68b71789..773326490 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 a0b7a9fa0..cda4f3a74 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 de0e9a4e5..bd667e40b 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 a15c071a8..26e1da828 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 29d26d013..a14f977d6 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 9c57061b0..505f676b1 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 08f8c9eaa..6b8750b44 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 84bca1e95..e7ad551b2 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 577fc734d..e6c8c545a 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 a14f977d6..0e258571f 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 6b8750b44..4354a0313 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 0e258571f..546151e27 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 505f676b1..d4e63d6e8 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 dcb295626..39f85da70 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 546151e27..8579d891f 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 e4f847dec..d836ec9cf 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 e1a6eee1a..8eeecd893 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 2852cb581..fc8ac66b7 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 f6ad79a6a..a2b6f45f1 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 3f48aef42..45581bc3f 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 21bef504b..14e079c98 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 35fa22494..6b6b6aaba 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 ab3765bb6..2125deeff 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 61fe4b322..e688a9474 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 000000000..e3c01368b --- /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 000000000..cb82cbae7 --- /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 e78758bb6..2139f890f 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 5c32e7716..1fb3e1f1d 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 5b0c359c9..241f198cb 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 dc8edbc51..da14bb495 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 7c305b1b6..168e5cb0a 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 11521bb67..c65e12c60 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 eec4f2bd3..b4701126b 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 9166bf909..734df7d74 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 2363ae477..e3093d568 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 5926df269..607f585b7 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 6e3d447b2..cc062e827 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 cdc06f985..93c9797b2 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 4e03b788a..4e83c25db 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 0d4518f87..617f38daf 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 c8bf8ad64..1d3bc7641 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 69bbfa39f..1c0af217b 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 8d51bbf7e..421e12c13 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 82d9f6977..c9ca60b33 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 29ac33bc8..ef826e31c 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 fc8ac66b7..964b68cd1 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 1e8425229..1c8b1eff1 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 cc062e827..ac2a650d4 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 000000000..dffa29573 --- /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 387ee8606..af7469637 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 11befaeec..acc6c40c1 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 ee09cafa1..c48896435 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 62616d369..ab25c93fa 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 c9ca60b33..5f9559257 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 964b68cd1..c5061b93d 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 734047b8d..c098e0316 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 5fea5c006..7ad8fc0c2 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 421e12c13..e26dcdc9b 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 6ea79aa95..72acb1966 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 14e079c98..1597c81a3 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 6b6b6aaba..f41ba4345 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 c5061b93d..1c21e64c3 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 | 206 +----------- 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, 589 insertions(+), 371 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 5f9559257..39b4c486b 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 60e201ba4..665ab9354 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 607f585b7..b717f3a52 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 959f6b345..7acc6058e 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 c194e2779..42405a2f9 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 39cff3db6..a5ef439a7 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 1c21e64c3..7618a073a 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) { - 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 - { + return false; - beginRemoveRows (parent, row, row+count-1); + 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 05c523ccb..ea8ab80f9 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 000000000..595b0ac51 --- /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 000000000..6a3d7423c --- /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 000000000..4ade75b33 --- /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 000000000..28ced85e9 --- /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 dffa29573..5ec50b423 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 c098e0316..fede8383b 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 7ad8fc0c2..7dc66989c 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 c48896435..ca5efcdd9 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 ab25c93fa..dd432c5a9 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 bfdd4f9ee..eaa7b115d 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 e26dcdc9b..0aa83eb92 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 000000000..f557c3ba1 --- /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 0aa83eb92..d0b53a206 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 | 156 ++++++------------- 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, 165 insertions(+), 224 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 39b4c486b..8cf37da1d 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 1fb3e1f1d..dc52ae663 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 665ab9354..94c5afb83 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 b717f3a52..da1d8f0df 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 a5ef439a7..0cfc890ea 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 7618a073a..28742c8f2 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 ea8ab80f9..914b01cf9 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 595b0ac51..4befd1eee 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()) { + beginRemoveRows (parent, row, row+count-1); + for (int i = 0; i < count; ++i) { - mIdCollection->removeNestedRows(parent.row(), parent.column(), row+i); + mNestedCollection->removeNestedRows(parent.row(), parent.column(), row+i); } - } - else - { - - beginRemoveRows (parent, row, row+count-1); - - mIdCollection->removeRows (row, count); - } - endRemoveRows(); + endRemoveRows(); - emit dataChanged (CSMWorld::IdTree::index (parent.row(), 0), - CSMWorld::IdTree::index (parent.row(), mIdCollection->getColumns()-1)); + emit dataChanged (CSMWorld::IdTree::index (parent.row(), 0), + CSMWorld::IdTree::index (parent.row(), idCollection()->getColumns()-1)); - return true; + 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 6a3d7423c..80b44d241 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 4ade75b33..000000000 --- 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 28ced85e9..000000000 --- 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 f557c3ba1..937ad6ad6 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 5ec50b423..8046f9a09 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 QVariant getNestedData(int row, int column, int subRow, int subColumn) const = 0; - - virtual NestedTableWrapperBase* nestedTable(int row, int column) const = 0; + virtual void removeNestedRows(int row, int column, int subRow) = 0; - virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable) = 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 int getNestedRowsCount(int row, int column) const = 0; + virtual NestedTableWrapperBase* nestedTable(int row, int column) const = 0; - virtual int getNestedColumnsCount(int row, int column) const = 0; + virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable) = 0; - virtual void removeNestedRows(int row, int column, int subRow) = 0; + virtual int getNestedRowsCount(int row, int column) const; - private: + virtual int getNestedColumnsCount(int row, int column) const; - 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 ca5efcdd9..41ca7e440 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 dd432c5a9..2a271a846 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 dc52ae663..4bc9632a8 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 94c5afb83..e4d2195be 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 da1d8f0df..aef68fdbd 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 da14bb495..27fc3ad04 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 1d3bc7641..db0ebfd86 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 1c0af217b..e36e29b3b 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 0cfc890ea..ea94fe905 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 000000000..bec21a0f3 --- /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 000000000..fa7c55bd3 --- /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 74bb6c955..f2aeb5aaf 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 ac2a650d4..a2cbea1a6 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 fede8383b..182ed11ab 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 7dc66989c..177a25d28 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 af7469637..7f7d00413 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 99117cc7f..b2a08e71c 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 acc6c40c1..f72c0d196 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 d0b53a206..79eb48534 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 298a9be1f..b9e060002 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 fa7c55bd3..025c2e137 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 f2aeb5aaf..919a0a604 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 42405a2f9..a70b36178 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 bec21a0f3..753ac01f0 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 80b44d241..d06d86a4f 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 8046f9a09..b075f53c4 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 7f7d00413..91f19577b 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 f72c0d196..7296b6c68 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 2a271a846..5bf7c177e 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 919a0a604..92091cf57 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 025c2e137..aed847909 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 a2cbea1a6..015765380 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 177a25d28..2ab04a584 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 aed847909..510a14f12 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 27fc3ad04..70c134e01 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 db0ebfd86..e6a27138f 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 e36e29b3b..2cb7101b0 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 ea94fe905..76e34961f 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 510a14f12..f5ed2e6e1 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 f5ed2e6e1..746815414 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 4befd1eee..952c9e329 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 d06d86a4f..5f005c4d3 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 cf2940b99..f9fe613ef 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 4bc9632a8..b0571bbed 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 e4d2195be..8d1985ff2 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 aef68fdbd..e6799cf56 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 70c134e01..3fb9a4685 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 e6a27138f..b65cf7f96 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 7acc6058e..d12c5d228 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 76e34961f..87d5116f1 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 753ac01f0..84ef2d1f8 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 746815414..2ce0777ac 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 015765380..97046276f 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 58b775f47..a12a95196 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 91f19577b..1a3f2700e 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 41ca7e440..b85deef4e 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 5bf7c177e..3315212c1 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 92091cf57..c53c7006a 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 952c9e329..49ceced2c 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())); + + if (role == Qt::EditRole && + !mNestedCollection->getNestableColumn(parentAddress.second)->nestedColumn(index.column()).isEditable()) + { + return QVariant(); + } - return mNestedCollection->getNestedData(parentAdress.first, - parentAdress.second, index.row(), index.column()); + 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 5f005c4d3..5337ed82b 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 182ed11ab..7b35c88e4 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 2ab04a584..f5cbdb10b 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 49ceced2c..eddde5a89 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 7b35c88e4..0f137d78f 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 b0f8a035a..f3b23100a 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 2ce0777ac..7df653059 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 000000000..c7e840955 --- /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 c53c7006a..df1f8a12e 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 e6799cf56..3902a009b 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 3fb9a4685..06467a632 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 b65cf7f96..39b3ea2e3 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 2cb7101b0..49a9208b0 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 87d5116f1..c387298d2 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 b9e060002..329aceaf7 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 7df653059..d5a44aea2 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 3902a009b..c994ced15 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 06467a632..675352d35 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 39b3ea2e3..c9155a5ad 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 49a9208b0..531cf9972 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 c387298d2..3352dd30e 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 329aceaf7..858f82639 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 d5a44aea2..00f7b1831 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 00f7b1831..9c4686f4e 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 c9155a5ad..a2843d3e8 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 531cf9972..a1dc89393 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 3352dd30e..87ba44001 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 858f82639..172a194be 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 9c4686f4e..c49435f1c 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 b85deef4e..392a1677e 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 87ba44001..74b418b30 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 172a194be..2d2fd974c 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 | 75 +++++++++++--- apps/opencs/model/world/data.hpp | 4 +- apps/opencs/model/world/idadapterimp.hpp | 119 +++++++++++++++++++++++ 6 files changed, 201 insertions(+), 107 deletions(-) diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index 675352d35..0ab33065b 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 a2843d3e8..efe9a5116 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 a1dc89393..6b3791042 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 74b418b30..86cf3bb44 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)); - - PathgridEdgeListColumn *edgeList = new PathgridEdgeListColumn (); + 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)); + + 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 2d2fd974c..5ab69ac10 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 c49435f1c..219032dd3 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 0ab33065b..210d63803 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 efe9a5116..fca16ec0b 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 6b3791042..4f77ee23a 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 86cf3bb44..538b240dc 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 219032dd3..d5bf83a2d 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 8d1985ff2..0d9eb1664 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 c994ced15..dc3aae11a 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 210d63803..68e7dd7b5 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 538b240dc..69e2b5aa8 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 | 495 ++++------------------- 5 files changed, 534 insertions(+), 431 deletions(-) create mode 100644 apps/opencs/model/world/idadapterimp.cpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 8cf37da1d..bc0b964ae 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 dc3aae11a..c7c8d3cd8 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 69e2b5aa8..db644affa 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 000000000..95e68e09e --- /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 d5bf83a2d..effa0011c 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 CSMWorld +namespace ESM { - template - class PathgridPointListAdapter : public NestedIdAdapter - { - public: - PathgridPointListAdapter () {} - - virtual void addNestedRow(Record& record, int position) 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"); - } - } + struct Faction; + struct Region; +} - 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"); - } +namespace CSMWorld +{ + struct Pathgrid; - pathgrid.mPoints[subRowIndex] = point; + struct PathgridPointsWrap : public NestedTableWrapperBase + { + ESM::Pathgrid mRecord; - record.setModified (pathgrid); - } + PathgridPointsWrap(ESM::Pathgrid pathgrid) + : mRecord(pathgrid) {} - virtual int getNestedColumnsCount(const Record& record) const - { - return 4; - } + virtual ~PathgridPointsWrap() {} - virtual int getNestedRowsCount(const Record& record) const + virtual int size() 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 () {} - - // 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(); - - 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); - } - - virtual void removeNestedRow(Record& record, int rowToRemove) const - { - ESXRecordT 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); - } + PathgridPointListAdapter (); - 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(); + virtual void addNestedRow(Record& record, int position) const; - 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"); - } - } + virtual void removeNestedRow(Record& record, int rowToRemove) const; - // FIXME: detect duplicates in mEdges - virtual void setNestedData(Record& record, const QVariant& value, - int subRowIndex, int subColIndex) const - { - ESXRecordT pathgrid = record.get(); + virtual void setNestedTable(Record& record, + const NestedTableWrapperBase& nestedTable) const; - if (subRowIndex < 0 || subRowIndex >= static_cast (pathgrid.mEdges.size())) - throw std::runtime_error ("index out of range"); + virtual NestedTableWrapperBase* nestedTable(const Record& record) const; - 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"); - } + virtual QVariant getNestedData(const Record& record, + int subRowIndex, int subColIndex) const; - pathgrid.mEdges[subRowIndex] = edge; + virtual void setNestedData(Record& record, + const QVariant& value, int subRowIndex, int subColIndex) const; - record.setModified (pathgrid); - } + virtual int getNestedColumnsCount(const Record& record) const; - 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 () {} - - 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::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"); - } - } + PathgridEdgeListAdapter (); - virtual void setNestedData(Record& record, const QVariant& value, - int subRowIndex, int subColIndex) 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; - if (subRowIndex < 0 || subRowIndex >= static_cast (reactions.size())) - throw std::runtime_error ("index out of range"); + virtual void setNestedTable(Record& record, + const NestedTableWrapperBase& nestedTable) 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 < subRowIndex; ++i) - iter++; + virtual NestedTableWrapperBase* nestedTable(const Record& record) const; - 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"); - } + virtual QVariant getNestedData(const Record& record, + int subRowIndex, int subColIndex) const; - record.setModified (faction); - } + virtual void setNestedData(Record& record, + const QVariant& value, int subRowIndex, int subColIndex) const; - virtual int getNestedColumnsCount(const Record& record) const - { - return 2; - } + virtual int getNestedColumnsCount(const Record& record) const; - 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 () {} - - virtual void addNestedRow(Record& record, int position) const - { - ESXRecordT region = record.get(); - - std::vector& soundList = region.mSoundList; + FactionReactionsAdapter (); - // blank row - typename 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(); + virtual void addNestedRow(Record& record, int position) const; - std::vector& soundList = region.mSoundList; + virtual void removeNestedRow(Record& record, int rowToRemove) const; - 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; - virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) const - { - record.get().mSoundList = - static_cast >&>(nestedTable).mNestedTable; - } + virtual NestedTableWrapperBase* nestedTable(const Record& record) const; - 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; - virtual QVariant getNestedData(const Record& record, int subRowIndex, int subColIndex) 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 (subRowIndex < 0 || subRowIndex >= static_cast (soundList.size())) - throw std::runtime_error ("index out of range"); + virtual int getNestedRowsCount(const Record& record) 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"); - } - } + class RegionSoundListAdapter : public NestedIdAdapter + { + public: + RegionSoundListAdapter (); - virtual void setNestedData(Record& record, const QVariant& value, - int subRowIndex, int subColIndex) 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; - if (subRowIndex < 0 || subRowIndex >= static_cast (soundList.size())) - throw std::runtime_error ("index out of range"); + virtual void setNestedTable(Record& record, + const NestedTableWrapperBase& nestedTable) const; - 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"); - } + virtual NestedTableWrapperBase* nestedTable(const Record& record) const; - region.mSoundList[subRowIndex] = soundRef; + virtual QVariant getNestedData(const Record& record, + int subRowIndex, int subColIndex) const; - record.setModified (region); - } + virtual void setNestedData(Record& record, + const QVariant& value, int subRowIndex, int subColIndex) const; - virtual int getNestedColumnsCount(const Record& record) const - { - return 2; - } + virtual int getNestedColumnsCount(const Record& record) const; - 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 bc0b964ae..babd3363f 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 db644affa..d7280e354 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 95e68e09e..2bf1ffadd 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 effa0011c..7fed74868 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 84ef2d1f8..e7e66ed4d 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 c7e840955..0cf51b9d8 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 1a3f2700e..f80ce7ab3 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 b2a08e71c..426bfe3d1 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 7296b6c68..b12d0cb6f 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 392a1677e..929a3b245 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 3315212c1..70651b78d 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 2bf1ffadd..785817d33 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 7fed74868..387b07e5c 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 426bfe3d1..42d1aa52e 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 b12d0cb6f..08e2e7493 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 929a3b245..755a1f56f 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 babd3363f..cfe084e2c 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 1c8b1eff1..000000000 --- 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 97046276f..000000000 --- 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 a12a95196..37cb67bca 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 f80ce7ab3..ba9da577d 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 42d1aa52e..cd3a20327 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 08e2e7493..32e9148c7 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 755a1f56f..92cd37d0d 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 70651b78d..f183dc7a0 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 32e9148c7..2599dc960 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 2599dc960..a3007d415 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 92cd37d0d..3f14ba4ac 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 f183dc7a0..4d511d12d 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 fca16ec0b..92a0d8f8d 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 4f77ee23a..2788966a7 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 785817d33..d974a34c7 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 387b07e5c..3328396fb 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 a3007d415..c0fcba43c 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 3f14ba4ac..000426a0b 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 92a0d8f8d..547efac56 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 2788966a7..6068ea6e7 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 3328396fb..2aa1123a3 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 cd3a20327..98c1b6f0f 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 c0fcba43c..bc00d31f9 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 000426a0b..48f95451c 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 547efac56..83d6ceb57 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 6068ea6e7..81cae5e36 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 bc00d31f9..d09aaaa45 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 48f95451c..be5d67766 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 c7c8d3cd8..813de8d96 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 eddde5a89..06db09a0f 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 0f137d78f..acf197716 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 f5cbdb10b..2d5a46c48 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 79eb48534..88791c9cd 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 72acb1966..067ff95f5 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 f3b23100a..5694c6e5a 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 | 88 ++++++------- apps/opencs/model/world/columns.hpp | 2 + apps/opencs/model/world/refidadapterimp.hpp | 131 +++++++++++++++++++- apps/opencs/model/world/refidcollection.cpp | 14 +++ 4 files changed, 191 insertions(+), 44 deletions(-) diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 83d6ceb57..81968d114 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_RegionSounds, "Sounds"}, - { ColumnId_SoundName, "Name"}, - { ColumnId_SoundChance, "Chance"}, - - { 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_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_LevelledList,"Levelled List"}, - { ColumnId_LevelledItemId,"Item ID"}, - { ColumnId_LevelledItemLevel,"Level"}, + { 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_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_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_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 81cae5e36..986b90df5 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 d09aaaa45..2b2b189e0 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 be5d67766..02d876df8 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 197fb5ad3..437d07f97 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 81968d114..ff28a1289 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 986b90df5..7c28f9589 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 d7280e354..5733fd83f 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 d133f3ba9..2e53c2b1c 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 5733fd83f..843d08281 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 2aa1123a3..951c7a610 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 2e53c2b1c..92fbfd08e 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 01032bcda..1b000fabb 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 7c305b1b6..eb523f781 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 5ef4aa444..045afe04c 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 437d07f97..f6ebb16b8 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 ff28a1289..3d15ed4f3 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 7c28f9589..7508c9880 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 843d08281..f4edb8e57 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 951c7a610..3f8e6d6a9 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 92fbfd08e..a685276f4 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 9fee26078..1dfe3a792 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 045afe04c..5690d9253 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 f6ebb16b8..8dab0602e 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 3d15ed4f3..19efc8177 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 f4edb8e57..0490cbe7a 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 3f8e6d6a9..1ee447f34 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 a685276f4..636f9a57f 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 1dfe3a792..1281f89f2 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 5690d9253..cea00b7bc 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 8dab0602e..20e3ccce6 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 19efc8177..fd090d181 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 2b2b189e0..489808393 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 636f9a57f..3bdf8361f 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 1281f89f2..3f0c10053 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 cea00b7bc..659954f48 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 20e3ccce6..4c3f9385a 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 fd090d181..1b5aefee9 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 7508c9880..1760bff30 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 489808393..5fd888441 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 3bdf8361f..caf1041c6 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 3f0c10053..5908c67a1 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 10a192668..9d718cf81 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 eb523f781..c635948a3 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 9d718cf81..9358bf6c7 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 c635948a3..bda93678a 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 1ee447f34..841c3955a 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 9358bf6c7..6626d67c3 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 bda93678a..eb523f781 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 d974a34c7..bd6a5c449 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 841c3955a..8d0b0ce7a 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 e7e66ed4d..5e7256fa7 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 0cf51b9d8..2b795f9c6 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 5fd888441..9556c83e3 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 bd6a5c449..bfb2fb578 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 8d0b0ce7a..4a7101cba 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 5e7256fa7..462b5a5ab 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 2b795f9c6..792a13b7d 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 9556c83e3..d3d52d2e1 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 6626d67c3..2e800b56f 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 9a5fc1933..9fb80324e 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 4c3f9385a..0e954ecca 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 1b5aefee9..1ea7da647 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 1760bff30..5a1577ddb 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 0490cbe7a..873d8b78a 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 5ab69ac10..8689b98c0 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 bfb2fb578..d29155a47 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 4a7101cba..96dcd943d 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 000000000..4abaaf9c0 --- /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 000000000..03c0c2349 --- /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 caf1041c6..4a8f398cd 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 2e800b56f..f067c3225 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 7a1a86153..2d444f245 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 aaf8f2d6a..e430bfa5e 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 cb3b4ba18..31d0aaccd 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 aa5af0e6d..811eb8763 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 617f38daf..da8d49db0 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 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, npcRating2, npcRating3; + getPersuasionRatings(npcStats, npcRating1, npcRating2, npcRating3, false); - 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 d3d52d2e1..41d8c65d5 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 d12c5d228..ce82e07bf 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 a70b36178..2bd47ae91 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 eaa7b115d..85d16a6eb 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 ca6faafbc..d94033d9c 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 ce82e07bf..5a3190846 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 2bd47ae91..89ca5d1ff 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 28742c8f2..2f0164c2d 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 559a43cb7..9ecba0214 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 06db09a0f..564e4ec2f 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 5337ed82b..73cc9bdfd 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 257b67d72..71c22a9f0 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 6612349f7..13706c950 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 12b4c86f6..cf3653c1b 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 4d463246a..b5a44d266 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 1597c81a3..5c8762020 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 f41ba4345..b8e91844c 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 fbcfc5215..8b4bfeaac 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 f78cc0c85..f9f5e161a 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 f98b407c6..0fb449e16 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 d94033d9c..199f91e29 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 564e4ec2f..06db09a0f 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 73cc9bdfd..5337ed82b 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 39f85da70..bd4e69d6b 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 d836ec9cf..aed56f415 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 554fa3967..b78d4075a 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 bd4e69d6b..14d4a1db5 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 f9f5e161a..ef33f495f 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 | 55 ++++++++++++++++------- 3 files changed, 57 insertions(+), 20 deletions(-) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index b25d84829..91fa556ab 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 f00ea447a..4eafc59bd 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 14d4a1db5..bd4cf918c 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 << "#" << 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]; - //std::cout <<"refcollection " + stream.str() << std::endl; + 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 - stream << "#" << index.first << " " << index.second; - - ref.mCell = stream.str(); } 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 91fa556ab..f4ae78ae7 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 bd4cf918c..c94ec1dc4 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 46572752e..82ec2f390 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 aed56f415..0f8897c48 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 e5595ccf6..5a45691d5 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 5a45691d5..1f6da2580 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 f4ae78ae7..97b34551d 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 c94ec1dc4..8f12b6844 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 + + // 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]) { - 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; + 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 82ec2f390..d031398d3 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 1f6da2580..7363f999e 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 afc4fcb96..4fe965148 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 ca7c13fea..f3d2b852a 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 5648ace54..1248e202b 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 7363f999e..d6258da6a 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 7a975c99c..6e240c998 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 5743ad761..9a654c802 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 9a654c802..2038612a2 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 eeefa9afb..6dedd6ef2 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 | 24 ++++++++++++++++++------ 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/apps/opencs/model/tools/search.cpp b/apps/opencs/model/tools/search.cpp index cb8850754..7eb531161 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 c9dfc4c44..69b98bbdb 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 2038612a2..32c26ee96 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)); - + + if (table!=currentTable) + { + search.configure (table); + currentTable = table; + } + std::string hint = model.getHint (*iter); - - mSearch.replace (mDocument, table, id, hint, replace); - mTable->flagAsReplaced (*iter); - if (autoDelete) - mTable->model()->removeRows (*iter, 1); + 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 97b34551d..fc4532fb0 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 8f12b6844..ff30dafae 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 8b4bfeaac..a11b5bdde 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 cb8142720..b36b1d8cb 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 271b0316d..991e58ae7 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 0192bc550..90fe2917e 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 | 12 +++++------ 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, 128 insertions(+), 130 deletions(-) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 7861894b0..ec2e1246e 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 4c142231d..00e6a9aa2 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 246f7ece2..5893c5d0d 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 6886732db..a6ab657fe 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 a4bb8c538..4496490d4 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 eb458be50..1f24b58d8 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 6ad4da3bf..9a737af64 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 5099fc4d6..26761f2fc 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 7859c8a7b..21fbc9a6e 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 a7c1d781b..6d86b4a23 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 71b4a560f..c50d47ef5 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 42491a5e8..aecfce98d 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 09a3c11ac..6d9c0a580 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 279c2f22e..015af0043 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 88d891a02..2e82faa6d 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 1c7451c32..a4a398d05 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 871561bdc..6dcd92b15 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 8071dd5fd..7d61e3b6c 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 79eeff2d0..49e65490d 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 0299dc493..b69222664 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 a724644a7..6a6d52e26 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 8fb1ee53c..f00ebb303 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 d591cca2e..fd439050c 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 775950431..53d54cdc9 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 a61daa5a4..7538511fe 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 bbe475ff7..2804f89d4 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 14951608d..c64678e70 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 b78d4075a..1aef97d9f 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 b1c01fcba..b0897ec67 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 9fb36d984..5e0ea6c86 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 6c5e83eeb..aee16f280 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 0d81d84b6..f4126b7a7 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 c13532644..b583429dd 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 c6f0f7136..7bc73ddda 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) - , mMinBatchSize(minBatchSize) - , mMaxBatchSize(maxBatchSize) + , mWorkQueueChannel(0) , mVisible(true) - , mMaxX(0) + , mChunksLoading(0) , mMinX(0) - , mMaxY(0) + , mMaxX(0) , mMinY(0) - , mChunksLoading(0) - , mWorkQueueChannel(0) + , mMaxY(0) + , mMinBatchSize(minBatchSize) + , mMaxBatchSize(maxBatchSize) , mLayerLoadPending(true) { #if TERRAIN_USE_SHADER == 0 diff --git a/components/terrain/quadtreenode.cpp b/components/terrain/quadtreenode.cpp index 6a9964213..89e5e34a3 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 5cc2647c6..3baaaed44 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 8517a0303..5a79de3d1 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 013ef1003..15be7665a 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 349647892..5fa284c00 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 41d8c65d5..e38554383 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 ef33f495f..c3b889df5 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 0fb449e16..e9959611b 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 6e240c998..d9db95c71 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 991e58ae7..9e0a7e95a 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 90fe2917e..3355d40c1 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 ea9dcee8c..335cb97af 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 561476577..5d85891cf 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 d9db95c71..9e00b7d1a 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 9e0a7e95a..0909c00f9 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 335cb97af..c7ddcd82a 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 5d85891cf..1c6474e54 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 0909c00f9..b4f4234f1 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 3355d40c1..a19cee486 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 c7ddcd82a..411eb3660 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 | 126 +++++++++++--------- apps/opencs/model/world/refidcollection.cpp | 4 +- apps/opencs/view/world/dialoguesubview.cpp | 5 +- 6 files changed, 89 insertions(+), 69 deletions(-) diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 3d735ddca..3172e72e4 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 0c525fd11..b87f6c53d 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 232959727..9a0401081 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 e38554383..61e8115c0 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") + 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: { - leveled.mFlags = 0x01; - break; + if(value.toBool()) + { + leveled.mFlags |= ESM::ItemLevList::Each; + break; + } + else + { + leveled.mFlags &= ~ESM::ItemLevList::Each; + break; + } } - else if(mType == CSMWorld::UniversalId::Type_ItemLevelledList && - value.toString().toStdString() == "All Levels") + case 1: { - leveled.mFlags = 0x02; - break; + if(value.toBool()) + { + leveled.mFlags |= ESM::ItemLevList::AllLevels; + break; + } + else + { + leveled.mFlags &= ~ESM::ItemLevList::AllLevels; + 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 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 4a8f398cd..1941c505a 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 cf3653c1b..0d0e82dbf 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 7c0422c88..506bdab2c 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 b4cf46040..4269679bf 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 678005082..1f854c69e 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 14034ea7f..f88b9f0b9 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 2296a8297..edc12975c 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 1e3cc00d7..e9bb04ba7 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 002a62d87..877307c29 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 239c7410f..e9d644f61 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 198c3627f..be9663e7a 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 fbc942f8e..e496fe79b 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 e430bfa5e..5636fff94 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 582ccea64..e3e5ce50e 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"),