From 518cb0e3b7a181462bb7044ae966a9bcf18659c1 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 16 Apr 2013 12:12:04 +0200 Subject: [PATCH 01/39] added another abstraction layer to ID access in IdCollection --- apps/opencs/model/world/idcollection.hpp | 123 +++++++++++++---------- 1 file changed, 72 insertions(+), 51 deletions(-) diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index 4afe9cbaa..7052b300e 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -79,8 +79,29 @@ namespace CSMWorld virtual void load (ESM::ESMReader& reader, bool base) = 0; }; - ///< \brief Collection of ID-based records + ///< \brief Access to ID field in records template + struct IdAccessor + { + std::string& getId (ESXRecordT& record); + + const std::string getId (const ESXRecordT& record) const; + }; + + template + std::string& IdAccessor::getId (ESXRecordT& record) + { + return record.mId; + } + + template + const std::string IdAccessor::getId (const ESXRecordT& record) const + { + return record.mId; + } + + ///< \brief Collection of ID-based records + template > class IdCollection : public IdCollectionBase { std::vector > mRecords; @@ -150,21 +171,21 @@ namespace CSMWorld void addColumn (Column *column); }; - template - IdCollection::IdCollection() + template + IdCollection::IdCollection() {} - template - IdCollection::~IdCollection() + template + IdCollection::~IdCollection() { for (typename std::vector *>::iterator iter (mColumns.begin()); iter!=mColumns.end(); ++iter) delete *iter; } - template - void IdCollection::add (const ESXRecordT& record) + template + void IdCollection::add (const ESXRecordT& record) { - std::string id = Misc::StringUtils::lowerCase(record.mId); + std::string id = Misc::StringUtils::lowerCase (IdAccessorT().getId (record)); std::map::iterator iter = mIndex.find (id); @@ -183,20 +204,20 @@ namespace CSMWorld } } - template - int IdCollection::getSize() const + template + int IdCollection::getSize() const { return mRecords.size(); } - template - std::string IdCollection::getId (int index) const + template + std::string IdCollection::getId (int index) const { - return mRecords.at (index).get().mId; + return IdAccessorT().getId (mRecords.at (index).get()); } - template - int IdCollection::getIndex (const std::string& id) const + template + int IdCollection::getIndex (const std::string& id) const { int index = searchId (id); @@ -206,38 +227,38 @@ namespace CSMWorld return index; } - template - int IdCollection::getColumns() const + template + int IdCollection::getColumns() const { return mColumns.size(); } - template - QVariant IdCollection::getData (int index, int column) const + template + QVariant IdCollection::getData (int index, int column) const { return mColumns.at (column)->get (mRecords.at (index)); } - template - void IdCollection::setData (int index, int column, const QVariant& data) + template + void IdCollection::setData (int index, int column, const QVariant& data) { return mColumns.at (column)->set (mRecords.at (index), data); } - template - const ColumnBase& IdCollection::getColumn (int column) const + template + const ColumnBase& IdCollection::getColumn (int column) const { return *mColumns.at (column); } - template - void IdCollection::addColumn (Column *column) + template + void IdCollection::addColumn (Column *column) { mColumns.push_back (column); } - template - void IdCollection::merge() + template + void IdCollection::merge() { for (typename std::vector >::iterator iter (mRecords.begin()); iter!=mRecords.end(); ++iter) iter->merge(); @@ -245,16 +266,16 @@ namespace CSMWorld purge(); } - template - void IdCollection::purge() + template + void IdCollection::purge() { mRecords.erase (std::remove_if (mRecords.begin(), mRecords.end(), std::mem_fun_ref (&Record::isErased) // I want lambda :( ), mRecords.end()); } - template - void IdCollection::removeRows (int index, int count) + template + void IdCollection::removeRows (int index, int count) { mRecords.erase (mRecords.begin()+index, mRecords.begin()+index+count); @@ -278,17 +299,17 @@ namespace CSMWorld } } - template - void IdCollection::appendBlankRecord (const std::string& id) + template + void IdCollection::appendBlankRecord (const std::string& id) { ESXRecordT record; - record.mId = id; + IdAccessorT().getId (record) = id; record.blank(); add (record); } - template - int IdCollection::searchId (const std::string& id) const + template + int IdCollection::searchId (const std::string& id) const { std::string id2 = Misc::StringUtils::lowerCase(id); @@ -300,28 +321,28 @@ namespace CSMWorld return iter->second; } - template - void IdCollection::replace (int index, const RecordBase& record) + template + void IdCollection::replace (int index, const RecordBase& record) { mRecords.at (index) = dynamic_cast&> (record); } - template - void IdCollection::appendRecord (const RecordBase& record) + template + void IdCollection::appendRecord (const RecordBase& record) { mRecords.push_back (dynamic_cast&> (record)); mIndex.insert (std::make_pair (Misc::StringUtils::lowerCase (getId (record)), mRecords.size()-1)); } - template - std::string IdCollection::getId (const RecordBase& record) const + template + std::string IdCollection::getId (const RecordBase& record) const { const Record& record2 = dynamic_cast&> (record); - return (record2.isModified() ? record2.mModified : record2.mBase).mId; + return IdAccessorT().getId (record2.isModified() ? record2.mModified : record2.mBase); } - template - void IdCollection::load (ESM::ESMReader& reader, bool base) + template + void IdCollection::load (ESM::ESMReader& reader, bool base) { std::string id = reader.getHNOString ("NAME"); @@ -351,10 +372,10 @@ namespace CSMWorld else { ESXRecordT record; - record.mId = id; + IdAccessorT().getId (record) = id; record.load (reader); - int index = searchId (record.mId); + int index = searchId (IdAccessorT().getId (record)); if (index==-1) { @@ -378,15 +399,15 @@ namespace CSMWorld } } - template - const Record& IdCollection::getRecord (const std::string& id) const + template + const Record& IdCollection::getRecord (const std::string& id) const { int index = getIndex (id); return mRecords.at (index); } - template - const Record& IdCollection::getRecord (int index) const + template + const Record& IdCollection::getRecord (int index) const { return mRecords.at (index); } From afe7b3c64c4adafd112b4d151d8866ffefb4a725 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 23 Apr 2013 10:56:55 +0200 Subject: [PATCH 02/39] added additional type argument to IdCollection::appendBlankRecord --- apps/opencs/model/world/idcollection.hpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index 7052b300e..45b4961aa 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -16,6 +16,7 @@ #include #include "columnbase.hpp" +#include "universalid.hpp" namespace CSMWorld { @@ -53,7 +54,9 @@ namespace CSMWorld virtual void removeRows (int index, int count) = 0; - virtual void appendBlankRecord (const std::string& id) = 0; + 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 virtual int searchId (const std::string& id) const = 0; ////< Search record with \a id. @@ -143,7 +146,9 @@ namespace CSMWorld virtual void removeRows (int index, int count) ; - virtual void appendBlankRecord (const std::string& id); + virtual void appendBlankRecord (const std::string& id, + UniversalId::Type type = UniversalId::Type_None); + ///< \param type Will be ignored, unless the collection supports multiple record types virtual int searchId (const std::string& id) const; ////< Search record with \a id. @@ -300,7 +305,8 @@ namespace CSMWorld } template - void IdCollection::appendBlankRecord (const std::string& id) + void IdCollection::appendBlankRecord (const std::string& id, + UniversalId::Type type) { ESXRecordT record; IdAccessorT().getId (record) = id; From 808718d96708d9833e7a8fe959de1e8823802039 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 23 Apr 2013 11:21:21 +0200 Subject: [PATCH 03/39] added referenceable record types to UniversalId --- apps/opencs/model/world/universalid.cpp | 26 +++++++++++++++++++++++++ apps/opencs/model/world/universalid.hpp | 25 +++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/world/universalid.cpp b/apps/opencs/model/world/universalid.cpp index c0241bc38..bd1632e3e 100644 --- a/apps/opencs/model/world/universalid.cpp +++ b/apps/opencs/model/world/universalid.cpp @@ -29,6 +29,8 @@ namespace { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Birthsigns, "Birthsigns" }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Spells, "Spells" }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Cells, "Cells" }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Referenceables, + "Referenceables" }, { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker }; @@ -47,6 +49,30 @@ namespace { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Birthsign, "Birthsign" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Spell, "Spell" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell, "Cell" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Referenceable, "Referenceables" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Activator, "Activator" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Potion, "Potion" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Apparatus, "Apparatus" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Armor, "Armor" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Book, "Book" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Clothing, "Clothing" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Container, "Container" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Creature, "Creature" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Door, "Door" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Ingredient, "Ingredient" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_CreatureLevelledList, + "Creature Levelled List" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_ItemLevelledList, + "Item Levelled List" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Light, "Light" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Lockpick, "Lockpick" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Miscellaneous, + "Miscellaneous" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Npc, "NPC" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Probe, "Probe" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Repair, "Repair" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Static, "Static" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Weapon, "Weapon" }, { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker }; diff --git a/apps/opencs/model/world/universalid.hpp b/apps/opencs/model/world/universalid.hpp index 9b52aded1..2c4b14eaf 100644 --- a/apps/opencs/model/world/universalid.hpp +++ b/apps/opencs/model/world/universalid.hpp @@ -57,7 +57,30 @@ namespace CSMWorld Type_Spells, Type_Spell, Type_Cells, - Type_Cell + Type_Cell, + Type_Referenceables, + Type_Referenceable, + Type_Activator, + Type_Potion, + Type_Apparatus, + Type_Armor, + Type_Book, + Type_Clothing, + Type_Container, + Type_Creature, + Type_Door, + Type_Ingredient, + Type_CreatureLevelledList, + Type_ItemLevelledList, + Type_Light, + Type_Lockpick, + Type_Miscellaneous, + Type_Npc, + Type_Probe, + Type_Repair, + Type_Static, + Type_Weapon + }; private: From a17d17c19105557c88ff2cdcaca19df103f6fba6 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 23 Apr 2013 11:22:07 +0200 Subject: [PATCH 04/39] added additional type argument to IdCollection::load --- apps/opencs/model/world/idcollection.hpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index 45b4961aa..7761929f3 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -79,7 +79,9 @@ namespace CSMWorld virtual const RecordBase& getRecord (int index) const = 0; - virtual void load (ESM::ESMReader& reader, bool base) = 0; + virtual void load (ESM::ESMReader& reader, bool base, + UniversalId::Type type = UniversalId::Type_None) = 0; + ///< \param type Will be ignored, unless the collection supports multiple record types }; ///< \brief Access to ID field in records @@ -171,7 +173,9 @@ namespace CSMWorld virtual const Record& getRecord (int index) const; - virtual void load (ESM::ESMReader& reader, bool base); + virtual void load (ESM::ESMReader& reader, bool base, + UniversalId::Type type = UniversalId::Type_None); + ///< \param type Will be ignored, unless the collection supports multiple record types void addColumn (Column *column); }; @@ -348,7 +352,8 @@ namespace CSMWorld } template - void IdCollection::load (ESM::ESMReader& reader, bool base) + void IdCollection::load (ESM::ESMReader& reader, bool base, + UniversalId::Type type) { std::string id = reader.getHNOString ("NAME"); From e7bf1d230ccf6ec08e01b5ef813d0b98adbc2dc9 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 27 Apr 2013 16:22:04 +0200 Subject: [PATCH 05/39] fixed an indexing problem in IdCollection --- apps/opencs/model/world/idcollection.hpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index 7761929f3..e65f11cef 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -278,9 +278,15 @@ namespace CSMWorld template void IdCollection::purge() { - mRecords.erase (std::remove_if (mRecords.begin(), mRecords.end(), - std::mem_fun_ref (&Record::isErased) // I want lambda :( - ), mRecords.end()); + int i = 0; + + while (i (mRecords.size())) + { + if (mRecords[i].isErased()) + removeRows (i, 1); + else + ++i; + } } template From 236751ec451495f2b1161ef0d5324f15a6a3e39c Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 29 Apr 2013 17:52:01 +0200 Subject: [PATCH 06/39] some IdCollection and IdTable cleanup --- apps/opencs/model/world/commands.cpp | 4 +-- apps/opencs/model/world/idcollection.hpp | 44 +++++++++++++----------- apps/opencs/model/world/idtable.cpp | 8 ++--- apps/opencs/model/world/idtable.hpp | 2 +- 4 files changed, 30 insertions(+), 28 deletions(-) diff --git a/apps/opencs/model/world/commands.cpp b/apps/opencs/model/world/commands.cpp index 1f8660bdd..eaded5b70 100644 --- a/apps/opencs/model/world/commands.cpp +++ b/apps/opencs/model/world/commands.cpp @@ -71,7 +71,7 @@ void CSMWorld::RevertCommand::redo() void CSMWorld::RevertCommand::undo() { - mModel.setRecord (*mOld); + mModel.setRecord (mId, *mOld); } CSMWorld::DeleteCommand::DeleteCommand (IdTable& model, const std::string& id, QUndoCommand *parent) @@ -104,5 +104,5 @@ void CSMWorld::DeleteCommand::redo() void CSMWorld::DeleteCommand::undo() { - mModel.setRecord (*mOld); + mModel.setRecord (mId, *mOld); } \ No newline at end of file diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index e65f11cef..9ace34a09 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -66,15 +66,12 @@ namespace CSMWorld ///< If the record type does not match, an exception is thrown. /// /// \attention \a record must not change the ID. + ///< \param type Will be ignored, unless the collection supports multiple record types - virtual void appendRecord (const RecordBase& record) = 0; + virtual void appendRecord (const RecordBase& record, + UniversalId::Type type = UniversalId::Type_None) = 0; ///< If the record type does not match, an exception is thrown. - virtual std::string getId (const RecordBase& record) const = 0; - ///< Return ID for \a record. - /// - /// \attention Throws an exception, if the type of \a record does not match. - virtual const RecordBase& getRecord (const std::string& id) const = 0; virtual const RecordBase& getRecord (int index) const = 0; @@ -82,6 +79,9 @@ namespace CSMWorld virtual void load (ESM::ESMReader& reader, bool base, UniversalId::Type type = UniversalId::Type_None) = 0; ///< \param type Will be ignored, unless the collection supports multiple record types + + virtual int getAppendIndex (UniversalId::Type type = UniversalId::Type_None) const = 0; + ///< \param type Will be ignored, unless the collection supports multiple record types }; ///< \brief Access to ID field in records @@ -161,13 +161,10 @@ namespace CSMWorld /// /// \attention \a record must not change the ID. - virtual void appendRecord (const RecordBase& record); + virtual void appendRecord (const RecordBase& record, + UniversalId::Type type = UniversalId::Type_None); ///< If the record type does not match, an exception is thrown. - - virtual std::string getId (const RecordBase& record) const; - ///< Return ID for \a record. - /// - /// \attention Throw san exception, if the type of \a record does not match. + ///< \param type Will be ignored, unless the collection supports multiple record types virtual const Record& getRecord (const std::string& id) const; @@ -177,6 +174,9 @@ namespace CSMWorld UniversalId::Type type = UniversalId::Type_None); ///< \param type Will be ignored, unless the collection supports multiple record types + virtual int getAppendIndex (UniversalId::Type type = UniversalId::Type_None) const; + ///< \param type Will be ignored, unless the collection supports multiple record types + void addColumn (Column *column); }; @@ -344,17 +344,13 @@ namespace CSMWorld } template - void IdCollection::appendRecord (const RecordBase& record) + void IdCollection::appendRecord (const RecordBase& record, + UniversalId::Type type) { mRecords.push_back (dynamic_cast&> (record)); - mIndex.insert (std::make_pair (Misc::StringUtils::lowerCase (getId (record)), mRecords.size()-1)); - } - - template - std::string IdCollection::getId (const RecordBase& record) const - { - const Record& record2 = dynamic_cast&> (record); - return IdAccessorT().getId (record2.isModified() ? record2.mModified : record2.mBase); + mIndex.insert (std::make_pair (Misc::StringUtils::lowerCase (IdAccessorT().getId ( + dynamic_cast (record))), + mRecords.size()-1)); } template @@ -416,6 +412,12 @@ namespace CSMWorld } } + template + int IdCollection::getAppendIndex (UniversalId::Type type) const + { + return static_cast (mRecords.size()); + } + template const Record& IdCollection::getRecord (const std::string& id) const { diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index 79e33584b..386ca8702 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -117,7 +117,7 @@ QModelIndex CSMWorld::IdTable::parent (const QModelIndex& index) const void CSMWorld::IdTable::addRecord (const std::string& id) { - int index = mIdCollection->getSize(); + int index = mIdCollection->getAppendIndex(); beginInsertRows (QModelIndex(), index, index); @@ -131,13 +131,13 @@ QModelIndex CSMWorld::IdTable::getModelIndex (const std::string& id, int column) return index (mIdCollection->getIndex (id), column); } -void CSMWorld::IdTable::setRecord (const RecordBase& record) +void CSMWorld::IdTable::setRecord (const std::string& id, const RecordBase& record) { - int index = mIdCollection->searchId (mIdCollection->getId (record)); + int index = mIdCollection->searchId (id); if (index==-1) { - int index = mIdCollection->getSize(); + int index = mIdCollection->getAppendIndex(); beginInsertRows (QModelIndex(), index, index); diff --git a/apps/opencs/model/world/idtable.hpp b/apps/opencs/model/world/idtable.hpp index 80476c524..de0dde56e 100644 --- a/apps/opencs/model/world/idtable.hpp +++ b/apps/opencs/model/world/idtable.hpp @@ -48,7 +48,7 @@ namespace CSMWorld QModelIndex getModelIndex (const std::string& id, int column) const; - void setRecord (const RecordBase& record); + void setRecord (const std::string& id, const RecordBase& record); ///< Add record or overwrite existing recrod. const RecordBase& getRecord (const std::string& id) const; From f8a331f1738a58667db2af0f81dd0a6c3ed0d30f Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 1 May 2013 16:49:34 +0200 Subject: [PATCH 07/39] fixed a bad cast --- apps/opencs/model/world/idcollection.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index 9ace34a09..93390c97b 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -349,7 +349,7 @@ namespace CSMWorld { mRecords.push_back (dynamic_cast&> (record)); mIndex.insert (std::make_pair (Misc::StringUtils::lowerCase (IdAccessorT().getId ( - dynamic_cast (record))), + dynamic_cast&> (record).get())), mRecords.size()-1)); } From 1b84aeb5b9e67493a3fe0f0984695ba6ccbbeb20 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 2 May 2013 14:30:39 +0200 Subject: [PATCH 08/39] fixed a problem with editing records that do not exist in base --- apps/opencs/model/world/record.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/world/record.hpp b/apps/opencs/model/world/record.hpp index c8f728e7d..4d95b5c91 100644 --- a/apps/opencs/model/world/record.hpp +++ b/apps/opencs/model/world/record.hpp @@ -81,7 +81,9 @@ namespace CSMWorld throw std::logic_error ("attempt to modify a deleted record"); mModified = modified; - mState = State_Modified; + + if (mState!=State_ModifiedOnly) + mState = State_Modified; } template From 13e7abd7df0a3e54349a4c8d7e9b4fa2bc447bc3 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 3 May 2013 12:52:45 +0200 Subject: [PATCH 09/39] added assign function to Record class --- apps/opencs/model/world/record.hpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/apps/opencs/model/world/record.hpp b/apps/opencs/model/world/record.hpp index 4d95b5c91..853ed1559 100644 --- a/apps/opencs/model/world/record.hpp +++ b/apps/opencs/model/world/record.hpp @@ -22,6 +22,9 @@ namespace CSMWorld virtual RecordBase *clone() const = 0; + virtual void assign (const RecordBase& record) = 0; + ///< Will throw an exception if the types don't match. + bool isDeleted() const; bool isErased() const; @@ -37,6 +40,8 @@ namespace CSMWorld virtual RecordBase *clone() const; + virtual void assign (const RecordBase& record); + const ESXRecordT& get() const; ///< Throws an exception, if the record is deleted. @@ -56,6 +61,12 @@ namespace CSMWorld return new Record (*this); } + template + void Record::assign (const RecordBase& record) + { + *this = dynamic_cast& > (record); + } + template const ESXRecordT& Record::get() const { From b21dae8d75d7d5f6d625455401d786b102b4dd28 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 6 May 2013 14:10:43 +0200 Subject: [PATCH 10/39] added blank function to all referencable record structs --- components/esm/aipackage.cpp | 6 ++++ components/esm/aipackage.hpp | 3 ++ components/esm/loadacti.cpp | 7 +++++ components/esm/loadacti.hpp | 3 ++ components/esm/loadalch.cpp | 12 ++++++++ components/esm/loadalch.hpp | 4 +++ components/esm/loadappa.cpp | 12 ++++++++ components/esm/loadappa.hpp | 3 ++ components/esm/loadarmo.cpp | 15 ++++++++++ components/esm/loadarmo.hpp | 3 ++ components/esm/loadbook.cpp | 14 +++++++++ components/esm/loadbook.hpp | 3 ++ components/esm/loadclot.cpp | 20 +++++++++++-- components/esm/loadclot.hpp | 3 ++ components/esm/loadcont.cpp | 9 ++++++ components/esm/loadcont.hpp | 3 ++ components/esm/loadcrea.cpp | 24 +++++++++++++++ components/esm/loadcrea.hpp | 3 ++ components/esm/loaddoor.cpp | 8 +++++ components/esm/loaddoor.hpp | 3 ++ components/esm/loadingr.cpp | 18 ++++++++++- components/esm/loadingr.hpp | 3 ++ components/esm/loadlevlist.cpp | 8 ++++- components/esm/loadlevlist.hpp | 5 +++- components/esm/loadligh.cpp | 14 +++++++++ components/esm/loadligh.hpp | 3 ++ components/esm/loadlock.cpp | 14 +++++++-- components/esm/loadlock.hpp | 3 ++ components/esm/loadmisc.cpp | 10 +++++++ components/esm/loadmisc.hpp | 3 ++ components/esm/loadnpc.cpp | 55 ++++++++++++++++++++++++++++++++-- components/esm/loadnpc.hpp | 15 ++++------ components/esm/loadprob.cpp | 13 +++++++- components/esm/loadprob.hpp | 3 ++ components/esm/loadrepa.cpp | 12 +++++++- components/esm/loadrepa.hpp | 3 ++ components/esm/loadstat.cpp | 4 +++ components/esm/loadstat.hpp | 3 ++ components/esm/loadweap.cpp | 20 +++++++++++++ components/esm/loadweap.hpp | 3 ++ 40 files changed, 347 insertions(+), 23 deletions(-) diff --git a/components/esm/aipackage.cpp b/components/esm/aipackage.cpp index 1e6220c3a..1440dbd13 100644 --- a/components/esm/aipackage.cpp +++ b/components/esm/aipackage.cpp @@ -5,6 +5,12 @@ namespace ESM { + void AIData::blank() + { + mHello = mU1 = mFight = mFlee = mAlarm = mU2 = mU3 = mU4 = 0; + mServices = 0; + } + void AIPackageList::load(ESMReader &esm) { while (esm.hasMoreSubs()) { diff --git a/components/esm/aipackage.hpp b/components/esm/aipackage.hpp index 3128fe0c6..38499b2dd 100644 --- a/components/esm/aipackage.hpp +++ b/components/esm/aipackage.hpp @@ -19,6 +19,9 @@ namespace ESM // These are probabilities char mHello, mU1, mFight, mFlee, mAlarm, mU2, mU3, mU4; int mServices; // See the Services enum + + void blank(); + ///< Set record to default state (does not touch the ID). }; // 12 bytes struct AIWander diff --git a/components/esm/loadacti.cpp b/components/esm/loadacti.cpp index 0e214e2b6..fd022af7e 100644 --- a/components/esm/loadacti.cpp +++ b/components/esm/loadacti.cpp @@ -17,4 +17,11 @@ void Activator::save(ESMWriter &esm) esm.writeHNCString("FNAM", mName); esm.writeHNOCString("SCRI", mScript); } + + void Activator::blank() + { + mName.clear(); + mScript.clear(); + mModel.clear(); + } } diff --git a/components/esm/loadacti.hpp b/components/esm/loadacti.hpp index 8cb335feb..a62990590 100644 --- a/components/esm/loadacti.hpp +++ b/components/esm/loadacti.hpp @@ -15,6 +15,9 @@ struct Activator void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } diff --git a/components/esm/loadalch.cpp b/components/esm/loadalch.cpp index a4b1bb718..dbb69c066 100644 --- a/components/esm/loadalch.cpp +++ b/components/esm/loadalch.cpp @@ -23,4 +23,16 @@ void Potion::save(ESMWriter &esm) esm.writeHNT("ALDT", mData, 12); mEffects.save(esm); } + + void Potion::blank() + { + mData.mWeight = 0; + mData.mValue = 0; + mData.mAutoCalc = 0; + mName.clear(); + mModel.clear(); + mIcon.clear(); + mScript.clear(); + mEffects.mList.clear(); + } } diff --git a/components/esm/loadalch.hpp b/components/esm/loadalch.hpp index 1e571ac40..3ede85342 100644 --- a/components/esm/loadalch.hpp +++ b/components/esm/loadalch.hpp @@ -30,6 +30,10 @@ struct Potion void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). + }; } #endif diff --git a/components/esm/loadappa.cpp b/components/esm/loadappa.cpp index 643fefda5..4b8d2b763 100644 --- a/components/esm/loadappa.cpp +++ b/components/esm/loadappa.cpp @@ -36,4 +36,16 @@ void Apparatus::save(ESMWriter &esm) esm.writeHNOCString("SCRI", mScript); esm.writeHNCString("ITEX", mIcon); } + + void Apparatus::blank() + { + mData.mType = 0; + mData.mQuality = 0; + mData.mWeight = 0; + mData.mValue = 0; + mModel.clear(); + mIcon.clear(); + mScript.clear(); + mName.clear(); + } } diff --git a/components/esm/loadappa.hpp b/components/esm/loadappa.hpp index 486a559f8..ed9d335be 100644 --- a/components/esm/loadappa.hpp +++ b/components/esm/loadappa.hpp @@ -36,6 +36,9 @@ struct Apparatus void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } #endif diff --git a/components/esm/loadarmo.cpp b/components/esm/loadarmo.cpp index 613346533..e64c8705d 100644 --- a/components/esm/loadarmo.cpp +++ b/components/esm/loadarmo.cpp @@ -50,4 +50,19 @@ void Armor::save(ESMWriter &esm) esm.writeHNOCString("ENAM", mEnchant); } + void Armor::blank() + { + mData.mType = 0; + mData.mWeight = 0; + mData.mValue = 0; + mData.mHealth = 0; + mData.mEnchant = 0; + mData.mArmor = 0; + mParts.mParts.clear(); + mName.clear(); + mModel.clear(); + mIcon.clear(); + mScript.clear(); + mEnchant.clear(); + } } diff --git a/components/esm/loadarmo.hpp b/components/esm/loadarmo.hpp index c18b4486d..eaef42be8 100644 --- a/components/esm/loadarmo.hpp +++ b/components/esm/loadarmo.hpp @@ -90,6 +90,9 @@ struct Armor void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } #endif diff --git a/components/esm/loadbook.cpp b/components/esm/loadbook.cpp index 8ed2f122a..3a70ac786 100644 --- a/components/esm/loadbook.cpp +++ b/components/esm/loadbook.cpp @@ -27,4 +27,18 @@ void Book::save(ESMWriter &esm) esm.writeHNOCString("ENAM", mEnchant); } + void Book::blank() + { + mData.mWeight = 0; + mData.mValue = 0; + mData.mIsScroll = 0; + mData.mSkillID = 0; + mData.mEnchant = 0; + mName.clear(); + mModel.clear(); + mIcon.clear(); + mScript.clear(); + mEnchant.clear(); + mText.clear(); + } } diff --git a/components/esm/loadbook.hpp b/components/esm/loadbook.hpp index 22201abed..68042e246 100644 --- a/components/esm/loadbook.hpp +++ b/components/esm/loadbook.hpp @@ -26,6 +26,9 @@ struct Book void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } #endif diff --git a/components/esm/loadclot.cpp b/components/esm/loadclot.cpp index a37fbe8a4..10b00970f 100644 --- a/components/esm/loadclot.cpp +++ b/components/esm/loadclot.cpp @@ -16,7 +16,7 @@ void Clothing::load(ESMReader &esm) mIcon = esm.getHNOString("ITEX"); mParts.load(esm); - + mEnchant = esm.getHNOString("ENAM"); } @@ -28,10 +28,24 @@ void Clothing::save(ESMWriter &esm) esm.writeHNOCString("SCRI", mScript); esm.writeHNOCString("ITEX", mIcon); - + mParts.save(esm); - + esm.writeHNOCString("ENAM", mEnchant); } + void Clothing::blank() + { + mData.mType = 0; + mData.mWeight = 0; + mData.mValue = 0; + mData.mEnchant = 0; + mParts.mParts.clear(); + mName.clear(); + mModel.clear(); + mIcon.clear(); + mIcon.clear(); + mEnchant.clear(); + mScript.clear(); + } } diff --git a/components/esm/loadclot.hpp b/components/esm/loadclot.hpp index 623983ccf..816d03cb2 100644 --- a/components/esm/loadclot.hpp +++ b/components/esm/loadclot.hpp @@ -46,6 +46,9 @@ struct Clothing void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } #endif diff --git a/components/esm/loadcont.cpp b/components/esm/loadcont.cpp index e6ba91e7c..853c8bd50 100644 --- a/components/esm/loadcont.cpp +++ b/components/esm/loadcont.cpp @@ -53,4 +53,13 @@ void Container::save(ESMWriter &esm) mInventory.save(esm); } + void Container::blank() + { + mName.clear(); + mModel.clear(); + mScript.clear(); + mWeight = 0; + mFlags = 0; + mInventory.mList.clear(); + } } diff --git a/components/esm/loadcont.hpp b/components/esm/loadcont.hpp index b66ca086d..b2bbab73d 100644 --- a/components/esm/loadcont.hpp +++ b/components/esm/loadcont.hpp @@ -47,6 +47,9 @@ struct Container void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } #endif diff --git a/components/esm/loadcrea.cpp b/components/esm/loadcrea.cpp index b59835bd6..3698d4117 100644 --- a/components/esm/loadcrea.cpp +++ b/components/esm/loadcrea.cpp @@ -53,4 +53,28 @@ void Creature::save(ESMWriter &esm) mAiPackage.save(esm); } + void Creature::blank() + { + mData.mType = 0; + mData.mLevel = 0; + mData.mStrength = mData.mIntelligence = mData.mWillpower = mData.mAgility = + mData.mSpeed = mData.mEndurance = mData.mPersonality = mData.mLuck = 0; + mData.mHealth = mData.mMana = mData.mFatigue = 0; + mData.mSoul = 0; + mData.mCombat = mData.mMagic = mData.mStealth = 0; + for (int i=0; i<6; ++i) mData.mAttack[i] = 0; + mData.mGold = 0; + mFlags = 0; + mScale = 0; + mModel.clear(); + mName.clear(); + mScript.clear(); + mOriginal.clear(); + mInventory.mList.clear(); + mSpells.mList.clear(); + mHasAI = false; + mAiData.blank(); + mAiData.mServices = 0; + mAiPackage.mList.clear(); + } } diff --git a/components/esm/loadcrea.hpp b/components/esm/loadcrea.hpp index 1c93d995a..a97f2e0a6 100644 --- a/components/esm/loadcrea.hpp +++ b/components/esm/loadcrea.hpp @@ -84,6 +84,9 @@ struct Creature void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } diff --git a/components/esm/loaddoor.cpp b/components/esm/loaddoor.cpp index b8ef029c5..a4c7b7d58 100644 --- a/components/esm/loaddoor.cpp +++ b/components/esm/loaddoor.cpp @@ -24,4 +24,12 @@ void Door::save(ESMWriter &esm) esm.writeHNOCString("ANAM", mCloseSound); } + void Door::blank() + { + mName.clear(); + mModel.clear(); + mScript.clear(); + mOpenSound.clear(); + mCloseSound.clear(); + } } diff --git a/components/esm/loaddoor.hpp b/components/esm/loaddoor.hpp index e992a592f..77ffc6489 100644 --- a/components/esm/loaddoor.hpp +++ b/components/esm/loaddoor.hpp @@ -15,6 +15,9 @@ struct Door void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } #endif diff --git a/components/esm/loadingr.cpp b/components/esm/loadingr.cpp index 4312dc05b..7e31a4116 100644 --- a/components/esm/loadingr.cpp +++ b/components/esm/loadingr.cpp @@ -24,7 +24,7 @@ void Ingredient::load(ESMReader &esm) { mData.mAttributes[i] = -1; } - + // is this relevant in cycle from 0 to 4? if (mData.mEffectID[i] != 89 && mData.mEffectID[i] != 26 && @@ -46,4 +46,20 @@ void Ingredient::save(ESMWriter &esm) esm.writeHNOCString("ITEX", mIcon); } + void Ingredient::blank() + { + mData.mWeight = 0; + mData.mValue = 0; + for (int i=0; i<4; ++i) + { + mData.mEffectID[i] = 0; + mData.mSkills[i] = 0; + mData.mAttributes[i] = 0; + } + + mName.clear(); + mModel.clear(); + mIcon.clear(); + mScript.clear(); + } } diff --git a/components/esm/loadingr.hpp b/components/esm/loadingr.hpp index cd63cf39a..5e286535f 100644 --- a/components/esm/loadingr.hpp +++ b/components/esm/loadingr.hpp @@ -29,6 +29,9 @@ struct Ingredient void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } #endif diff --git a/components/esm/loadlevlist.cpp b/components/esm/loadlevlist.cpp index 4cba1119b..b54a91276 100644 --- a/components/esm/loadlevlist.cpp +++ b/components/esm/loadlevlist.cpp @@ -38,7 +38,7 @@ void LeveledListBase::save(ESMWriter &esm) esm.writeHNT("DATA", mFlags); esm.writeHNT("NNAM", mChanceNone); esm.writeHNT("INDX", mList.size()); - + for (std::vector::iterator it = mList.begin(); it != mList.end(); ++it) { esm.writeHNCString(mRecName, it->mId); @@ -46,4 +46,10 @@ void LeveledListBase::save(ESMWriter &esm) } } + void LeveledListBase::blank() + { + mFlags = 0; + mChanceNone = 0; + mList.clear(); + } } diff --git a/components/esm/loadlevlist.hpp b/components/esm/loadlevlist.hpp index aa9656d72..7339cac56 100644 --- a/components/esm/loadlevlist.hpp +++ b/components/esm/loadlevlist.hpp @@ -15,7 +15,7 @@ class ESMWriter; * to implement it once. * * We should later implement the ability to merge leveled lists from - * several files. + * several files. */ struct LeveledListBase @@ -52,6 +52,9 @@ struct LeveledListBase void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; struct CreatureLevList: LeveledListBase diff --git a/components/esm/loadligh.cpp b/components/esm/loadligh.cpp index 48a56db3c..89a2b8c65 100644 --- a/components/esm/loadligh.cpp +++ b/components/esm/loadligh.cpp @@ -26,4 +26,18 @@ void Light::save(ESMWriter &esm) esm.writeHNOCString("SNAM", mSound); } + void Light::blank() + { + mData.mWeight = 0; + mData.mValue = 0; + mData.mTime = 0; + mData.mRadius = 0; + mData.mColor = 0; + mData.mFlags = 0; + mSound.clear(); + mScript.clear(); + mModel.clear(); + mIcon.clear(); + mName.clear(); + } } diff --git a/components/esm/loadligh.hpp b/components/esm/loadligh.hpp index b3d703cc2..3f0b76d6e 100644 --- a/components/esm/loadligh.hpp +++ b/components/esm/loadligh.hpp @@ -45,6 +45,9 @@ struct Light void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } #endif diff --git a/components/esm/loadlock.cpp b/components/esm/loadlock.cpp index 02a36abfe..03eac52bd 100644 --- a/components/esm/loadlock.cpp +++ b/components/esm/loadlock.cpp @@ -21,11 +21,21 @@ void Lockpick::save(ESMWriter &esm) { esm.writeHNCString("MODL", mModel); esm.writeHNCString("FNAM", mName); - + esm.writeHNT("LKDT", mData, 16); esm.writeHNOString("SCRI", mScript); esm.writeHNOCString("ITEX", mIcon); } - + void Lockpick::blank() + { + mData.mWeight = 0; + mData.mValue = 0; + mData.mQuality = 0; + mData.mUses = 0; + mName.clear(); + mModel.clear(); + mIcon.clear(); + mScript.clear(); + } } diff --git a/components/esm/loadlock.hpp b/components/esm/loadlock.hpp index 0bbedf362..953066cb2 100644 --- a/components/esm/loadlock.hpp +++ b/components/esm/loadlock.hpp @@ -25,6 +25,9 @@ struct Lockpick void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } diff --git a/components/esm/loadmisc.cpp b/components/esm/loadmisc.cpp index 3a5dded15..6006334ea 100644 --- a/components/esm/loadmisc.cpp +++ b/components/esm/loadmisc.cpp @@ -23,4 +23,14 @@ void Miscellaneous::save(ESMWriter &esm) esm.writeHNOCString("ITEX", mIcon); } + void Miscellaneous::blank() + { + mData.mWeight = 0; + mData.mValue = 0; + mData.mIsKey = 0; + mName.clear(); + mModel.clear(); + mIcon.clear(); + mScript.clear(); + } } diff --git a/components/esm/loadmisc.hpp b/components/esm/loadmisc.hpp index 26d25139c..25a9c5865 100644 --- a/components/esm/loadmisc.hpp +++ b/components/esm/loadmisc.hpp @@ -30,6 +30,9 @@ struct Miscellaneous void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } #endif diff --git a/components/esm/loadnpc.cpp b/components/esm/loadnpc.cpp index 72d0b3736..3b53a20e5 100644 --- a/components/esm/loadnpc.cpp +++ b/components/esm/loadnpc.cpp @@ -56,7 +56,7 @@ void NPC::load(ESMReader &esm) mTransport.push_back(dodt); } else if (esm.retSubName() == 0x4d414e44) { // DNAM struct mTransport.back().mCellName = esm.getHString(); - } + } } mAiPackage.load(esm); esm.skipRecord(); @@ -71,14 +71,14 @@ void NPC::save(ESMWriter &esm) esm.writeHNCString("BNAM", mHead); esm.writeHNCString("KNAM", mHair); esm.writeHNOCString("SCRI", mScript); - + if (mNpdtType == 52) esm.writeHNT("NPDT", mNpdt52, 52); else if (mNpdtType == 12) esm.writeHNT("NPDT", mNpdt12, 12); esm.writeHNT("FLAG", mFlags); - + mInventory.save(esm); mSpells.save(esm); if (mHasAI) { @@ -93,4 +93,53 @@ void NPC::save(ESMWriter &esm) mAiPackage.save(esm); } + bool NPC::isMale() const { + return (mFlags & Female) == 0; + } + + void NPC::setIsMale(bool value) { + mFlags |= Female; + if (value) { + mFlags ^= Female; + } + } + + void NPC::blank() + { + mNpdtType = 0; + mNpdt52.mLevel = 0; + mNpdt52.mStrength = mNpdt52.mIntelligence = mNpdt52.mWillpower = mNpdt52.mAgility = + mNpdt52.mSpeed = mNpdt52.mEndurance = mNpdt52.mPersonality = mNpdt52.mLuck = 0; + for (int i=0; i<27; ++i) mNpdt52.mSkills[i] = 0; + mNpdt52.mReputation = 0; + mNpdt52.mHealth = mNpdt52.mMana = mNpdt52.mFatigue = 0; + mNpdt52.mDisposition = 0; + mNpdt52.mFactionID = 0; + mNpdt52.mRank = 0; + mNpdt52.mUnknown = 0; + mNpdt52.mGold = 0; + mNpdt12.mLevel = 0; + mNpdt12.mDisposition = 0; + mNpdt12.mReputation = 0; + mNpdt12.mRank = 0; + mNpdt12.mUnknown1 = 0; + mNpdt12.mUnknown2 = 0; + mNpdt12.mUnknown3 = 0; + mNpdt12.mGold = 0; + mFlags = 0; + mInventory.mList.clear(); + mSpells.mList.clear(); + mAiData.blank(); + mHasAI = false; + mTransport.clear(); + mAiPackage.mList.clear(); + mName.clear(); + mModel.clear(); + mRace.clear(); + mClass.clear(); + mFaction.clear(); + mScript.clear(); + mHair.clear(); + mHead.clear(); + } } diff --git a/components/esm/loadnpc.hpp b/components/esm/loadnpc.hpp index b30077f23..30a525565 100644 --- a/components/esm/loadnpc.hpp +++ b/components/esm/loadnpc.hpp @@ -114,20 +114,15 @@ struct NPC // body parts std::string mHair, mHead; - // Implementation moved to load_impl.cpp void load(ESMReader &esm); void save(ESMWriter &esm); - bool isMale() const { - return (mFlags & Female) == 0; - } + bool isMale() const; - void setIsMale(bool value) { - mFlags |= Female; - if (value) { - mFlags ^= Female; - } - } + void setIsMale(bool value); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } #endif diff --git a/components/esm/loadprob.cpp b/components/esm/loadprob.cpp index bbaec1ce2..729f8404e 100644 --- a/components/esm/loadprob.cpp +++ b/components/esm/loadprob.cpp @@ -21,10 +21,21 @@ void Probe::save(ESMWriter &esm) { esm.writeHNCString("MODL", mModel); esm.writeHNCString("FNAM", mName); - + esm.writeHNT("PBDT", mData, 16); esm.writeHNOString("SCRI", mScript); esm.writeHNOCString("ITEX", mIcon); } + void Probe::blank() + { + mData.mWeight = 0; + mData.mValue = 0; + mData.mQuality = 0; + mData.mUses = 0; + mName.clear(); + mModel.clear(); + mIcon.clear(); + mScript.clear(); + } } diff --git a/components/esm/loadprob.hpp b/components/esm/loadprob.hpp index 4a47a8600..55b896bcd 100644 --- a/components/esm/loadprob.hpp +++ b/components/esm/loadprob.hpp @@ -25,6 +25,9 @@ struct Probe void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } diff --git a/components/esm/loadrepa.cpp b/components/esm/loadrepa.cpp index f7eeddf96..ced6daa2e 100644 --- a/components/esm/loadrepa.cpp +++ b/components/esm/loadrepa.cpp @@ -27,5 +27,15 @@ void Repair::save(ESMWriter &esm) esm.writeHNOCString("ITEX", mIcon); } - + void Repair::blank() + { + mData.mWeight = 0; + mData.mValue = 0; + mData.mQuality = 0; + mData.mUses = 0; + mName.clear(); + mModel.clear(); + mIcon.clear(); + mScript.clear(); + } } diff --git a/components/esm/loadrepa.hpp b/components/esm/loadrepa.hpp index 60ff5df90..83812bad9 100644 --- a/components/esm/loadrepa.hpp +++ b/components/esm/loadrepa.hpp @@ -25,6 +25,9 @@ struct Repair void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } diff --git a/components/esm/loadstat.cpp b/components/esm/loadstat.cpp index 92c9ebc71..c9346dafc 100644 --- a/components/esm/loadstat.cpp +++ b/components/esm/loadstat.cpp @@ -15,4 +15,8 @@ void Static::save(ESMWriter &esm) esm.writeHNCString("MODL", mModel); } + void Static::blank() + { + mModel.clear(); + } } diff --git a/components/esm/loadstat.hpp b/components/esm/loadstat.hpp index 790a71147..1adb7d05b 100644 --- a/components/esm/loadstat.hpp +++ b/components/esm/loadstat.hpp @@ -26,6 +26,9 @@ struct Static void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } #endif diff --git a/components/esm/loadweap.cpp b/components/esm/loadweap.cpp index 18d37e56c..253712396 100644 --- a/components/esm/loadweap.cpp +++ b/components/esm/loadweap.cpp @@ -25,4 +25,24 @@ void Weapon::save(ESMWriter &esm) esm.writeHNOCString("ENAM", mEnchant); } + void Weapon::blank() + { + mData.mWeight = 0; + mData.mValue = 0; + mData.mType = 0; + mData.mHealth = 0; + mData.mSpeed = 0; + mData.mReach = 0; + mData.mEnchant = 0; + mData.mChop[0] = mData.mChop[1] = 0; + mData.mSlash[0] = mData.mSlash[1] = 0; + mData.mThrust[0] = mData.mThrust[1] = 0; + mData.mFlags = 0; + + mName.clear(); + mModel.clear(); + mIcon.clear(); + mEnchant.clear(); + mScript.clear(); + } } diff --git a/components/esm/loadweap.hpp b/components/esm/loadweap.hpp index e482d3b10..60535ee2e 100644 --- a/components/esm/loadweap.hpp +++ b/components/esm/loadweap.hpp @@ -60,6 +60,9 @@ struct Weapon void load(ESMReader &esm); void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; } #endif From e9f1aac7bde34c61cc4199ea0a41048af2c68c76 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 6 May 2013 14:11:55 +0200 Subject: [PATCH 11/39] added data structures for referenceable records --- apps/opencs/CMakeLists.txt | 3 +- apps/opencs/model/world/refidadapter.cpp | 6 + apps/opencs/model/world/refidadapter.hpp | 36 ++++ apps/opencs/model/world/refidcollection.cpp | 202 ++++++++++++++++++++ apps/opencs/model/world/refidcollection.hpp | 95 +++++++++ apps/opencs/model/world/refiddata.cpp | 198 +++++++++++++++++++ apps/opencs/model/world/refiddata.hpp | 188 ++++++++++++++++++ 7 files changed, 727 insertions(+), 1 deletion(-) create mode 100644 apps/opencs/model/world/refidadapter.cpp create mode 100644 apps/opencs/model/world/refidadapter.hpp create mode 100644 apps/opencs/model/world/refidcollection.cpp create mode 100644 apps/opencs/model/world/refidcollection.hpp create mode 100644 apps/opencs/model/world/refiddata.cpp create mode 100644 apps/opencs/model/world/refiddata.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index efc3551fd..102b34890 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -22,7 +22,8 @@ opencs_units (model/world opencs_units_noqt (model/world - universalid data record idcollection commands columnbase scriptcontext cell + universalid data record idcollection commands columnbase scriptcontext cell refidcollection + refidadapter refiddata ) opencs_hdrs_noqt (model/world diff --git a/apps/opencs/model/world/refidadapter.cpp b/apps/opencs/model/world/refidadapter.cpp new file mode 100644 index 000000000..94ae38c3c --- /dev/null +++ b/apps/opencs/model/world/refidadapter.cpp @@ -0,0 +1,6 @@ + +#include "refidadapter.hpp" + +CSMWorld::RefIdAdapter::RefIdAdapter() {} + +CSMWorld::RefIdAdapter::~RefIdAdapter() {} \ No newline at end of file diff --git a/apps/opencs/model/world/refidadapter.hpp b/apps/opencs/model/world/refidadapter.hpp new file mode 100644 index 000000000..fa56e2836 --- /dev/null +++ b/apps/opencs/model/world/refidadapter.hpp @@ -0,0 +1,36 @@ +#ifndef CSM_WOLRD_REDIDADAPTER_H +#define CSM_WOLRD_REFIDADAPTER_H + +#include + +class QVariant; + +namespace CSMWorld +{ + class RefIdColumn; + class RefIdData; + class RecordBase; + + class RefIdAdapter + { + // not implemented + RefIdAdapter (const RefIdAdapter&); + RefIdAdapter& operator= (const RefIdAdapter&); + + public: + + RefIdAdapter(); + + virtual ~RefIdAdapter(); + + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data) const = 0; + + virtual void setData (const RefIdColumn *column, RefIdData& data, const QVariant& value) + const = 0; + ///< If the data type does not match an exception is thrown. + + virtual std::string getId (const RecordBase& record) const = 0; + }; +} + +#endif \ No newline at end of file diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp new file mode 100644 index 000000000..751d4e759 --- /dev/null +++ b/apps/opencs/model/world/refidcollection.cpp @@ -0,0 +1,202 @@ + +#include "refidcollection.hpp" + +#include + +#include "refidadapter.hpp" + +CSMWorld::RefIdColumn::RefIdColumn (const std::string& title, Display displayType, int flag, + bool editable, bool userEditable) +: ColumnBase (title, displayType, flag), mEditable (editable), mUserEditable (userEditable) +{} + +bool CSMWorld::RefIdColumn::isEditable() const +{ + return mEditable; +} + +bool CSMWorld::RefIdColumn::isUserEditable() const +{ + return mUserEditable; +} + + +const CSMWorld::RefIdAdapter& CSMWorld::RefIdCollection::findAdaptor (UniversalId::Type type) const +{ + std::map::const_iterator iter = mAdapters.find (type); + + if (iter==mAdapters.end()) + throw std::logic_error ("unsupported type in RefIdCollection"); + + return *iter->second; +} + +CSMWorld::RefIdCollection::RefIdCollection() +{ + mColumns.push_back (RefIdColumn ("ID", ColumnBase::Display_String, + ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false)); + mColumns.push_back (RefIdColumn ("*", ColumnBase::Display_Integer, + ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false)); + mColumns.push_back (RefIdColumn ("Name", ColumnBase::Display_String)); +} + +CSMWorld::RefIdCollection::~RefIdCollection() +{ + for (std::map::iterator iter (mAdapters.begin()); + iter!=mAdapters.end(); ++iter) + delete iter->second; +} + +int CSMWorld::RefIdCollection::getSize() const +{ + return mData.getSize(); +} + +std::string CSMWorld::RefIdCollection::getId (int index) const +{ + return getData (index, 0).toString().toUtf8().constData(); +} + +int CSMWorld::RefIdCollection::getIndex (const std::string& id) const +{ + int index = searchId (id); + + if (index==-1) + throw std::runtime_error ("invalid ID: " + id); + + return index; +} + +int CSMWorld::RefIdCollection::getColumns() const +{ + return mColumns.size(); +} + +const CSMWorld::ColumnBase& CSMWorld::RefIdCollection::getColumn (int column) const +{ + return mColumns.at (column); +} + +QVariant CSMWorld::RefIdCollection::getData (int index, int column) const +{ + RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (index); + + const RefIdAdapter& adaptor = findAdaptor (localIndex.second); + + return adaptor.getData (&mColumns.at (column), mData); +} + +void CSMWorld::RefIdCollection::setData (int index, int column, const QVariant& data) +{ + RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (index); + + const RefIdAdapter& adaptor = findAdaptor (localIndex.second); + + adaptor.setData (&mColumns.at (column), mData, data); +} + +void CSMWorld::RefIdCollection::removeRows (int index, int count) +{ + mData.erase (index, count); +} + +void CSMWorld::RefIdCollection::appendBlankRecord (const std::string& id, UniversalId::Type type) +{ + mData.appendRecord (type, id); +} + +int CSMWorld::RefIdCollection::searchId (const std::string& id) const +{ + return mData.localToGlobalIndex (mData.searchId (id)); +} + +void CSMWorld::RefIdCollection::replace (int index, const RecordBase& record) +{ + mData.getRecord (mData.globalToLocalIndex (index)).assign (record); +} + +void CSMWorld::RefIdCollection::appendRecord (const RecordBase& record, + UniversalId::Type type) +{ + std::string id = findAdaptor (type).getId (record); + + int index = mData.getAppendIndex (type); + + mData.appendRecord (type, id); + + mData.getRecord (mData.globalToLocalIndex (index)).assign (record); +} + +const CSMWorld::RecordBase& CSMWorld::RefIdCollection::getRecord (const std::string& id) const +{ + return mData.getRecord (mData.searchId (id)); +} + +const CSMWorld::RecordBase& CSMWorld::RefIdCollection::getRecord (int index) const +{ + return mData.getRecord (mData.globalToLocalIndex (index)); +} + +void CSMWorld::RefIdCollection::load (ESM::ESMReader& reader, bool base, UniversalId::Type type) +{ + std::string id = reader.getHNOString ("NAME"); + + int index = searchId (id); + + if (reader.isNextSub ("DELE")) + { + reader.skipRecord(); + + if (index==-1) + { + // deleting a record that does not exist + + // ignore it for now + + /// \todo report the problem to the user + } + else if (base) + { + mData.erase (index, 1); + } + else + { + mData.getRecord (mData.globalToLocalIndex (index)).mState = RecordBase::State_Deleted; + } + } + else + { + if (index==-1) + { + // new record + int index = mData.getAppendIndex (type); + mData.appendRecord (type, id); + + RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (index); + + mData.load (localIndex, reader, base); + + mData.getRecord (localIndex).mState = + base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly; + } + else + { + // old record + RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (index); + + if (!base) + if (mData.getRecord (localIndex).mState==RecordBase::State_Erased) + throw std::logic_error ("attempt to access a deleted record"); + + mData.load (localIndex, reader, base); + + if (!base) + mData.getRecord (localIndex).mState = RecordBase::State_Modified; + } + } +} + +int CSMWorld::RefIdCollection::getAppendIndex (UniversalId::Type type) const +{ + return mData.getAppendIndex (type); +} \ No newline at end of file diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp new file mode 100644 index 000000000..4f8096d25 --- /dev/null +++ b/apps/opencs/model/world/refidcollection.hpp @@ -0,0 +1,95 @@ +#ifndef CSM_WOLRD_REFIDCOLLECTION_H +#define CSM_WOLRD_REFIDCOLLECTION_H + +#include +#include + +#include "columnbase.hpp" +#include "idcollection.hpp" +#include "refiddata.hpp" + +namespace CSMWorld +{ + class RefIdAdapter; + + class RefIdColumn : public ColumnBase + { + bool mEditable; + bool mUserEditable; + + public: + + RefIdColumn (const std::string& title, Display displayType, + int flag = Flag_Table | Flag_Dialogue, bool editable = true, + bool userEditable = true); + + virtual bool isEditable() const; + + virtual bool isUserEditable() const; + }; + + class RefIdCollection : public IdCollectionBase + { + private: + + RefIdData mData; + std::vector mColumns; + std::map mAdapters; + + private: + + const RefIdAdapter& findAdaptor (UniversalId::Type) const; + ///< Throws an exception if no adaptor for \a Type can be found. + + public: + + RefIdCollection(); + + virtual ~RefIdCollection(); + + virtual int getSize() const; + + virtual std::string getId (int index) const; + + virtual int getIndex (const std::string& id) const; + + virtual int getColumns() const; + + virtual const ColumnBase& getColumn (int column) const; + + virtual QVariant getData (int index, int column) const; + + virtual void setData (int index, int column, const QVariant& data); + + virtual void removeRows (int index, int count); + + virtual void appendBlankRecord (const std::string& id, UniversalId::Type type); + ///< \param type Will be ignored, unless the collection supports multiple record types + + virtual int searchId (const std::string& id) const; + ////< Search record with \a id. + /// \return index of record (if found) or -1 (not found) + + virtual void replace (int index, const RecordBase& record); + ///< If the record type does not match, an exception is thrown. + /// + /// \attention \a record must not change the ID. + + virtual void appendRecord (const RecordBase& record, UniversalId::Type type); + ///< If the record type does not match, an exception is thrown. + /// + ///< \param type Will be ignored, unless the collection supports multiple record types + + virtual const RecordBase& getRecord (const std::string& id) const; + + virtual const RecordBase& getRecord (int index) const; + + virtual void load (ESM::ESMReader& reader, bool base, UniversalId::Type type); + + virtual int getAppendIndex (UniversalId::Type type) const; + ///< \param type Will be ignored, unless the collection supports multiple record types + + }; +} + +#endif diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp new file mode 100644 index 000000000..9f6ed9be3 --- /dev/null +++ b/apps/opencs/model/world/refiddata.cpp @@ -0,0 +1,198 @@ + +#include "refiddata.hpp" + +#include + +#include + +CSMWorld::RefIdDataContainerBase::~RefIdDataContainerBase() {} + +CSMWorld::RefIdData::RefIdData() +{ + mRecordContainers.insert (std::make_pair (UniversalId::Type_Activator, &mActivators)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Potion, &mPotions)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Apparatus, &mApparati)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Armor, &mArmors)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Book, &mBooks)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Clothing, &mClothing)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Container, &mContainers)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Creature, &mCreatures)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Door, &mDoors)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Ingredient, &mIngredients)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_CreatureLevelledList, + &mCreatureLevelledLists)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_ItemLevelledList, &mItemLevelledLists)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Light, &mLights)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Lockpick, &mLockpicks)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Miscellaneous, &mMiscellaneous)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Npc, &mNpcs)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Probe, &mProbes)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Repair, &mRepairs)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Static, &mStatics)); + mRecordContainers.insert (std::make_pair (UniversalId::Type_Weapon, &mWeapons)); +} + +CSMWorld::RefIdData::LocalIndex CSMWorld::RefIdData::globalToLocalIndex (int index) const +{ + for (std::map::const_iterator iter ( + mRecordContainers.begin()); iter!=mRecordContainers.end(); ++iter) + { + if (indexsecond->getSize()) + return LocalIndex (index, iter->first); + + index -= iter->second->getSize(); + } + + throw std::runtime_error ("RefIdData index out of range"); +} + +int CSMWorld::RefIdData::localToGlobalIndex (const LocalIndex& index) + const +{ + std::map::const_iterator end = + mRecordContainers.find (index.second); + + if (end==mRecordContainers.end()) + throw std::logic_error ("invalid local index type"); + + int globalIndex = index.first; + + for (std::map::const_iterator iter ( + mRecordContainers.begin()); iter!=end; ++iter) + globalIndex += iter->second->getSize(); + + return globalIndex; +} + +CSMWorld::RefIdData::LocalIndex CSMWorld::RefIdData::searchId ( + const std::string& id) const +{ + std::string id2 = Misc::StringUtils::lowerCase (id); + + std::map >::const_iterator iter = mIndex.find (id2); + + if (iter!=mIndex.end()) + return std::make_pair (-1, CSMWorld::UniversalId::Type_None); + + return iter->second; +} + +void CSMWorld::RefIdData::erase (int index, int count) +{ + LocalIndex localIndex = globalToLocalIndex (index); + + std::map::const_iterator iter = + mRecordContainers.find (localIndex.second); + + while (count>0 && iter!=mRecordContainers.end()) + { + int size = iter->second->getSize(); + + if (localIndex.first+count>size) + { + erase (localIndex, size-localIndex.first); + count -= size-localIndex.first; + + ++iter; + + if (iter==mRecordContainers.end()) + throw std::runtime_error ("invalid count value for erase operation"); + + localIndex.first = 0; + localIndex.second = iter->first; + } + else + { + erase (localIndex, count); + count = 0; + } + } +} + +const CSMWorld::RecordBase& CSMWorld::RefIdData::getRecord (const LocalIndex& index) const +{ + std::map::const_iterator iter = + mRecordContainers.find (index.second); + + if (iter==mRecordContainers.end()) + throw std::logic_error ("invalid local index type"); + + return iter->second->getRecord (index.first); +} + +CSMWorld::RecordBase& CSMWorld::RefIdData::getRecord (const LocalIndex& index) +{ + std::map::iterator iter = + mRecordContainers.find (index.second); + + if (iter==mRecordContainers.end()) + throw std::logic_error ("invalid local index type"); + + return iter->second->getRecord (index.first); +} + +void CSMWorld::RefIdData::appendRecord (UniversalId::Type type, const std::string& id) +{ + std::map::iterator iter = + mRecordContainers.find (type); + + if (iter==mRecordContainers.end()) + throw std::logic_error ("invalid local index type"); + + iter->second->appendRecord (id); + + mIndex.insert (std::make_pair (Misc::StringUtils::lowerCase (id), + LocalIndex (iter->second->getSize()-1, type))); +} + +int CSMWorld::RefIdData::getAppendIndex (UniversalId::Type type) const +{ + int index = 0; + + for (std::map::const_iterator iter ( + mRecordContainers.begin()); iter!=mRecordContainers.end(); ++iter) + { + index += iter->second->getSize(); + + if (type==iter->first) + break; + } + + return index; +} + +void CSMWorld::RefIdData::load (const LocalIndex& index, ESM::ESMReader& reader, bool base) +{ + std::map::iterator iter = + mRecordContainers.find (index.second); + + if (iter==mRecordContainers.end()) + throw std::logic_error ("invalid local index type"); + + iter->second->load (index.first, reader, base); +} + +void CSMWorld::RefIdData::erase (const LocalIndex& index, int count) +{ + std::map::iterator iter = + mRecordContainers.find (index.second); + + if (iter==mRecordContainers.end()) + throw std::logic_error ("invalid local index type"); + + for (int i=index.first; i::iterator result = + mIndex.find (Misc::StringUtils::lowerCase (iter->second->getId (i))); + + if (result!=mIndex.end()) + mIndex.erase (result); + } + + iter->second->erase (index.first, count); +} + +int CSMWorld::RefIdData::getSize() const +{ + return mIndex.size(); +} diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp new file mode 100644 index 000000000..475566fb5 --- /dev/null +++ b/apps/opencs/model/world/refiddata.hpp @@ -0,0 +1,188 @@ +#ifndef CSM_WOLRD_REFIDDATA_H +#define CSM_WOLRD_REFIDDATA_H + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "record.hpp" +#include "universalid.hpp" + +namespace ESM +{ + class ESMReader; +} + +namespace CSMWorld +{ + struct RefIdDataContainerBase + { + virtual ~RefIdDataContainerBase(); + + virtual int getSize() const = 0; + + virtual const RecordBase& getRecord (int index) const = 0; + + virtual RecordBase& getRecord (int index)= 0; + + virtual void appendRecord (const std::string& id) = 0; + + 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; + }; + + template + struct RefIdDataContainer : public RefIdDataContainerBase + { + std::vector > mContainer; + + virtual int getSize() const; + + virtual const RecordBase& getRecord (int index) const; + + virtual RecordBase& getRecord (int index); + + virtual void appendRecord (const std::string& id); + + virtual void load (int index, ESM::ESMReader& reader, bool base); + + virtual void erase (int index, int count); + + virtual std::string getId (int index) const; + }; + + template + int RefIdDataContainer::getSize() const + { + return static_cast (mContainer.size()); + } + + template + const RecordBase& RefIdDataContainer::getRecord (int index) const + { + return mContainer.at (index); + } + + template + RecordBase& RefIdDataContainer::getRecord (int index) + { + return mContainer.at (index); + } + + template + void RefIdDataContainer::appendRecord (const std::string& id) + { + Record record; + record.mModified.mId = id; + record.mModified.blank(); + record.mState = RecordBase::State_ModifiedOnly; + + mContainer.push_back (record); + } + + template + void RefIdDataContainer::load (int index, ESM::ESMReader& reader, bool base) + { + (base ? mContainer.at (index).mBase : mContainer.at (index).mModified).load (reader); + } + + template + void RefIdDataContainer::erase (int index, int count) + { + if (index<0 || index+count>=getSize()) + throw std::runtime_error ("invalid RefIdDataContainer index"); + + mContainer.erase (mContainer.begin()+index, mContainer.begin()+index+count); + } + + template + std::string RefIdDataContainer::getId (int index) const + { + return mContainer.at (index).get().mId; + } + + class RefIdData + { + public: + + typedef std::pair LocalIndex; + + private: + + RefIdDataContainer mActivators; + RefIdDataContainer mPotions; + RefIdDataContainer mApparati; + RefIdDataContainer mArmors; + RefIdDataContainer mBooks; + RefIdDataContainer mClothing; + RefIdDataContainer mContainers; + RefIdDataContainer mCreatures; + RefIdDataContainer mDoors; + RefIdDataContainer mIngredients; + RefIdDataContainer mCreatureLevelledLists; + RefIdDataContainer mItemLevelledLists; + RefIdDataContainer mLights; + RefIdDataContainer mLockpicks; + RefIdDataContainer mMiscellaneous; + RefIdDataContainer mNpcs; + RefIdDataContainer mProbes; + RefIdDataContainer mRepairs; + RefIdDataContainer mStatics; + RefIdDataContainer mWeapons; + + std::map mIndex; + + std::map mRecordContainers; + + void erase (const LocalIndex& index, int count); + ///< Must not spill over into another type. + + public: + + RefIdData(); + + LocalIndex globalToLocalIndex (int index) const; + + int localToGlobalIndex (const LocalIndex& index) const; + + LocalIndex searchId (const std::string& id) const; + + void erase (int index, int count); + + const RecordBase& getRecord (const LocalIndex& index) const; + + RecordBase& getRecord (const LocalIndex& index); + + void appendRecord (UniversalId::Type type, const std::string& id); + + int getAppendIndex (UniversalId::Type type) const; + + void load (const LocalIndex& index, ESM::ESMReader& reader, bool base); + + int getSize() const; + }; +} + +#endif From f7f56a1a1f965d071b00cb08cbb2d8abc3c6c20b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 7 May 2013 11:23:18 +0200 Subject: [PATCH 12/39] added a RefIdCollection to Data --- apps/opencs/model/world/data.cpp | 12 ++++++++++++ apps/opencs/model/world/data.hpp | 6 ++++++ apps/opencs/model/world/idcollection.hpp | 6 ++++-- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index dedbfc4e7..9172959bb 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -140,6 +140,8 @@ CSMWorld::Data::Data() addModel (new IdTable (&mBirthsigns), UniversalId::Type_Birthsigns, UniversalId::Type_Birthsign); addModel (new IdTable (&mSpells), UniversalId::Type_Spells, UniversalId::Type_Spell); addModel (new IdTable (&mCells), UniversalId::Type_Cells, UniversalId::Type_Cell); + addModel (new IdTable (&mReferenceables), UniversalId::Type_Referenceables, + UniversalId::Type_Referenceable); } CSMWorld::Data::~Data() @@ -268,6 +270,16 @@ CSMWorld::IdCollection& CSMWorld::Data::getCells() return mCells; } +const CSMWorld::RefIdCollection& CSMWorld::Data::getReferenceables() const +{ + return mReferenceables; +} + +CSMWorld::RefIdCollection& CSMWorld::Data::getReferenceables() +{ + return mReferenceables; +} + QAbstractItemModel *CSMWorld::Data::getTableModel (const UniversalId& id) { std::map::iterator iter = mModelIndex.find (id.getType()); diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index 03a2448f1..ad6e4ba69 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -21,6 +21,7 @@ #include "idcollection.hpp" #include "universalid.hpp" #include "cell.hpp" +#include "refidcollection.hpp" class QAbstractItemModel; @@ -40,6 +41,7 @@ namespace CSMWorld IdCollection mBirthsigns; IdCollection mSpells; IdCollection mCells; + RefIdCollection mReferenceables; std::vector mModels; std::map mModelIndex; @@ -104,6 +106,10 @@ namespace CSMWorld IdCollection& getCells(); + const RefIdCollection& getReferenceables() const; + + RefIdCollection& getReferenceables(); + QAbstractItemModel *getTableModel (const UniversalId& id); ///< If no table model is available for \a id, an exception is thrown. /// diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index 93390c97b..193e4f8e2 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -46,10 +46,12 @@ namespace CSMWorld virtual void setData (int index, int column, const QVariant& data) = 0; - virtual void merge() = 0; +// Not in use. Temporarily removed so that the implementation of RefIdCollection can continue without +// these functions for now. +// virtual void merge() = 0; ///< Merge modified into base. - virtual void purge() = 0; +// virtual void purge() = 0; ///< Remove records that are flagged as erased. virtual void removeRows (int index, int count) = 0; From 0f29ab8cf998222a6a27b7c9c299ecf0c3ed7fd0 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 7 May 2013 14:19:02 +0200 Subject: [PATCH 13/39] fixed the interface of the adapter class --- apps/opencs/model/world/refidadapter.hpp | 7 ++++--- apps/opencs/model/world/refidcollection.cpp | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/opencs/model/world/refidadapter.hpp b/apps/opencs/model/world/refidadapter.hpp index fa56e2836..bb9005b27 100644 --- a/apps/opencs/model/world/refidadapter.hpp +++ b/apps/opencs/model/world/refidadapter.hpp @@ -23,10 +23,11 @@ namespace CSMWorld virtual ~RefIdAdapter(); - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data) const = 0; - - virtual void setData (const RefIdColumn *column, RefIdData& data, const QVariant& value) + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int idnex) const = 0; + + virtual void setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const = 0; ///< If the data type does not match an exception is thrown. virtual std::string getId (const RecordBase& record) const = 0; diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 751d4e759..013970b04 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -83,7 +83,7 @@ QVariant CSMWorld::RefIdCollection::getData (int index, int column) const const RefIdAdapter& adaptor = findAdaptor (localIndex.second); - return adaptor.getData (&mColumns.at (column), mData); + return adaptor.getData (&mColumns.at (column), mData, localIndex.first); } void CSMWorld::RefIdCollection::setData (int index, int column, const QVariant& data) @@ -92,7 +92,7 @@ void CSMWorld::RefIdCollection::setData (int index, int column, const QVariant& const RefIdAdapter& adaptor = findAdaptor (localIndex.second); - adaptor.setData (&mColumns.at (column), mData, data); + adaptor.setData (&mColumns.at (column), mData, localIndex.first, data); } void CSMWorld::RefIdCollection::removeRows (int index, int count) From 02ace69511390bd0bba14555f0d6c2b4140a7cdf Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 11 May 2013 16:55:10 +0200 Subject: [PATCH 14/39] fixed RefID search --- apps/opencs/model/world/refidcollection.cpp | 14 ++++++++++++-- apps/opencs/model/world/refiddata.cpp | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 013970b04..1312a44e3 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -4,6 +4,7 @@ #include #include "refidadapter.hpp" +#include "refidadapterimp.hpp" CSMWorld::RefIdColumn::RefIdColumn (const std::string& title, Display displayType, int flag, bool editable, bool userEditable) @@ -37,7 +38,11 @@ CSMWorld::RefIdCollection::RefIdCollection() ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false)); mColumns.push_back (RefIdColumn ("*", ColumnBase::Display_Integer, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false)); - mColumns.push_back (RefIdColumn ("Name", ColumnBase::Display_String)); +// mColumns.push_back (RefIdColumn ("Name", ColumnBase::Display_String)); + + mAdapters.insert (std::make_pair (UniversalId::Type_Static, new StaticRefIdAdapter (&mColumns[0], + &mColumns[1]))); + } CSMWorld::RefIdCollection::~RefIdCollection() @@ -107,7 +112,12 @@ void CSMWorld::RefIdCollection::appendBlankRecord (const std::string& id, Univer int CSMWorld::RefIdCollection::searchId (const std::string& id) const { - return mData.localToGlobalIndex (mData.searchId (id)); + RefIdData::LocalIndex localIndex = mData.searchId (id); + + if (localIndex.first==-1) + return -1; + + return mData.localToGlobalIndex (localIndex); } void CSMWorld::RefIdCollection::replace (int index, const RecordBase& record) diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp index 9f6ed9be3..c95db045f 100644 --- a/apps/opencs/model/world/refiddata.cpp +++ b/apps/opencs/model/world/refiddata.cpp @@ -71,7 +71,7 @@ CSMWorld::RefIdData::LocalIndex CSMWorld::RefIdData::searchId ( std::map >::const_iterator iter = mIndex.find (id2); - if (iter!=mIndex.end()) + if (iter==mIndex.end()) return std::make_pair (-1, CSMWorld::UniversalId::Type_None); return iter->second; From 9426eda47abbca4facf4e4a8be0fd8d305ed139d Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 11 May 2013 17:01:16 +0200 Subject: [PATCH 15/39] small test with statics and two columns --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/model/world/data.cpp | 2 + apps/opencs/model/world/refidadapter.hpp | 2 +- apps/opencs/model/world/refidadapterimp.cpp | 49 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 28 ++++++++++++ apps/opencs/view/doc/view.cpp | 10 +++++ apps/opencs/view/doc/view.hpp | 2 + apps/opencs/view/world/subviews.cpp | 1 + 8 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 apps/opencs/model/world/refidadapterimp.cpp create mode 100644 apps/opencs/model/world/refidadapterimp.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 102b34890..26287c6bd 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -23,7 +23,7 @@ opencs_units (model/world opencs_units_noqt (model/world universalid data record idcollection commands columnbase scriptcontext cell refidcollection - refidadapter refiddata + refidadapter refiddata refidadapterimp ) opencs_hdrs_noqt (model/world diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 9172959bb..db6629aa0 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -327,6 +327,8 @@ void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base) case ESM::REC_SPEL: mSpells.load (reader, base); break; case ESM::REC_CELL: mCells.load (reader, base); break; + case ESM::REC_STAT: mReferenceables.load (reader, base, UniversalId::Type_Static); break; + default: /// \todo throw an exception instead, once all records are implemented diff --git a/apps/opencs/model/world/refidadapter.hpp b/apps/opencs/model/world/refidadapter.hpp index bb9005b27..df0ceae70 100644 --- a/apps/opencs/model/world/refidadapter.hpp +++ b/apps/opencs/model/world/refidadapter.hpp @@ -1,4 +1,4 @@ -#ifndef CSM_WOLRD_REDIDADAPTER_H +#ifndef CSM_WOLRD_REFIDADAPTER_H #define CSM_WOLRD_REFIDADAPTER_H #include diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp new file mode 100644 index 000000000..5038797dd --- /dev/null +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -0,0 +1,49 @@ + +#include "refidadapterimp.hpp" + +#include + +#include + +#include "record.hpp" +#include "refiddata.hpp" +#include "universalid.hpp" + +CSMWorld::StaticRefIdAdapter::StaticRefIdAdapter (const RefIdColumn *id, const RefIdColumn *modified) +: mId (id), mModified (modified) +{} + +QVariant CSMWorld::StaticRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const +{ + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Static))); + + if (column==mId) + return QString::fromUtf8 (record.get().mId.c_str()); + + if (column==mModified) + { + if (record.mState==Record::State_Erased) + return static_cast (Record::State_Deleted); + + return static_cast (record.mState); + } + + return QVariant(); +} + +void CSMWorld::StaticRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const +{ + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Static))); + + if (column==mModified) + record.mState = static_cast (value.toInt()); +} + +std::string CSMWorld::StaticRefIdAdapter::getId (const RecordBase& record) const +{ + return dynamic_cast&> (record).get().mId; +} \ No newline at end of file diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp new file mode 100644 index 000000000..c130e2f73 --- /dev/null +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -0,0 +1,28 @@ +#ifndef CSM_WOLRD_REFIDADAPTERIMP_H +#define CSM_WOLRD_REFIDADAPTERIMP_H + +#include "refidadapter.hpp" + +namespace CSMWorld +{ + class StaticRefIdAdapter : public RefIdAdapter + { + const RefIdColumn *mId; + const RefIdColumn *mModified; + + public: + + StaticRefIdAdapter (const RefIdColumn *id, const RefIdColumn *modified); + + virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int idnex) + 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 std::string getId (const RecordBase& record) const; + }; +} + +#endif diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index a684b85c5..8b46d649f 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -129,6 +129,11 @@ void CSVDoc::View::setupWorldMenu() QAction *cells = new QAction (tr ("Cells"), this); connect (cells, SIGNAL (triggered()), this, SLOT (addCellsSubView())); world->addAction (cells); + + QAction *referenceables = new QAction (tr ("Referenceables"), this); + connect (referenceables, SIGNAL (triggered()), this, SLOT (addReferenceablesSubView())); + world->addAction (referenceables); + } void CSVDoc::View::setupUi() @@ -334,6 +339,11 @@ void CSVDoc::View::addCellsSubView() addSubView (CSMWorld::UniversalId::Type_Cells); } +void CSVDoc::View::addReferenceablesSubView() +{ + addSubView (CSMWorld::UniversalId::Type_Referenceables); +} + void CSVDoc::View::abortOperation (int type) { mDocument->abortOperation (type); diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index a240d3b01..9e1e94188 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -135,6 +135,8 @@ namespace CSVDoc void addSpellsSubView(); void addCellsSubView(); + + void addReferenceablesSubView(); }; } diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index 0ce3d3d6d..3d05f8860 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -27,6 +27,7 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) CSMWorld::UniversalId::Type_Birthsigns, CSMWorld::UniversalId::Type_Spells, CSMWorld::UniversalId::Type_Cells, + CSMWorld::UniversalId::Type_Referenceables, CSMWorld::UniversalId::Type_None // end marker }; From d715cf5431dc9f15684d6199e6db59f704506399 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 11 May 2013 17:34:18 +0200 Subject: [PATCH 16/39] replaced static adapter with a template --- apps/opencs/model/world/refidadapterimp.cpp | 44 ------------- apps/opencs/model/world/refidadapterimp.hpp | 69 ++++++++++++++++++--- apps/opencs/model/world/refidcollection.cpp | 10 ++- apps/opencs/model/world/refidcollection.hpp | 3 +- 4 files changed, 72 insertions(+), 54 deletions(-) diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 5038797dd..b24be3da5 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -1,49 +1,5 @@ #include "refidadapterimp.hpp" -#include -#include -#include "record.hpp" -#include "refiddata.hpp" -#include "universalid.hpp" - -CSMWorld::StaticRefIdAdapter::StaticRefIdAdapter (const RefIdColumn *id, const RefIdColumn *modified) -: mId (id), mModified (modified) -{} - -QVariant CSMWorld::StaticRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, - int index) const -{ - const Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Static))); - - if (column==mId) - return QString::fromUtf8 (record.get().mId.c_str()); - - if (column==mModified) - { - if (record.mState==Record::State_Erased) - return static_cast (Record::State_Deleted); - - return static_cast (record.mState); - } - - return QVariant(); -} - -void CSMWorld::StaticRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const -{ - Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Static))); - - if (column==mModified) - record.mState = static_cast (value.toInt()); -} - -std::string CSMWorld::StaticRefIdAdapter::getId (const RecordBase& record) const -{ - return dynamic_cast&> (record).get().mId; -} \ No newline at end of file diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index c130e2f73..021fe58a9 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -1,28 +1,83 @@ #ifndef CSM_WOLRD_REFIDADAPTERIMP_H #define CSM_WOLRD_REFIDADAPTERIMP_H +#include + +#include "record.hpp" +#include "refiddata.hpp" +#include "universalid.hpp" #include "refidadapter.hpp" namespace CSMWorld { - class StaticRefIdAdapter : public RefIdAdapter + struct BaseColumns { - const RefIdColumn *mId; - const RefIdColumn *mModified; + const RefIdColumn *mId; + const RefIdColumn *mModified; + }; + + template + class BaseRefIdAdapter : public RefIdAdapter + { + UniversalId::Type mType; + BaseColumns mBase; public: - StaticRefIdAdapter (const RefIdColumn *id, const RefIdColumn *modified); + BaseRefIdAdapter (UniversalId::Type type, const BaseColumns& base); - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int idnex) + virtual std::string getId (const RecordBase& record) const; + + 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. - - virtual std::string getId (const RecordBase& record) const; }; + + template + BaseRefIdAdapter::BaseRefIdAdapter (UniversalId::Type type, const BaseColumns& base) + : mType (type), mBase (base) + {} + + template + std::string BaseRefIdAdapter::getId (const RecordBase& record) const + { + return dynamic_cast&> (record).get().mId; + } + + template + QVariant BaseRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const + { + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, mType))); + + if (column==mBase.mId) + return QString::fromUtf8 (record.get().mId.c_str()); + + if (column==mBase.mModified) + { + if (record.mState==Record::State_Erased) + return static_cast (Record::State_Deleted); + + return static_cast (record.mState); + } + + return QVariant(); + } + + template + void BaseRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const + { + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, mType))); + + if (column==mBase.mModified) + record.mState = static_cast (value.toInt()); + } } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 1312a44e3..c2969bf9c 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -34,14 +34,20 @@ const CSMWorld::RefIdAdapter& CSMWorld::RefIdCollection::findAdaptor (UniversalI CSMWorld::RefIdCollection::RefIdCollection() { + BaseColumns baseColumns; + mColumns.push_back (RefIdColumn ("ID", ColumnBase::Display_String, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false)); + baseColumns.mId = &mColumns.back(); mColumns.push_back (RefIdColumn ("*", ColumnBase::Display_Integer, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false)); + baseColumns.mModified = &mColumns.back(); // mColumns.push_back (RefIdColumn ("Name", ColumnBase::Display_String)); - mAdapters.insert (std::make_pair (UniversalId::Type_Static, new StaticRefIdAdapter (&mColumns[0], - &mColumns[1]))); + + + mAdapters.insert (std::make_pair (UniversalId::Type_Static, + new BaseRefIdAdapter (UniversalId::Type_Static, baseColumns))); } diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index 4f8096d25..a55ad38a4 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -3,6 +3,7 @@ #include #include +#include #include "columnbase.hpp" #include "idcollection.hpp" @@ -33,7 +34,7 @@ namespace CSMWorld private: RefIdData mData; - std::vector mColumns; + std::deque mColumns; std::map mAdapters; private: From c22f773f7231243d9e142a3c55122cfd875073e3 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 11 May 2013 17:45:28 +0200 Subject: [PATCH 17/39] load all types of referenceable IDs --- apps/opencs/model/world/data.cpp | 22 ++++++++++++ apps/opencs/model/world/refidcollection.cpp | 40 ++++++++++++++++++++- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index db6629aa0..1701e4289 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -327,7 +327,29 @@ void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base) case ESM::REC_SPEL: mSpells.load (reader, base); break; case ESM::REC_CELL: mCells.load (reader, base); break; + case ESM::REC_ACTI: mReferenceables.load (reader, base, UniversalId::Type_Activator); break; + case ESM::REC_ALCH: mReferenceables.load (reader, base, UniversalId::Type_Potion); break; + case ESM::REC_APPA: mReferenceables.load (reader, base, UniversalId::Type_Apparatus); break; + case ESM::REC_ARMO: mReferenceables.load (reader, base, UniversalId::Type_Armor); break; + case ESM::REC_BOOK: mReferenceables.load (reader, base, UniversalId::Type_Book); break; + case ESM::REC_CLOT: mReferenceables.load (reader, base, UniversalId::Type_Clothing); break; + case ESM::REC_CONT: mReferenceables.load (reader, base, UniversalId::Type_Container); break; + case ESM::REC_CREA: mReferenceables.load (reader, base, UniversalId::Type_Creature); break; + case ESM::REC_DOOR: mReferenceables.load (reader, base, UniversalId::Type_Door); break; + case ESM::REC_INGR: mReferenceables.load (reader, base, UniversalId::Type_Ingredient); break; + case ESM::REC_LEVC: + mReferenceables.load (reader, base, UniversalId::Type_CreatureLevelledList); break; + case ESM::REC_LEVI: + mReferenceables.load (reader, base, UniversalId::Type_ItemLevelledList); break; + case ESM::REC_LIGH: mReferenceables.load (reader, base, UniversalId::Type_Light); break; + case ESM::REC_LOCK: mReferenceables.load (reader, base, UniversalId::Type_Lockpick); break; + case ESM::REC_MISC: + mReferenceables.load (reader, base, UniversalId::Type_Miscellaneous); break; + case ESM::REC_NPC_: mReferenceables.load (reader, base, UniversalId::Type_Npc); break; + case ESM::REC_PROB: mReferenceables.load (reader, base, UniversalId::Type_Probe); break; + case ESM::REC_REPA: mReferenceables.load (reader, base, UniversalId::Type_Repair); break; case ESM::REC_STAT: mReferenceables.load (reader, base, UniversalId::Type_Static); break; + case ESM::REC_WEAP: mReferenceables.load (reader, base, UniversalId::Type_Weapon); break; default: diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index c2969bf9c..18feb7424 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -46,9 +46,47 @@ CSMWorld::RefIdCollection::RefIdCollection() + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, + new BaseRefIdAdapter (UniversalId::Type_Activator, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Potion, + new BaseRefIdAdapter (UniversalId::Type_Potion, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Apparatus, + new BaseRefIdAdapter (UniversalId::Type_Apparatus, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Armor, + new BaseRefIdAdapter (UniversalId::Type_Armor, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Book, + new BaseRefIdAdapter (UniversalId::Type_Book, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Clothing, + new BaseRefIdAdapter (UniversalId::Type_Clothing, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Container, + new BaseRefIdAdapter (UniversalId::Type_Container, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Creature, + new BaseRefIdAdapter (UniversalId::Type_Creature, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Door, + new BaseRefIdAdapter (UniversalId::Type_Door, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Ingredient, + new BaseRefIdAdapter (UniversalId::Type_Ingredient, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_CreatureLevelledList, + new BaseRefIdAdapter ( + UniversalId::Type_CreatureLevelledList, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_ItemLevelledList, + new BaseRefIdAdapter (UniversalId::Type_ItemLevelledList, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Light, + new BaseRefIdAdapter (UniversalId::Type_Light, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Lockpick, + new BaseRefIdAdapter (UniversalId::Type_Lockpick, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Miscellaneous, + new BaseRefIdAdapter (UniversalId::Type_Miscellaneous, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Npc, + new BaseRefIdAdapter (UniversalId::Type_Npc, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Probe, + new BaseRefIdAdapter (UniversalId::Type_Probe, baseColumns))); + mAdapters.insert (std::make_pair (UniversalId::Type_Repair, + new BaseRefIdAdapter (UniversalId::Type_Repair, baseColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Static, new BaseRefIdAdapter (UniversalId::Type_Static, baseColumns))); - + mAdapters.insert (std::make_pair (UniversalId::Type_Weapon, + new BaseRefIdAdapter (UniversalId::Type_Weapon, baseColumns))); } CSMWorld::RefIdCollection::~RefIdCollection() From 8ef2d040075352288625277a60f70cbb23fc8d32 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 11 May 2013 17:49:38 +0200 Subject: [PATCH 18/39] added type column --- apps/opencs/model/world/refidadapterimp.hpp | 4 ++++ apps/opencs/model/world/refidcollection.cpp | 3 +++ 2 files changed, 7 insertions(+) diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 021fe58a9..814ac9023 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -14,6 +14,7 @@ namespace CSMWorld { const RefIdColumn *mId; const RefIdColumn *mModified; + const RefIdColumn *mType; }; template @@ -65,6 +66,9 @@ namespace CSMWorld return static_cast (record.mState); } + if (column==mBase.mType) + return static_cast (mType); + return QVariant(); } diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 18feb7424..782b080c0 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -42,6 +42,9 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("*", ColumnBase::Display_Integer, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false)); baseColumns.mModified = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Type", ColumnBase::Display_Integer, + ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false)); + baseColumns.mType = &mColumns.back(); // mColumns.push_back (RefIdColumn ("Name", ColumnBase::Display_String)); From 318ebe0cb6c3bdfc49287ff140c4ec89ad017167 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 11 May 2013 18:35:48 +0200 Subject: [PATCH 19/39] added model column --- apps/opencs/model/world/record.hpp | 12 ++++ apps/opencs/model/world/refidadapterimp.hpp | 66 +++++++++++++++++++++ apps/opencs/model/world/refidcollection.cpp | 39 ++++++------ 3 files changed, 99 insertions(+), 18 deletions(-) diff --git a/apps/opencs/model/world/record.hpp b/apps/opencs/model/world/record.hpp index 853ed1559..861fc47a3 100644 --- a/apps/opencs/model/world/record.hpp +++ b/apps/opencs/model/world/record.hpp @@ -45,6 +45,9 @@ namespace CSMWorld const ESXRecordT& get() const; ///< Throws an exception, if the record is deleted. + ESXRecordT& get(); + ///< Throws an exception, if the record is deleted. + const ESXRecordT& getBase() const; ///< Throws an exception, if the record is deleted. Returns modified, if there is no base. @@ -76,6 +79,15 @@ namespace CSMWorld return mState==State_BaseOnly || mState==State_Deleted ? mBase : mModified; } + template + ESXRecordT& Record::get() + { + if (mState==State_Erased) + throw std::logic_error ("attempt to access a deleted record"); + + return mState==State_BaseOnly || mState==State_Deleted ? mBase : mModified; + } + template const ESXRecordT& Record::getBase() const { diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 814ac9023..55aaa536e 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -17,6 +17,7 @@ namespace CSMWorld const RefIdColumn *mType; }; + /// \brief Base adapter for all refereceable record types template class BaseRefIdAdapter : public RefIdAdapter { @@ -35,6 +36,8 @@ namespace CSMWorld 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. + + UniversalId::Type getType() const; }; template @@ -82,6 +85,69 @@ namespace CSMWorld if (column==mBase.mModified) record.mState = static_cast (value.toInt()); } + + template + UniversalId::Type BaseRefIdAdapter::getType() const + { + return mType; + } + + + struct ModelColumns : public BaseColumns + { + const RefIdColumn *mModel; + + ModelColumns (const BaseColumns& base) : BaseColumns (base) {} + }; + + /// \brief Adapter for IDs with models (all but levelled lists) + template + class ModelRefIdAdapter : public BaseRefIdAdapter + { + ModelColumns mModel; + + public: + + ModelRefIdAdapter (UniversalId::Type type, const ModelColumns& 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 + ModelRefIdAdapter::ModelRefIdAdapter (UniversalId::Type type, const ModelColumns& columns) + : BaseRefIdAdapter (type, columns), mModel (columns) + {} + + template + QVariant ModelRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const + { + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + + if (column==mModel.mModel) + return QString::fromUtf8 (record.get().mModel.c_str()); + + return BaseRefIdAdapter::getData (column, data, index); + } + + template + void ModelRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const + { + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + + if (column==mModel.mModel) + record.get().mModel = value.toString().toUtf8().constData(); + else + BaseRefIdAdapter::setData (column, data, index, value); + } } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 782b080c0..9806f260f 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -47,49 +47,52 @@ CSMWorld::RefIdCollection::RefIdCollection() baseColumns.mType = &mColumns.back(); // mColumns.push_back (RefIdColumn ("Name", ColumnBase::Display_String)); + ModelColumns modelColumns (baseColumns); + mColumns.push_back (RefIdColumn ("Model", ColumnBase::Display_String)); + modelColumns.mModel = &mColumns.back(); mAdapters.insert (std::make_pair (UniversalId::Type_Activator, - new BaseRefIdAdapter (UniversalId::Type_Activator, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Activator, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, - new BaseRefIdAdapter (UniversalId::Type_Potion, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Potion, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Apparatus, - new BaseRefIdAdapter (UniversalId::Type_Apparatus, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Apparatus, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Armor, - new BaseRefIdAdapter (UniversalId::Type_Armor, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Armor, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Book, - new BaseRefIdAdapter (UniversalId::Type_Book, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Book, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Clothing, - new BaseRefIdAdapter (UniversalId::Type_Clothing, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Clothing, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Container, - new BaseRefIdAdapter (UniversalId::Type_Container, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Container, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Creature, - new BaseRefIdAdapter (UniversalId::Type_Creature, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Creature, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Door, - new BaseRefIdAdapter (UniversalId::Type_Door, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Door, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Ingredient, - new BaseRefIdAdapter (UniversalId::Type_Ingredient, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Ingredient, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_CreatureLevelledList, new BaseRefIdAdapter ( UniversalId::Type_CreatureLevelledList, baseColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_ItemLevelledList, new BaseRefIdAdapter (UniversalId::Type_ItemLevelledList, baseColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Light, - new BaseRefIdAdapter (UniversalId::Type_Light, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Light, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Lockpick, - new BaseRefIdAdapter (UniversalId::Type_Lockpick, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Lockpick, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Miscellaneous, - new BaseRefIdAdapter (UniversalId::Type_Miscellaneous, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Miscellaneous, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Npc, - new BaseRefIdAdapter (UniversalId::Type_Npc, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Npc, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Probe, - new BaseRefIdAdapter (UniversalId::Type_Probe, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Probe, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Repair, - new BaseRefIdAdapter (UniversalId::Type_Repair, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Repair, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Static, - new BaseRefIdAdapter (UniversalId::Type_Static, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Static, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Weapon, - new BaseRefIdAdapter (UniversalId::Type_Weapon, baseColumns))); + new ModelRefIdAdapter (UniversalId::Type_Weapon, modelColumns))); } CSMWorld::RefIdCollection::~RefIdCollection() From e24ecfd5d26516d323caa05a4b9cc08fc83910bf Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 11 May 2013 18:43:01 +0200 Subject: [PATCH 20/39] added name column --- apps/opencs/model/world/refidadapterimp.hpp | 56 +++++++++++++++++++++ apps/opencs/model/world/refidcollection.cpp | 40 ++++++++------- 2 files changed, 78 insertions(+), 18 deletions(-) diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 55aaa536e..1978ae838 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -148,6 +148,62 @@ namespace CSMWorld else BaseRefIdAdapter::setData (column, data, index, value); } + + struct NameColumns : public ModelColumns + { + const RefIdColumn *mName; + + NameColumns (const ModelColumns& base) : ModelColumns (base) {} + }; + + /// \brief Adapter for IDs with names (all but levelled lists and statics) + template + class NameRefIdAdapter : public ModelRefIdAdapter + { + NameColumns mName; + + public: + + NameRefIdAdapter (UniversalId::Type type, const NameColumns& 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 + NameRefIdAdapter::NameRefIdAdapter (UniversalId::Type type, const NameColumns& columns) + : ModelRefIdAdapter (type, columns), mName (columns) + {} + + template + QVariant NameRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const + { + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + + if (column==mName.mName) + return QString::fromUtf8 (record.get().mName.c_str()); + + return ModelRefIdAdapter::getData (column, data, index); + } + + template + void NameRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const + { + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + + if (column==mName.mName) + record.get().mName = value.toString().toUtf8().constData(); + else + ModelRefIdAdapter::setData (column, data, index, value); + } } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 9806f260f..9968532cb 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -45,54 +45,58 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Type", ColumnBase::Display_Integer, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false)); baseColumns.mType = &mColumns.back(); -// mColumns.push_back (RefIdColumn ("Name", ColumnBase::Display_String)); ModelColumns modelColumns (baseColumns); mColumns.push_back (RefIdColumn ("Model", ColumnBase::Display_String)); modelColumns.mModel = &mColumns.back(); + NameColumns nameColumns (modelColumns); + + mColumns.push_back (RefIdColumn ("Name", ColumnBase::Display_String)); + nameColumns.mName = &mColumns.back(); + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, - new ModelRefIdAdapter (UniversalId::Type_Activator, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, - new ModelRefIdAdapter (UniversalId::Type_Potion, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Potion, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Apparatus, - new ModelRefIdAdapter (UniversalId::Type_Apparatus, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Apparatus, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Armor, - new ModelRefIdAdapter (UniversalId::Type_Armor, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Armor, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Book, - new ModelRefIdAdapter (UniversalId::Type_Book, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Book, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Clothing, - new ModelRefIdAdapter (UniversalId::Type_Clothing, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Clothing, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Container, - new ModelRefIdAdapter (UniversalId::Type_Container, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Container, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Creature, - new ModelRefIdAdapter (UniversalId::Type_Creature, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Creature, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Door, - new ModelRefIdAdapter (UniversalId::Type_Door, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Door, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Ingredient, - new ModelRefIdAdapter (UniversalId::Type_Ingredient, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Ingredient, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_CreatureLevelledList, new BaseRefIdAdapter ( UniversalId::Type_CreatureLevelledList, baseColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_ItemLevelledList, new BaseRefIdAdapter (UniversalId::Type_ItemLevelledList, baseColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Light, - new ModelRefIdAdapter (UniversalId::Type_Light, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Light, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Lockpick, - new ModelRefIdAdapter (UniversalId::Type_Lockpick, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Lockpick, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Miscellaneous, - new ModelRefIdAdapter (UniversalId::Type_Miscellaneous, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Miscellaneous, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Npc, - new ModelRefIdAdapter (UniversalId::Type_Npc, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Npc, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Probe, - new ModelRefIdAdapter (UniversalId::Type_Probe, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Probe, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Repair, - new ModelRefIdAdapter (UniversalId::Type_Repair, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Repair, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Static, new ModelRefIdAdapter (UniversalId::Type_Static, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Weapon, - new ModelRefIdAdapter (UniversalId::Type_Weapon, modelColumns))); + new NameRefIdAdapter (UniversalId::Type_Weapon, nameColumns))); } CSMWorld::RefIdCollection::~RefIdCollection() From ee2bc94698bd46e3ed64fe3be748ebd1acef8753 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 11 May 2013 18:57:23 +0200 Subject: [PATCH 21/39] added script column --- apps/opencs/model/world/refidadapterimp.hpp | 6 ++++++ apps/opencs/model/world/refidcollection.cpp | 2 ++ 2 files changed, 8 insertions(+) diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 1978ae838..78a363bef 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -152,6 +152,7 @@ namespace CSMWorld struct NameColumns : public ModelColumns { const RefIdColumn *mName; + const RefIdColumn *mScript; NameColumns (const ModelColumns& base) : ModelColumns (base) {} }; @@ -189,6 +190,9 @@ namespace CSMWorld if (column==mName.mName) return QString::fromUtf8 (record.get().mName.c_str()); + if (column==mName.mScript) + return QString::fromUtf8 (record.get().mScript.c_str()); + return ModelRefIdAdapter::getData (column, data, index); } @@ -201,6 +205,8 @@ namespace CSMWorld if (column==mName.mName) record.get().mName = value.toString().toUtf8().constData(); + else if (column==mName.mScript) + record.get().mScript = value.toString().toUtf8().constData(); else ModelRefIdAdapter::setData (column, data, index, value); } diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 9968532cb..31055a439 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -55,6 +55,8 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Name", ColumnBase::Display_String)); nameColumns.mName = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Script", ColumnBase::Display_String)); + nameColumns.mScript = &mColumns.back(); mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); From da929213872e0e9901fd1df1dfc57f8e8fd379c2 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 11 May 2013 19:21:16 +0200 Subject: [PATCH 22/39] added columns related to items in inventories --- apps/opencs/model/world/refidadapterimp.hpp | 69 +++++++++++++++++++++ apps/opencs/model/world/refidcollection.cpp | 34 ++++++---- 2 files changed, 91 insertions(+), 12 deletions(-) diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 78a363bef..4ceb01336 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -210,6 +210,75 @@ namespace CSMWorld else ModelRefIdAdapter::setData (column, data, index, value); } + + struct InventoryColumns : public NameColumns + { + const RefIdColumn *mIcon; + const RefIdColumn *mWeight; + const RefIdColumn *mValue; + + InventoryColumns (const NameColumns& base) : NameColumns (base) {} + }; + + /// \brief Adapter for IDs with names (all but levelled lists and statics) + template + class InventoryRefIdAdapter : public NameRefIdAdapter + { + InventoryColumns mName; + + public: + + InventoryRefIdAdapter (UniversalId::Type type, const InventoryColumns& 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 + InventoryRefIdAdapter::InventoryRefIdAdapter (UniversalId::Type type, + const InventoryColumns& columns) + : NameRefIdAdapter (type, columns), mName (columns) + {} + + template + QVariant InventoryRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const + { + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + + if (column==mName.mIcon) + return QString::fromUtf8 (record.get().mIcon.c_str()); + + if (column==mName.mWeight) + return record.get().mData.mWeight; + + if (column==mName.mValue) + return record.get().mData.mValue; + + return NameRefIdAdapter::getData (column, data, index); + } + + template + void InventoryRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const + { + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + + if (column==mName.mIcon) + record.get().mIcon = value.toString().toUtf8().constData(); + else if (column==mName.mWeight) + record.get().mData.mWeight = value.toFloat(); + else if (column==mName.mValue) + record.get().mData.mValue = value.toInt(); + else + NameRefIdAdapter::setData (column, data, index, value); + } } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 31055a439..5bfbb022d 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -58,18 +58,27 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Script", ColumnBase::Display_String)); nameColumns.mScript = &mColumns.back(); + InventoryColumns inventoryColumns (nameColumns); + + mColumns.push_back (RefIdColumn ("Icon", ColumnBase::Display_String)); + inventoryColumns.mIcon = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Weight", ColumnBase::Display_Float)); + inventoryColumns.mWeight = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Value", ColumnBase::Display_Integer)); + inventoryColumns.mValue = &mColumns.back(); + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, - new NameRefIdAdapter (UniversalId::Type_Potion, nameColumns))); + new InventoryRefIdAdapter (UniversalId::Type_Potion, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Apparatus, - new NameRefIdAdapter (UniversalId::Type_Apparatus, nameColumns))); + new InventoryRefIdAdapter (UniversalId::Type_Apparatus, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Armor, - new NameRefIdAdapter (UniversalId::Type_Armor, nameColumns))); + new InventoryRefIdAdapter (UniversalId::Type_Armor, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Book, - new NameRefIdAdapter (UniversalId::Type_Book, nameColumns))); + new InventoryRefIdAdapter (UniversalId::Type_Book, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Clothing, - new NameRefIdAdapter (UniversalId::Type_Clothing, nameColumns))); + new InventoryRefIdAdapter (UniversalId::Type_Clothing, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Container, new NameRefIdAdapter (UniversalId::Type_Container, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Creature, @@ -77,28 +86,29 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Door, new NameRefIdAdapter (UniversalId::Type_Door, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Ingredient, - new NameRefIdAdapter (UniversalId::Type_Ingredient, nameColumns))); + new InventoryRefIdAdapter (UniversalId::Type_Ingredient, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_CreatureLevelledList, new BaseRefIdAdapter ( UniversalId::Type_CreatureLevelledList, baseColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_ItemLevelledList, new BaseRefIdAdapter (UniversalId::Type_ItemLevelledList, baseColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Light, - new NameRefIdAdapter (UniversalId::Type_Light, nameColumns))); + new InventoryRefIdAdapter (UniversalId::Type_Light, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Lockpick, - new NameRefIdAdapter (UniversalId::Type_Lockpick, nameColumns))); + new InventoryRefIdAdapter (UniversalId::Type_Lockpick, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Miscellaneous, - new NameRefIdAdapter (UniversalId::Type_Miscellaneous, nameColumns))); + new InventoryRefIdAdapter (UniversalId::Type_Miscellaneous, + inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Npc, new NameRefIdAdapter (UniversalId::Type_Npc, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Probe, - new NameRefIdAdapter (UniversalId::Type_Probe, nameColumns))); + new InventoryRefIdAdapter (UniversalId::Type_Probe, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Repair, - new NameRefIdAdapter (UniversalId::Type_Repair, nameColumns))); + new InventoryRefIdAdapter (UniversalId::Type_Repair, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Static, new ModelRefIdAdapter (UniversalId::Type_Static, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Weapon, - new NameRefIdAdapter (UniversalId::Type_Weapon, nameColumns))); + new InventoryRefIdAdapter (UniversalId::Type_Weapon, inventoryColumns))); } CSMWorld::RefIdCollection::~RefIdCollection() From 7fd277b87ab8bb8d7ed6e0094c802ebc707715ed Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 12 May 2013 15:50:29 +0200 Subject: [PATCH 23/39] added missing column for potions --- apps/opencs/model/world/refidadapterimp.cpp | 27 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 18 ++++++++++++++ apps/opencs/model/world/refidcollection.cpp | 5 +++- 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index b24be3da5..783d9ba41 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -1,5 +1,32 @@ #include "refidadapterimp.hpp" +CSMWorld::PotionRefIdAdapter::PotionRefIdAdapter (const InventoryColumns& columns, + const RefIdColumn *autoCalc) +: InventoryRefIdAdapter (UniversalId::Type_Potion, columns), + mAutoCalc (autoCalc) +{} +QVariant CSMWorld::PotionRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const +{ + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Potion))); + if (column==mAutoCalc) + return record.get().mData.mAutoCalc; + + return InventoryRefIdAdapter::getData (column, data, index); +} + +void CSMWorld::PotionRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const +{ + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Potion))); + + if (column==mAutoCalc) + record.get().mData.mAutoCalc = value.toInt(); + else + InventoryRefIdAdapter::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 4ceb01336..e6bfcab8a 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -3,6 +3,8 @@ #include +#include + #include "record.hpp" #include "refiddata.hpp" #include "universalid.hpp" @@ -279,6 +281,22 @@ namespace CSMWorld else NameRefIdAdapter::setData (column, data, index, value); } + + class PotionRefIdAdapter : public InventoryRefIdAdapter + { + const RefIdColumn *mAutoCalc; + + public: + + PotionRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *autoCalc); + + 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. + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 5bfbb022d..cc0d390d5 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -67,10 +67,13 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Value", ColumnBase::Display_Integer)); inventoryColumns.mValue = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Auto Calc", ColumnBase::Display_Boolean)); + const RefIdColumn *autoCalc = &mColumns.back(); + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, - new InventoryRefIdAdapter (UniversalId::Type_Potion, inventoryColumns))); + new PotionRefIdAdapter (inventoryColumns, autoCalc))); mAdapters.insert (std::make_pair (UniversalId::Type_Apparatus, new InventoryRefIdAdapter (UniversalId::Type_Apparatus, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Armor, From 929b38ff6a06707a48770ee95e81c63f36c4a0e8 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 13 May 2013 12:51:27 +0200 Subject: [PATCH 24/39] added missing columns for apparati records --- apps/opencs/model/world/columnbase.hpp | 3 +- apps/opencs/model/world/refidadapterimp.cpp | 36 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 19 +++++++++++ apps/opencs/model/world/refidcollection.cpp | 8 ++++- apps/opencs/view/doc/viewmanager.cpp | 8 +++++ apps/opencs/view/world/enumdelegate.cpp | 26 +++++++++------ 6 files changed, 88 insertions(+), 12 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index fea618037..3dc41f737 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -36,7 +36,8 @@ namespace CSMWorld Display_Attribute, Display_Boolean, Display_SpellType, - Display_Script + Display_Script, + Display_ApparatusType }; std::string mTitle; diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 783d9ba41..eb68468de 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -29,4 +29,40 @@ void CSMWorld::PotionRefIdAdapter::setData (const RefIdColumn *column, RefIdData record.get().mData.mAutoCalc = value.toInt(); else InventoryRefIdAdapter::setData (column, data, index, value); +} + + +CSMWorld::ApparatusRefIdAdapter::ApparatusRefIdAdapter (const InventoryColumns& columns, + const RefIdColumn *type, const RefIdColumn *quality) +: InventoryRefIdAdapter (UniversalId::Type_Apparatus, columns), + mType (type), mQuality (quality) +{} + +QVariant CSMWorld::ApparatusRefIdAdapter::getData (const RefIdColumn *column, + const RefIdData& data, int index) const +{ + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Apparatus))); + + if (column==mType) + return record.get().mData.mType; + + if (column==mQuality) + return record.get().mData.mQuality; + + return InventoryRefIdAdapter::getData (column, data, index); +} + +void CSMWorld::ApparatusRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const +{ + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Apparatus))); + + if (column==mType) + record.get().mData.mType = value.toInt(); + else if (column==mQuality) + record.get().mData.mQuality = value.toFloat(); + else + InventoryRefIdAdapter::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 e6bfcab8a..fc641e2af 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -4,6 +4,7 @@ #include #include +#include #include "record.hpp" #include "refiddata.hpp" @@ -297,6 +298,24 @@ namespace CSMWorld const QVariant& value) const; ///< If the data type does not match an exception is thrown. }; + + class ApparatusRefIdAdapter : public InventoryRefIdAdapter + { + const RefIdColumn *mType; + const RefIdColumn *mQuality; + + public: + + ApparatusRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *type, + const RefIdColumn *quality); + + 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. + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index cc0d390d5..bc18f90ae 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -70,12 +70,18 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Auto Calc", ColumnBase::Display_Boolean)); const RefIdColumn *autoCalc = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Apparatus Type", ColumnBase::Display_ApparatusType)); + const RefIdColumn *apparatusType = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Quality", ColumnBase::Display_Float)); + const RefIdColumn *quality = &mColumns.back(); + 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))); mAdapters.insert (std::make_pair (UniversalId::Type_Apparatus, - new InventoryRefIdAdapter (UniversalId::Type_Apparatus, inventoryColumns))); + new ApparatusRefIdAdapter (inventoryColumns, apparatusType, quality))); mAdapters.insert (std::make_pair (UniversalId::Type_Armor, new InventoryRefIdAdapter (UniversalId::Type_Armor, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Book, diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 050bd51fe..182d87dc6 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -54,6 +54,11 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) "Spell", "Ability", "Blight", "Disease", "Curse", "Power", 0 }; + static const char *sApparatusTypes[] = + { + "Mortar & Pestle", "Albemic", "Calcinator", "Retort", 0 + }; + mDelegateFactories = new CSVWorld::CommandDelegateFactoryCollection; mDelegateFactories->add (CSMWorld::ColumnBase::Display_GmstVarType, @@ -70,6 +75,9 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) mDelegateFactories->add (CSMWorld::ColumnBase::Display_SpellType, new CSVWorld::EnumDelegateFactory (sSpellTypes)); + + mDelegateFactories->add (CSMWorld::ColumnBase::Display_ApparatusType, + new CSVWorld::EnumDelegateFactory (sApparatusTypes)); } CSVDoc::ViewManager::~ViewManager() diff --git a/apps/opencs/view/world/enumdelegate.cpp b/apps/opencs/view/world/enumdelegate.cpp index b1e9f7286..dd194abe9 100644 --- a/apps/opencs/view/world/enumdelegate.cpp +++ b/apps/opencs/view/world/enumdelegate.cpp @@ -44,6 +44,9 @@ CSVWorld::EnumDelegate::EnumDelegate (const std::vector QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { + if (!index.data().isValid()) + return 0; + QComboBox *comboBox = new QComboBox (parent); for (std::vector >::const_iterator iter (mValues.begin()); @@ -73,20 +76,23 @@ void CSVWorld::EnumDelegate::setEditorData (QWidget *editor, const QModelIndex& void CSVWorld::EnumDelegate::paint (QPainter *painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { - QStyleOptionViewItemV4 option2 (option); + if (index.data().isValid()) + { + QStyleOptionViewItemV4 option2 (option); - int value = index.data().toInt(); + int value = index.data().toInt(); - for (std::vector >::const_iterator iter (mValues.begin()); - iter!=mValues.end(); ++iter) - if (iter->first==value) - { - option2.text = iter->second; + for (std::vector >::const_iterator iter (mValues.begin()); + iter!=mValues.end(); ++iter) + if (iter->first==value) + { + option2.text = iter->second; - QApplication::style()->drawControl (QStyle::CE_ItemViewItem, &option2, painter); + QApplication::style()->drawControl (QStyle::CE_ItemViewItem, &option2, painter); - break; - } + break; + } + } } From 90bae2bead10ec4f872c26d40e83a1e8cb62da4a Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 13 May 2013 12:55:28 +0200 Subject: [PATCH 25/39] do not create editors for unused columns --- apps/opencs/view/world/util.cpp | 10 ++++++++++ apps/opencs/view/world/util.hpp | 3 +++ 2 files changed, 13 insertions(+) diff --git a/apps/opencs/view/world/util.cpp b/apps/opencs/view/world/util.cpp index 5ada1d84f..5bbedbf3d 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -116,6 +116,16 @@ void CSVWorld::CommandDelegate::setModelData (QWidget *editor, QAbstractItemMode ///< \todo provide some kind of feedback to the user, indicating that editing is currently not possible. } +QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleOptionViewItem& option, + const QModelIndex& index) const +{ + if (!index.data().isValid()) + return 0; + + return QStyledItemDelegate::createEditor (parent, option, index); +} + + void CSVWorld::CommandDelegate::setEditLock (bool locked) { mEditLock = locked; diff --git a/apps/opencs/view/world/util.hpp b/apps/opencs/view/world/util.hpp index 5334abf9c..95dfec6c5 100644 --- a/apps/opencs/view/world/util.hpp +++ b/apps/opencs/view/world/util.hpp @@ -99,6 +99,9 @@ namespace CSVWorld virtual void setModelData (QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const; + virtual QWidget *createEditor (QWidget *parent, const QStyleOptionViewItem& option, + const QModelIndex& index) const; + void setEditLock (bool locked); bool isEditLocked() const; From 52d81dc9fa9170d2d39d10c088c90513bf610ba2 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 13 May 2013 13:11:43 +0200 Subject: [PATCH 26/39] added columns for enchantments --- apps/opencs/model/world/refidadapterimp.hpp | 81 ++++++++++++++++++--- apps/opencs/model/world/refidcollection.cpp | 15 +++- 2 files changed, 83 insertions(+), 13 deletions(-) diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index fc641e2af..4eac0fa4b 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -223,11 +223,11 @@ namespace CSMWorld InventoryColumns (const NameColumns& base) : NameColumns (base) {} }; - /// \brief Adapter for IDs with names (all but levelled lists and statics) + /// \brief Adapter for IDs that can go into an inventory template class InventoryRefIdAdapter : public NameRefIdAdapter { - InventoryColumns mName; + InventoryColumns mInventory; public: @@ -244,7 +244,7 @@ namespace CSMWorld template InventoryRefIdAdapter::InventoryRefIdAdapter (UniversalId::Type type, const InventoryColumns& columns) - : NameRefIdAdapter (type, columns), mName (columns) + : NameRefIdAdapter (type, columns), mInventory (columns) {} template @@ -254,13 +254,13 @@ namespace CSMWorld const Record& record = static_cast&> ( data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); - if (column==mName.mIcon) + if (column==mInventory.mIcon) return QString::fromUtf8 (record.get().mIcon.c_str()); - if (column==mName.mWeight) + if (column==mInventory.mWeight) return record.get().mData.mWeight; - if (column==mName.mValue) + if (column==mInventory.mValue) return record.get().mData.mValue; return NameRefIdAdapter::getData (column, data, index); @@ -273,11 +273,11 @@ namespace CSMWorld Record& record = static_cast&> ( data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); - if (column==mName.mIcon) + if (column==mInventory.mIcon) record.get().mIcon = value.toString().toUtf8().constData(); - else if (column==mName.mWeight) + else if (column==mInventory.mWeight) record.get().mData.mWeight = value.toFloat(); - else if (column==mName.mValue) + else if (column==mInventory.mValue) record.get().mData.mValue = value.toInt(); else NameRefIdAdapter::setData (column, data, index, value); @@ -299,6 +299,69 @@ namespace CSMWorld ///< If the data type does not match an exception is thrown. }; + struct EnchantableColumns : public InventoryColumns + { + const RefIdColumn *mEnchantment; + const RefIdColumn *mEnchantmentPoints; + + EnchantableColumns (const InventoryColumns& base) : InventoryColumns (base) {} + }; + + /// \brief Adapter for enchantable IDs + template + class EnchantableRefIdAdapter : public InventoryRefIdAdapter + { + EnchantableColumns mEnchantable; + + public: + + EnchantableRefIdAdapter (UniversalId::Type type, const EnchantableColumns& 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 + EnchantableRefIdAdapter::EnchantableRefIdAdapter (UniversalId::Type type, + const EnchantableColumns& columns) + : InventoryRefIdAdapter (type, columns), mEnchantable (columns) + {} + + template + QVariant EnchantableRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const + { + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + + if (column==mEnchantable.mEnchantment) + return QString::fromUtf8 (record.get().mEnchant.c_str()); + + if (column==mEnchantable.mEnchantmentPoints) + return static_cast (record.get().mData.mEnchant); + + return InventoryRefIdAdapter::getData (column, data, index); + } + + template + void EnchantableRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, + int index, const QVariant& value) const + { + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + + if (column==mEnchantable.mEnchantment) + record.get().mEnchant = value.toString().toUtf8().constData(); + else if (column==mEnchantable.mEnchantmentPoints) + record.get().mData.mEnchant = value.toInt(); + else + InventoryRefIdAdapter::setData (column, data, index, value); + } + class ApparatusRefIdAdapter : public InventoryRefIdAdapter { const RefIdColumn *mType; diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index bc18f90ae..8ed927c70 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -67,6 +67,13 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Value", ColumnBase::Display_Integer)); inventoryColumns.mValue = &mColumns.back(); + EnchantableColumns enchantableColumns (inventoryColumns); + + mColumns.push_back (RefIdColumn ("Enchantment", ColumnBase::Display_String)); + enchantableColumns.mEnchantment = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Enchantment Points", ColumnBase::Display_Integer)); + enchantableColumns.mEnchantmentPoints = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Auto Calc", ColumnBase::Display_Boolean)); const RefIdColumn *autoCalc = &mColumns.back(); @@ -83,11 +90,11 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Apparatus, new ApparatusRefIdAdapter (inventoryColumns, apparatusType, quality))); mAdapters.insert (std::make_pair (UniversalId::Type_Armor, - new InventoryRefIdAdapter (UniversalId::Type_Armor, inventoryColumns))); + new EnchantableRefIdAdapter (UniversalId::Type_Armor, enchantableColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Book, - new InventoryRefIdAdapter (UniversalId::Type_Book, inventoryColumns))); + new EnchantableRefIdAdapter (UniversalId::Type_Book, enchantableColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Clothing, - new InventoryRefIdAdapter (UniversalId::Type_Clothing, inventoryColumns))); + new EnchantableRefIdAdapter (UniversalId::Type_Clothing, enchantableColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Container, new NameRefIdAdapter (UniversalId::Type_Container, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Creature, @@ -117,7 +124,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Static, new ModelRefIdAdapter (UniversalId::Type_Static, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Weapon, - new InventoryRefIdAdapter (UniversalId::Type_Weapon, inventoryColumns))); + new EnchantableRefIdAdapter (UniversalId::Type_Weapon, enchantableColumns))); } CSMWorld::RefIdCollection::~RefIdCollection() From 897e55391de4032cbbfcf392f148bbac07d3a3da Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 13 May 2013 13:36:24 +0200 Subject: [PATCH 27/39] added columns for tool IDs --- apps/opencs/model/world/refidadapterimp.hpp | 62 +++++++++++++++++++++ apps/opencs/model/world/refidcollection.cpp | 18 +++--- 2 files changed, 73 insertions(+), 7 deletions(-) diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 4eac0fa4b..8fc16af63 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -362,6 +362,68 @@ namespace CSMWorld InventoryRefIdAdapter::setData (column, data, index, value); } + struct ToolColumns : public InventoryColumns + { + const RefIdColumn *mQuality; + const RefIdColumn *mUses; + + ToolColumns (const InventoryColumns& base) : InventoryColumns (base) {} + }; + + /// \brief Adapter for tools with limited uses IDs (lockpick, repair, probes) + template + class ToolRefIdAdapter : public InventoryRefIdAdapter + { + ToolColumns mTools; + + public: + + ToolRefIdAdapter (UniversalId::Type type, const ToolColumns& 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 + ToolRefIdAdapter::ToolRefIdAdapter (UniversalId::Type type, const ToolColumns& columns) + : InventoryRefIdAdapter (type, columns), mTools (columns) + {} + + template + QVariant ToolRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const + { + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + + if (column==mTools.mQuality) + return record.get().mData.mQuality; + + if (column==mTools.mUses) + return record.get().mData.mUses; + + return InventoryRefIdAdapter::getData (column, data, index); + } + + template + void ToolRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, + int index, const QVariant& value) const + { + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + + if (column==mTools.mQuality) + record.get().mData.mQuality = value.toFloat(); + else if (column==mTools.mUses) + record.get().mData.mUses = value.toInt(); + else + InventoryRefIdAdapter::setData (column, data, index, value); + } + class ApparatusRefIdAdapter : public InventoryRefIdAdapter { const RefIdColumn *mType; diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 8ed927c70..829576725 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -74,21 +74,25 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Enchantment Points", ColumnBase::Display_Integer)); enchantableColumns.mEnchantmentPoints = &mColumns.back(); + ToolColumns toolsColumns (inventoryColumns); + + mColumns.push_back (RefIdColumn ("Quality", ColumnBase::Display_Float)); + toolsColumns.mQuality = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Uses", ColumnBase::Display_Integer)); + toolsColumns.mUses = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Auto Calc", ColumnBase::Display_Boolean)); const RefIdColumn *autoCalc = &mColumns.back(); mColumns.push_back (RefIdColumn ("Apparatus Type", ColumnBase::Display_ApparatusType)); const RefIdColumn *apparatusType = &mColumns.back(); - mColumns.push_back (RefIdColumn ("Quality", ColumnBase::Display_Float)); - const RefIdColumn *quality = &mColumns.back(); - 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))); mAdapters.insert (std::make_pair (UniversalId::Type_Apparatus, - new ApparatusRefIdAdapter (inventoryColumns, apparatusType, quality))); + new ApparatusRefIdAdapter (inventoryColumns, apparatusType, toolsColumns.mQuality))); mAdapters.insert (std::make_pair (UniversalId::Type_Armor, new EnchantableRefIdAdapter (UniversalId::Type_Armor, enchantableColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Book, @@ -111,16 +115,16 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Light, new InventoryRefIdAdapter (UniversalId::Type_Light, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Lockpick, - new InventoryRefIdAdapter (UniversalId::Type_Lockpick, inventoryColumns))); + new ToolRefIdAdapter (UniversalId::Type_Lockpick, toolsColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Miscellaneous, new InventoryRefIdAdapter (UniversalId::Type_Miscellaneous, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Npc, new NameRefIdAdapter (UniversalId::Type_Npc, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Probe, - new InventoryRefIdAdapter (UniversalId::Type_Probe, inventoryColumns))); + new ToolRefIdAdapter (UniversalId::Type_Probe, toolsColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Repair, - new InventoryRefIdAdapter (UniversalId::Type_Repair, inventoryColumns))); + new ToolRefIdAdapter (UniversalId::Type_Repair, toolsColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Static, new ModelRefIdAdapter (UniversalId::Type_Static, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Weapon, From 74d791e207d0a20e40617a9f727bb82634b446f9 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 13 May 2013 14:07:31 +0200 Subject: [PATCH 28/39] fixed auto calc column --- apps/opencs/model/world/refidadapterimp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index eb68468de..3668198c5 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -14,7 +14,7 @@ QVariant CSMWorld::PotionRefIdAdapter::getData (const RefIdColumn *column, const data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Potion))); if (column==mAutoCalc) - return record.get().mData.mAutoCalc; + return record.get().mData.mAutoCalc!=0; return InventoryRefIdAdapter::getData (column, data, index); } From 7c57f2c2215e9d4b615b1c1c97374e085f19c0f4 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 14 May 2013 13:20:59 +0200 Subject: [PATCH 29/39] added AI-related actor columns --- apps/opencs/model/world/refidadapterimp.hpp | 102 ++++++++++++++++++++ apps/opencs/model/world/refidcollection.cpp | 50 +++++++++- 2 files changed, 150 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 8fc16af63..0885517f2 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -1,6 +1,8 @@ #ifndef CSM_WOLRD_REFIDADAPTERIMP_H #define CSM_WOLRD_REFIDADAPTERIMP_H +#include + #include #include @@ -424,6 +426,106 @@ namespace CSMWorld InventoryRefIdAdapter::setData (column, data, index, value); } + struct ActorColumns : public NameColumns + { + const RefIdColumn *mHasAi; + const RefIdColumn *mHello; + const RefIdColumn *mFlee; + const RefIdColumn *mFight; + const RefIdColumn *mAlarm; + std::map mServices; + + ActorColumns (const NameColumns& base) : NameColumns (base) {} + }; + + /// \brief Adapter for actor IDs (handles common AI functionality) + template + class ActorRefIdAdapter : public NameRefIdAdapter + { + ActorColumns mActors; + + public: + + ActorRefIdAdapter (UniversalId::Type type, const ActorColumns& 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 + ActorRefIdAdapter::ActorRefIdAdapter (UniversalId::Type type, + const ActorColumns& columns) + : NameRefIdAdapter (type, columns), mActors (columns) + {} + + template + QVariant ActorRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const + { + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + + if (column==mActors.mHasAi) + return record.get().mHasAI!=0; + + if (column==mActors.mHello) + return record.get().mAiData.mHello; + + if (column==mActors.mFlee) + return record.get().mAiData.mFlee; + + if (column==mActors.mFight) + return record.get().mAiData.mFight; + + if (column==mActors.mAlarm) + return record.get().mAiData.mAlarm; + + std::map::const_iterator iter = + mActors.mServices.find (column); + + if (iter!=mActors.mServices.end()) + return (record.get().mAiData.mServices & iter->second)!=0; + + return NameRefIdAdapter::getData (column, data, index); + } + + template + void ActorRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const + { + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + + if (column==mActors.mHasAi) + record.get().mHasAI = value.toInt(); + else if (column==mActors.mHello) + record.get().mAiData.mHello = value.toInt(); + else if (column==mActors.mFlee) + record.get().mAiData.mFlee = value.toInt(); + else if (column==mActors.mFight) + record.get().mAiData.mFight = value.toInt(); + else if (column==mActors.mAlarm) + record.get().mAiData.mAlarm = value.toInt(); + else + { + typename std::map::const_iterator iter = + mActors.mServices.find (column); + if (iter!=mActors.mServices.end()) + { + if (value.toInt()!=0) + record.get().mAiData.mServices |= iter->second; + else + record.get().mAiData.mServices &= ~iter->second; + } + else + NameRefIdAdapter::setData (column, data, index, value); + } + } + class ApparatusRefIdAdapter : public InventoryRefIdAdapter { const RefIdColumn *mType; diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 829576725..452f59d19 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -81,6 +81,52 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Uses", ColumnBase::Display_Integer)); toolsColumns.mUses = &mColumns.back(); + ActorColumns actorsColumns (nameColumns); + + mColumns.push_back (RefIdColumn ("AI", ColumnBase::Display_Boolean)); + actorsColumns.mHasAi = &mColumns.back(); + mColumns.push_back (RefIdColumn ("AI Hello", ColumnBase::Display_Integer)); + actorsColumns.mHello = &mColumns.back(); + mColumns.push_back (RefIdColumn ("AI Flee", ColumnBase::Display_Integer)); + actorsColumns.mFlee = &mColumns.back(); + mColumns.push_back (RefIdColumn ("AI Fight", ColumnBase::Display_Integer)); + actorsColumns.mFight = &mColumns.back(); + mColumns.push_back (RefIdColumn ("AI Alarm", ColumnBase::Display_Integer)); + actorsColumns.mAlarm = &mColumns.back(); + + static const struct + { + const char *mName; + unsigned int mFlag; + } sServiceTable[] = + { + { "Buys Weapons", ESM::NPC::Weapon}, + { "Buys Armor", ESM::NPC::Armor}, + { "Buys Clothing", ESM::NPC::Clothing}, + { "Buys Books", ESM::NPC::Books}, + { "Buys Ingredients", ESM::NPC::Ingredients}, + { "Buys Lockpicks", ESM::NPC::Picks}, + { "Buys Probes", ESM::NPC::Probes}, + { "Buys Lights", ESM::NPC::Lights}, + { "Buys Apparati", ESM::NPC::Apparatus}, + { "Buys Repair Items", ESM::NPC::RepairItem}, + { "Buys Misc Items", ESM::NPC::Misc}, + { "Buys Potions", ESM::NPC::Potions}, + { "Buys Magic Items", ESM::NPC::MagicItems}, + { "Sells Spells", ESM::NPC::Spells}, + { "Trainer", ESM::NPC::Training}, + { "Spellmaking", ESM::NPC::Spellmaking}, + { "Enchanting Service", ESM::NPC::Enchanting}, + { "Repair Serivce", ESM::NPC::Repair}, + { 0, 0 } + }; + + for (int i=0; sServiceTable[i].mName; ++i) + { + mColumns.push_back (RefIdColumn (sServiceTable[i].mName, ColumnBase::Display_Boolean)); + actorsColumns.mServices.insert (std::make_pair (&mColumns.back(), sServiceTable[i].mFlag)); + } + mColumns.push_back (RefIdColumn ("Auto Calc", ColumnBase::Display_Boolean)); const RefIdColumn *autoCalc = &mColumns.back(); @@ -102,7 +148,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Container, new NameRefIdAdapter (UniversalId::Type_Container, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Creature, - new NameRefIdAdapter (UniversalId::Type_Creature, nameColumns))); + new ActorRefIdAdapter (UniversalId::Type_Creature, actorsColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Door, new NameRefIdAdapter (UniversalId::Type_Door, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Ingredient, @@ -120,7 +166,7 @@ CSMWorld::RefIdCollection::RefIdCollection() new InventoryRefIdAdapter (UniversalId::Type_Miscellaneous, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Npc, - new NameRefIdAdapter (UniversalId::Type_Npc, nameColumns))); + new ActorRefIdAdapter (UniversalId::Type_Npc, actorsColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Probe, new ToolRefIdAdapter (UniversalId::Type_Probe, toolsColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Repair, From fce9939f839a576e701fd8238b7a3c5c41c11dcc Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 14 May 2013 14:21:30 +0200 Subject: [PATCH 30/39] added missing columns for armor record --- apps/opencs/model/world/columnbase.hpp | 3 +- apps/opencs/model/world/refidadapterimp.cpp | 41 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 19 ++++++++++ apps/opencs/model/world/refidcollection.cpp | 11 +++++- apps/opencs/view/doc/viewmanager.cpp | 9 +++++ 5 files changed, 81 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 3dc41f737..5fc98cca0 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -37,7 +37,8 @@ namespace CSMWorld Display_Boolean, Display_SpellType, Display_Script, - Display_ApparatusType + Display_ApparatusType, + Display_ArmorType }; std::string mTitle; diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 3668198c5..7581c5ca3 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -65,4 +65,45 @@ void CSMWorld::ApparatusRefIdAdapter::setData (const RefIdColumn *column, RefIdD record.get().mData.mQuality = value.toFloat(); else InventoryRefIdAdapter::setData (column, data, index, value); +} + + +CSMWorld::ArmorRefIdAdapter::ArmorRefIdAdapter (const EnchantableColumns& columns, + const RefIdColumn *type, const RefIdColumn *health, const RefIdColumn *armor) +: EnchantableRefIdAdapter (UniversalId::Type_Armor, columns), + mType (type), mHealth (health), mArmor (armor) +{} + +QVariant CSMWorld::ArmorRefIdAdapter::getData (const RefIdColumn *column, + const RefIdData& data, int index) const +{ + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Armor))); + + if (column==mType) + return record.get().mData.mType; + + if (column==mHealth) + return record.get().mData.mHealth; + + if (column==mArmor) + return record.get().mData.mArmor; + + return EnchantableRefIdAdapter::getData (column, data, index); +} + +void CSMWorld::ArmorRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const +{ + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Armor))); + + if (column==mType) + record.get().mData.mType = value.toInt(); + else if (column==mHealth) + record.get().mData.mHealth = value.toInt(); + else if (column==mArmor) + record.get().mData.mArmor = value.toInt(); + 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 0885517f2..8881728f0 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -543,6 +543,25 @@ namespace CSMWorld const QVariant& value) const; ///< If the data type does not match an exception is thrown. }; + + class ArmorRefIdAdapter : public EnchantableRefIdAdapter + { + const RefIdColumn *mType; + const RefIdColumn *mHealth; + const RefIdColumn *mArmor; + + public: + + ArmorRefIdAdapter (const EnchantableColumns& columns, const RefIdColumn *type, + const RefIdColumn *health, const RefIdColumn *armor); + + 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. + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 452f59d19..086a509fb 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -133,6 +133,15 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Apparatus Type", ColumnBase::Display_ApparatusType)); const RefIdColumn *apparatusType = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Armor Type", ColumnBase::Display_ArmorType)); + const RefIdColumn *armorType = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Health", ColumnBase::Display_Integer)); + const RefIdColumn *health = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Armor Value", ColumnBase::Display_Integer)); + const RefIdColumn *armor = &mColumns.back(); + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, @@ -140,7 +149,7 @@ 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 EnchantableRefIdAdapter (UniversalId::Type_Armor, enchantableColumns))); + new ArmorRefIdAdapter (enchantableColumns, armorType, health, armor))); mAdapters.insert (std::make_pair (UniversalId::Type_Book, new EnchantableRefIdAdapter (UniversalId::Type_Book, enchantableColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Clothing, diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 182d87dc6..7a64f765d 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -59,6 +59,12 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) "Mortar & Pestle", "Albemic", "Calcinator", "Retort", 0 }; + static const char *sArmorTypes[] = + { + "Helmet", "Cuirass", "Left Pauldron", "Right Pauldron", "Greaves", "Boots", "Left Gauntlet", + "Right Gauntlet", "Shield", "Left Bracer", "Right Bracer", 0 + }; + mDelegateFactories = new CSVWorld::CommandDelegateFactoryCollection; mDelegateFactories->add (CSMWorld::ColumnBase::Display_GmstVarType, @@ -78,6 +84,9 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) mDelegateFactories->add (CSMWorld::ColumnBase::Display_ApparatusType, new CSVWorld::EnumDelegateFactory (sApparatusTypes)); + + mDelegateFactories->add (CSMWorld::ColumnBase::Display_ArmorType, + new CSVWorld::EnumDelegateFactory (sArmorTypes)); } CSVDoc::ViewManager::~ViewManager() From eba9d3e3ee93099cdd49dd24a610a3b47ab1cd98 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 14 May 2013 14:40:06 +0200 Subject: [PATCH 31/39] added missing columns for book record --- apps/opencs/model/world/refidadapterimp.cpp | 35 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 18 +++++++++++ apps/opencs/model/world/refidcollection.cpp | 8 ++++- 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 7581c5ca3..f062c8efe 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -106,4 +106,39 @@ void CSMWorld::ArmorRefIdAdapter::setData (const RefIdColumn *column, RefIdData& record.get().mData.mArmor = value.toInt(); else EnchantableRefIdAdapter::setData (column, data, index, value); +} + +CSMWorld::BookRefIdAdapter::BookRefIdAdapter (const EnchantableColumns& columns, + const RefIdColumn *scroll, const RefIdColumn *skill) +: EnchantableRefIdAdapter (UniversalId::Type_Book, columns), + mScroll (scroll), mSkill (skill) +{} + +QVariant CSMWorld::BookRefIdAdapter::getData (const RefIdColumn *column, + const RefIdData& data, int index) const +{ + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Book))); + + if (column==mScroll) + return record.get().mData.mIsScroll!=0; + + if (column==mSkill) + return record.get().mData.mSkillID; + + return EnchantableRefIdAdapter::getData (column, data, index); +} + +void CSMWorld::BookRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const +{ + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Book))); + + if (column==mScroll) + record.get().mData.mIsScroll = value.toInt(); + else if (column==mSkill) + record.get().mData.mSkillID = value.toInt(); + 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 8881728f0..0fbf9fabb 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -562,6 +562,24 @@ namespace CSMWorld const QVariant& value) const; ///< If the data type does not match an exception is thrown. }; + + class BookRefIdAdapter : public EnchantableRefIdAdapter + { + const RefIdColumn *mScroll; + const RefIdColumn *mSkill; + + public: + + BookRefIdAdapter (const EnchantableColumns& columns, const RefIdColumn *scroll, + const RefIdColumn *skill); + + 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. + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 086a509fb..a6e2e3d0f 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -142,6 +142,12 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Armor Value", ColumnBase::Display_Integer)); const RefIdColumn *armor = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Scroll", ColumnBase::Display_Boolean)); + const RefIdColumn *scroll = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Attribute", ColumnBase::Display_Attribute)); + const RefIdColumn *attribute = &mColumns.back(); + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, @@ -151,7 +157,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Armor, new ArmorRefIdAdapter (enchantableColumns, armorType, health, armor))); mAdapters.insert (std::make_pair (UniversalId::Type_Book, - new EnchantableRefIdAdapter (UniversalId::Type_Book, enchantableColumns))); + new BookRefIdAdapter (enchantableColumns, scroll, attribute))); mAdapters.insert (std::make_pair (UniversalId::Type_Clothing, new EnchantableRefIdAdapter (UniversalId::Type_Clothing, enchantableColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Container, From 28f2a7d2b4989e82c2830881389baadbade0db3e Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 15 May 2013 11:37:46 +0200 Subject: [PATCH 32/39] added missing column for clothing records --- apps/opencs/model/world/columnbase.hpp | 3 ++- apps/opencs/model/world/refidadapterimp.cpp | 29 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 16 ++++++++++++ apps/opencs/model/world/refidcollection.cpp | 5 +++- apps/opencs/view/doc/viewmanager.cpp | 9 +++++++ 5 files changed, 60 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 5fc98cca0..f2379304c 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -38,7 +38,8 @@ namespace CSMWorld Display_SpellType, Display_Script, Display_ApparatusType, - Display_ArmorType + Display_ArmorType, + Display_ClothingType }; std::string mTitle; diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index f062c8efe..57e868aa6 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -141,4 +141,33 @@ void CSMWorld::BookRefIdAdapter::setData (const RefIdColumn *column, RefIdData& record.get().mData.mSkillID = value.toInt(); else EnchantableRefIdAdapter::setData (column, data, index, value); +} + +CSMWorld::ClothingRefIdAdapter::ClothingRefIdAdapter (const EnchantableColumns& columns, + const RefIdColumn *type) +: EnchantableRefIdAdapter (UniversalId::Type_Clothing, columns), mType (type) +{} + +QVariant CSMWorld::ClothingRefIdAdapter::getData (const RefIdColumn *column, + const RefIdData& data, int index) const +{ + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Clothing))); + + if (column==mType) + return record.get().mData.mType; + + return EnchantableRefIdAdapter::getData (column, data, index); +} + +void CSMWorld::ClothingRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const +{ + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Clothing))); + + if (column==mType) + record.get().mData.mType = value.toInt(); + 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 0fbf9fabb..fb015b7e1 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -580,6 +580,22 @@ namespace CSMWorld const QVariant& value) const; ///< If the data type does not match an exception is thrown. }; + + class ClothingRefIdAdapter : public EnchantableRefIdAdapter + { + const RefIdColumn *mType; + + public: + + ClothingRefIdAdapter (const EnchantableColumns& columns, const RefIdColumn *type); + + 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. + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index a6e2e3d0f..8c9e19957 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -148,6 +148,9 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Attribute", ColumnBase::Display_Attribute)); const RefIdColumn *attribute = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Clothing Type", ColumnBase::Display_ClothingType)); + const RefIdColumn *clothingType = &mColumns.back(); + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, @@ -159,7 +162,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Book, new BookRefIdAdapter (enchantableColumns, scroll, attribute))); mAdapters.insert (std::make_pair (UniversalId::Type_Clothing, - new EnchantableRefIdAdapter (UniversalId::Type_Clothing, enchantableColumns))); + new ClothingRefIdAdapter (enchantableColumns, clothingType))); mAdapters.insert (std::make_pair (UniversalId::Type_Container, new NameRefIdAdapter (UniversalId::Type_Container, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Creature, diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 7a64f765d..b7da23083 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -65,6 +65,12 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) "Right Gauntlet", "Shield", "Left Bracer", "Right Bracer", 0 }; + static const char *sClothingTypes[] = + { + "Pants", "Shoes", "Shirt", "Belt", "Robe", "Right Glove", "Left Glove", "Skirt", "Ring", + "Amulet", 0 + }; + mDelegateFactories = new CSVWorld::CommandDelegateFactoryCollection; mDelegateFactories->add (CSMWorld::ColumnBase::Display_GmstVarType, @@ -87,6 +93,9 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) mDelegateFactories->add (CSMWorld::ColumnBase::Display_ArmorType, new CSVWorld::EnumDelegateFactory (sArmorTypes)); + + mDelegateFactories->add (CSMWorld::ColumnBase::Display_ClothingType, + new CSVWorld::EnumDelegateFactory (sClothingTypes)); } CSVDoc::ViewManager::~ViewManager() From d794a62d193f7e413a34b6981304df2a7aaa958f Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 15 May 2013 17:02:34 +0200 Subject: [PATCH 33/39] added missing columns for container record --- apps/opencs/model/world/refidadapterimp.cpp | 50 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 20 +++++++++ apps/opencs/model/world/refidcollection.cpp | 11 ++++- 3 files changed, 80 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 57e868aa6..ecd6ff7a6 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -170,4 +170,54 @@ void CSMWorld::ClothingRefIdAdapter::setData (const RefIdColumn *column, RefIdDa record.get().mData.mType = value.toInt(); else EnchantableRefIdAdapter::setData (column, data, index, value); +} + +CSMWorld::ContainerRefIdAdapter::ContainerRefIdAdapter (const NameColumns& columns, + const RefIdColumn *weight, const RefIdColumn *organic, const RefIdColumn *respawn) +: NameRefIdAdapter (UniversalId::Type_Container, columns), mWeight (weight), + mOrganic (organic), mRespawn (respawn) +{} + +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))); + + if (column==mWeight) + return record.get().mWeight; + + if (column==mOrganic) + return (record.get().mFlags & ESM::Container::Organic)!=0; + + if (column==mRespawn) + return (record.get().mFlags & ESM::Container::Respawn)!=0; + + return NameRefIdAdapter::getData (column, data, index); +} + +void CSMWorld::ContainerRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const +{ + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))); + + if (column==mWeight) + record.get().mWeight = value.toFloat(); + else if (column==mOrganic) + { + if (value.toInt()) + record.get().mFlags |= ESM::Container::Organic; + else + record.get().mFlags &= ~ESM::Container::Organic; + } + else if (column==mRespawn) + { + if (value.toInt()) + record.get().mFlags |= ESM::Container::Respawn; + else + record.get().mFlags &= ~ESM::Container::Respawn; + } + else + NameRefIdAdapter::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 fb015b7e1..681892165 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -596,6 +596,26 @@ namespace CSMWorld const QVariant& value) const; ///< If the data type does not match an exception is thrown. }; + + class ContainerRefIdAdapter : public NameRefIdAdapter + { + const RefIdColumn *mWeight; + const RefIdColumn *mOrganic; + const RefIdColumn *mRespawn; + + public: + + ContainerRefIdAdapter (const NameColumns& columns, const RefIdColumn *weight, + const RefIdColumn *organic, const RefIdColumn *respawn); + + 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. + + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 8c9e19957..e26f1dcf5 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -151,6 +151,15 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Clothing Type", ColumnBase::Display_ClothingType)); const RefIdColumn *clothingType = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Weight Capacity", ColumnBase::Display_Float)); + const RefIdColumn *weightCapacity = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Organic Container", ColumnBase::Display_Boolean)); + const RefIdColumn *organic = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Respawn", ColumnBase::Display_Boolean)); + const RefIdColumn *respawn = &mColumns.back(); + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, @@ -164,7 +173,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 NameRefIdAdapter (UniversalId::Type_Container, nameColumns))); + new ContainerRefIdAdapter (nameColumns, weightCapacity, organic, respawn))); mAdapters.insert (std::make_pair (UniversalId::Type_Creature, new ActorRefIdAdapter (UniversalId::Type_Creature, actorsColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Door, From 889a87982e77d3e19ace3696f26414ab63e2dad3 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 16 May 2013 16:27:33 +0200 Subject: [PATCH 34/39] added missing columns for creatures --- apps/opencs/model/world/columnbase.hpp | 3 +- apps/opencs/model/world/refidadapterimp.cpp | 66 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 26 ++++++++ apps/opencs/model/world/refidcollection.cpp | 39 +++++++++++- apps/opencs/view/doc/viewmanager.cpp | 8 +++ 5 files changed, 140 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index f2379304c..001ea4ff6 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -39,7 +39,8 @@ namespace CSMWorld Display_Script, Display_ApparatusType, Display_ArmorType, - Display_ClothingType + Display_ClothingType, + Display_CreatureType }; std::string mTitle; diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index ecd6ff7a6..1b54f2dad 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -220,4 +220,70 @@ void CSMWorld::ContainerRefIdAdapter::setData (const RefIdColumn *column, RefIdD } else NameRefIdAdapter::setData (column, data, index, value); +} + +CSMWorld::CreatureColumns::CreatureColumns (const ActorColumns& actorColumns) +: ActorColumns (actorColumns) +{} + +CSMWorld::CreatureRefIdAdapter::CreatureRefIdAdapter (const CreatureColumns& columns) +: ActorRefIdAdapter (UniversalId::Type_Creature, columns), mColumns (columns) +{} + +QVariant CSMWorld::CreatureRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const +{ + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature))); + + if (column==mColumns.mType) + return record.get().mData.mType; + + if (column==mColumns.mSoul) + return record.get().mData.mSoul; + + if (column==mColumns.mScale) + return record.get().mScale; + + if (column==mColumns.mOriginal) + return QString::fromUtf8 (record.get().mOriginal.c_str()); + + 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); +} + +void CSMWorld::CreatureRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const +{ + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature))); + + if (column==mColumns.mType) + record.get().mData.mType = value.toInt(); + else if (column==mColumns.mSoul) + record.get().mData.mSoul = value.toInt(); + else if (column==mColumns.mScale) + record.get().mScale = value.toFloat(); + else if (column==mColumns.mOriginal) + record.get().mOriginal = value.toString().toUtf8().constData(); + else + { + std::map::const_iterator iter = + mColumns.mFlags.find (column); + + if (iter!=mColumns.mFlags.end()) + { + if (value.toInt()!=0) + record.get().mFlags |= iter->second; + else + record.get().mFlags &= ~iter->second; + } + else + ActorRefIdAdapter::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 681892165..328be0c6b 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -614,7 +614,33 @@ namespace CSMWorld 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. + }; + struct CreatureColumns : public ActorColumns + { + std::map mFlags; + const RefIdColumn *mType; + const RefIdColumn *mSoul; + const RefIdColumn *mScale; + const RefIdColumn *mOriginal; + + CreatureColumns (const ActorColumns& actorColumns); + }; + + class CreatureRefIdAdapter : public ActorRefIdAdapter + { + CreatureColumns mColumns; + + public: + + CreatureRefIdAdapter (const CreatureColumns& 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. }; } diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index e26f1dcf5..5fc479f4c 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -160,6 +160,43 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Respawn", ColumnBase::Display_Boolean)); const RefIdColumn *respawn = &mColumns.back(); + CreatureColumns creatureColumns (actorsColumns); + + mColumns.push_back (RefIdColumn ("Creature Type", ColumnBase::Display_CreatureType)); + creatureColumns.mType = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Soul Points", ColumnBase::Display_Integer)); + creatureColumns.mSoul = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Scale", ColumnBase::Display_Float)); + creatureColumns.mScale = &mColumns.back(); + mColumns.push_back (RefIdColumn ("Original Creature", ColumnBase::Display_String)); + creatureColumns.mOriginal = &mColumns.back(); + + static const struct + { + const char *mName; + unsigned int mFlag; + } sCreatureFlagTable[] = + { + { "Biped", ESM::Creature::Biped }, + { "Has Weapon", ESM::Creature::Weapon }, + { "No Movement", ESM::Creature::None }, + { "Swims", ESM::Creature::Swims }, + { "Flies", ESM::Creature::Flies }, + { "Walks", ESM::Creature::Walks }, + { "Essential", ESM::Creature::Essential }, + { "Skeleton Blood", ESM::Creature::Skeleton }, + { "Metal Blood", ESM::Creature::Metal }, + { 0, 0 } + }; + + for (int i=0; sCreatureFlagTable[i].mName; ++i) + { + mColumns.push_back (RefIdColumn (sCreatureFlagTable[i].mName, ColumnBase::Display_Boolean)); + creatureColumns.mFlags.insert (std::make_pair (&mColumns.back(), sCreatureFlagTable[i].mFlag)); + } + + creatureColumns.mFlags.insert (std::make_pair (respawn, ESM::Creature::Respawn)); + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, @@ -175,7 +212,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Container, new ContainerRefIdAdapter (nameColumns, weightCapacity, organic, respawn))); mAdapters.insert (std::make_pair (UniversalId::Type_Creature, - new ActorRefIdAdapter (UniversalId::Type_Creature, actorsColumns))); + new CreatureRefIdAdapter (creatureColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Door, new NameRefIdAdapter (UniversalId::Type_Door, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Ingredient, diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index b7da23083..4e0614450 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -71,6 +71,11 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) "Amulet", 0 }; + static const char *sCreatureTypes[] = + { + "Creature", "Deadra", "Undead", "Humanoid", 0 + }; + mDelegateFactories = new CSVWorld::CommandDelegateFactoryCollection; mDelegateFactories->add (CSMWorld::ColumnBase::Display_GmstVarType, @@ -96,6 +101,9 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) mDelegateFactories->add (CSMWorld::ColumnBase::Display_ClothingType, new CSVWorld::EnumDelegateFactory (sClothingTypes)); + + mDelegateFactories->add (CSMWorld::ColumnBase::Display_CreatureType, + new CSVWorld::EnumDelegateFactory (sCreatureTypes)); } CSVDoc::ViewManager::~ViewManager() From 749fd418b5157812dd40d789ecacbf29cf266bb7 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 17 May 2013 15:10:41 +0200 Subject: [PATCH 35/39] added missing columns for door record --- apps/opencs/model/world/refidadapterimp.cpp | 36 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 18 +++++++++++ apps/opencs/model/world/refidcollection.cpp | 8 ++++- apps/opencs/model/world/refidcollection.hpp | 1 - 4 files changed, 61 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 1b54f2dad..10694a79e 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -286,4 +286,40 @@ void CSMWorld::CreatureRefIdAdapter::setData (const RefIdColumn *column, RefIdDa else ActorRefIdAdapter::setData (column, data, index, value); } +} + + +CSMWorld::DoorRefIdAdapter::DoorRefIdAdapter (const NameColumns& columns, + const RefIdColumn *openSound, const RefIdColumn *closeSound) +: NameRefIdAdapter (UniversalId::Type_Door, columns), mOpenSound (openSound), + mCloseSound (closeSound) +{} + +QVariant CSMWorld::DoorRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const +{ + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Door))); + + if (column==mOpenSound) + return QString::fromUtf8 (record.get().mOpenSound.c_str()); + + if (column==mCloseSound) + return QString::fromUtf8 (record.get().mCloseSound.c_str()); + + return NameRefIdAdapter::getData (column, data, index); +} + +void CSMWorld::DoorRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const +{ + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Door))); + + if (column==mOpenSound) + record.get().mOpenSound = value.toString().toUtf8().constData(); + else if (column==mCloseSound) + record.get().mCloseSound = value.toString().toUtf8().constData(); + else + NameRefIdAdapter::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 328be0c6b..fa25331a4 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -642,6 +642,24 @@ namespace CSMWorld const QVariant& value) const; ///< If the data type does not match an exception is thrown. }; + + class DoorRefIdAdapter : public NameRefIdAdapter + { + const RefIdColumn *mOpenSound; + const RefIdColumn *mCloseSound; + + public: + + DoorRefIdAdapter (const NameColumns& columns, const RefIdColumn *openSound, + const RefIdColumn *closeSound); + + 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. + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 5fc479f4c..5667d0170 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -197,6 +197,12 @@ CSMWorld::RefIdCollection::RefIdCollection() creatureColumns.mFlags.insert (std::make_pair (respawn, ESM::Creature::Respawn)); + mColumns.push_back (RefIdColumn ("Open Sound", ColumnBase::Display_String)); + const RefIdColumn *openSound = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Close Sound", ColumnBase::Display_String)); + const RefIdColumn *closeSound = &mColumns.back(); + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, @@ -214,7 +220,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Creature, new CreatureRefIdAdapter (creatureColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Door, - new NameRefIdAdapter (UniversalId::Type_Door, nameColumns))); + new DoorRefIdAdapter (nameColumns, openSound, closeSound))); mAdapters.insert (std::make_pair (UniversalId::Type_Ingredient, new InventoryRefIdAdapter (UniversalId::Type_Ingredient, inventoryColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_CreatureLevelledList, diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index a55ad38a4..dc86c128c 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -89,7 +89,6 @@ namespace CSMWorld virtual int getAppendIndex (UniversalId::Type type) const; ///< \param type Will be ignored, unless the collection supports multiple record types - }; } From 862e568f9b12649d9b02776aef1d5ee0214ff7af Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 18 May 2013 18:46:41 +0200 Subject: [PATCH 36/39] added missing columns for Light record --- apps/opencs/model/world/refidadapterimp.cpp | 68 ++++++++++++++++++++- apps/opencs/model/world/refidadapterimp.hpp | 27 ++++++++ apps/opencs/model/world/refidcollection.cpp | 40 +++++++++++- 3 files changed, 132 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 10694a79e..761e5a926 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -288,7 +288,6 @@ void CSMWorld::CreatureRefIdAdapter::setData (const RefIdColumn *column, RefIdDa } } - CSMWorld::DoorRefIdAdapter::DoorRefIdAdapter (const NameColumns& columns, const RefIdColumn *openSound, const RefIdColumn *closeSound) : NameRefIdAdapter (UniversalId::Type_Door, columns), mOpenSound (openSound), @@ -322,4 +321,69 @@ void CSMWorld::DoorRefIdAdapter::setData (const RefIdColumn *column, RefIdData& record.get().mCloseSound = value.toString().toUtf8().constData(); else NameRefIdAdapter::setData (column, data, index, value); -} \ No newline at end of file +} + +CSMWorld::LightColumns::LightColumns (const InventoryColumns& columns) +: InventoryColumns (columns) {} + +CSMWorld::LightRefIdAdapter::LightRefIdAdapter (const LightColumns& columns) +: InventoryRefIdAdapter (UniversalId::Type_Light, columns), mColumns (columns) +{} + +QVariant CSMWorld::LightRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const +{ + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Light))); + + if (column==mColumns.mTime) + return record.get().mData.mTime; + + if (column==mColumns.mRadius) + return record.get().mData.mRadius; + + if (column==mColumns.mColor) + return record.get().mData.mColor; + + if (column==mColumns.mSound) + return QString::fromUtf8 (record.get().mSound.c_str()); + + std::map::const_iterator iter = + mColumns.mFlags.find (column); + + if (iter!=mColumns.mFlags.end()) + return (record.get().mData.mFlags & iter->second)!=0; + + return InventoryRefIdAdapter::getData (column, data, index); +} + +void CSMWorld::LightRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const +{ + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Light))); + + if (column==mColumns.mTime) + record.get().mData.mTime = value.toInt(); + else if (column==mColumns.mRadius) + record.get().mData.mRadius = value.toInt(); + else if (column==mColumns.mColor) + record.get().mData.mColor = value.toInt(); + else if (column==mColumns.mSound) + record.get().mSound = value.toString().toUtf8().constData(); + else + { + std::map::const_iterator iter = + mColumns.mFlags.find (column); + + if (iter!=mColumns.mFlags.end()) + { + if (value.toInt()!=0) + record.get().mData.mFlags |= iter->second; + else + record.get().mData.mFlags &= ~iter->second; + } + else + InventoryRefIdAdapter::setData (column, data, index, value); + } +} diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index fa25331a4..a856d5202 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -660,6 +660,33 @@ namespace CSMWorld const QVariant& value) const; ///< If the data type does not match an exception is thrown. }; + + struct LightColumns : public InventoryColumns + { + const RefIdColumn *mTime; + const RefIdColumn *mRadius; + const RefIdColumn *mColor; + const RefIdColumn *mSound; + std::map mFlags; + + LightColumns (const InventoryColumns& columns); + }; + + class LightRefIdAdapter : public InventoryRefIdAdapter + { + LightColumns mColumns; + + public: + + LightRefIdAdapter (const LightColumns& 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. + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 5667d0170..45c4cb476 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -203,6 +203,44 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Close Sound", ColumnBase::Display_String)); const RefIdColumn *closeSound = &mColumns.back(); + LightColumns lightColumns (inventoryColumns); + + mColumns.push_back (RefIdColumn ("Duration", ColumnBase::Display_Integer)); + lightColumns.mTime = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Radius", ColumnBase::Display_Integer)); + lightColumns.mRadius = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Colour", ColumnBase::Display_Integer)); + lightColumns.mColor = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Sound", ColumnBase::Display_String)); + lightColumns.mSound = &mColumns.back(); + + static const struct + { + const char *mName; + unsigned int mFlag; + } sLightFlagTable[] = + { + { "Dynamic", ESM::Light::Dynamic }, + { "Portable", ESM::Light::Carry }, + { "Negative Light", ESM::Light::Negative }, + { "Flickering", ESM::Light::Flicker }, + { "Slow Flickering", ESM::Light::Flicker }, + { "Pulsing", ESM::Light::Pulse }, + { "Slow Pulsing", ESM::Light::PulseSlow }, + { "Fire", ESM::Light::Fire }, + { "Off by default", ESM::Light::OffDefault }, + { 0, 0 } + }; + + for (int i=0; sLightFlagTable[i].mName; ++i) + { + mColumns.push_back (RefIdColumn (sLightFlagTable[i].mName, ColumnBase::Display_Boolean)); + lightColumns.mFlags.insert (std::make_pair (&mColumns.back(), sLightFlagTable[i].mFlag)); + } + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, @@ -229,7 +267,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_ItemLevelledList, new BaseRefIdAdapter (UniversalId::Type_ItemLevelledList, baseColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Light, - new InventoryRefIdAdapter (UniversalId::Type_Light, inventoryColumns))); + new LightRefIdAdapter (lightColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Lockpick, new ToolRefIdAdapter (UniversalId::Type_Lockpick, toolsColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Miscellaneous, From 8d78bea4aab1ae70fbd524774f939e9d59cdb4f1 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 18 May 2013 18:55:23 +0200 Subject: [PATCH 37/39] added missing column for misc record --- apps/opencs/model/world/refidadapterimp.cpp | 28 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 16 ++++++++++++ apps/opencs/model/world/refidcollection.cpp | 6 +++-- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 761e5a926..0b5cd7a8b 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -387,3 +387,31 @@ void CSMWorld::LightRefIdAdapter::setData (const RefIdColumn *column, RefIdData& InventoryRefIdAdapter::setData (column, data, index, value); } } + +CSMWorld::MiscRefIdAdapter::MiscRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *key) +: InventoryRefIdAdapter (UniversalId::Type_Miscellaneous, columns), mKey (key) +{} + +QVariant CSMWorld::MiscRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const +{ + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Miscellaneous))); + + if (column==mKey) + return record.get().mData.mIsKey!=0; + + return InventoryRefIdAdapter::getData (column, data, index); +} + +void CSMWorld::MiscRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const +{ + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Miscellaneous))); + + if (column==mKey) + record.get().mData.mIsKey = value.toInt(); + else + InventoryRefIdAdapter::setData (column, data, index, value); +} diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index a856d5202..04cee12d1 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -687,6 +687,22 @@ namespace CSMWorld const QVariant& value) const; ///< If the data type does not match an exception is thrown. }; + + class MiscRefIdAdapter : public InventoryRefIdAdapter + { + const RefIdColumn *mKey; + + public: + + MiscRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *key); + + 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. + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 45c4cb476..0ff3f3fc9 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -241,6 +241,9 @@ CSMWorld::RefIdCollection::RefIdCollection() lightColumns.mFlags.insert (std::make_pair (&mColumns.back(), sLightFlagTable[i].mFlag)); } + mColumns.push_back (RefIdColumn ("Key", ColumnBase::Display_Boolean)); + const RefIdColumn *key = &mColumns.back(); + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, @@ -271,8 +274,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Lockpick, new ToolRefIdAdapter (UniversalId::Type_Lockpick, toolsColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Miscellaneous, - new InventoryRefIdAdapter (UniversalId::Type_Miscellaneous, - inventoryColumns))); + new MiscRefIdAdapter (inventoryColumns, key))); mAdapters.insert (std::make_pair (UniversalId::Type_Npc, new ActorRefIdAdapter (UniversalId::Type_Npc, actorsColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Probe, From 2123900db5c5498ba45731a461480d6363736d37 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 19 May 2013 13:53:47 +0200 Subject: [PATCH 38/39] added missing columns for NPC records --- apps/opencs/model/world/refidadapterimp.cpp | 69 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 28 +++++++++ apps/opencs/model/world/refidcollection.cpp | 44 ++++++++++++- 3 files changed, 140 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 0b5cd7a8b..59907b6d6 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -415,3 +415,72 @@ void CSMWorld::MiscRefIdAdapter::setData (const RefIdColumn *column, RefIdData& else InventoryRefIdAdapter::setData (column, data, index, value); } + +CSMWorld::NpcColumns::NpcColumns (const ActorColumns& actorColumns) : ActorColumns (actorColumns) {} + +CSMWorld::NpcRefIdAdapter::NpcRefIdAdapter (const NpcColumns& columns) +: ActorRefIdAdapter (UniversalId::Type_Npc, columns), mColumns (columns) +{} + +QVariant CSMWorld::NpcRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, int index) + const +{ + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc))); + + if (column==mColumns.mRace) + return QString::fromUtf8 (record.get().mRace.c_str()); + + if (column==mColumns.mClass) + return QString::fromUtf8 (record.get().mClass.c_str()); + + if (column==mColumns.mFaction) + return QString::fromUtf8 (record.get().mFaction.c_str()); + + if (column==mColumns.mHair) + return QString::fromUtf8 (record.get().mHair.c_str()); + + if (column==mColumns.mHead) + return QString::fromUtf8 (record.get().mHead.c_str()); + + 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); +} + +void CSMWorld::NpcRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const +{ + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc))); + + if (column==mColumns.mRace) + record.get().mRace = value.toString().toUtf8().constData(); + else if (column==mColumns.mClass) + record.get().mClass = value.toString().toUtf8().constData(); + else if (column==mColumns.mFaction) + record.get().mFaction = value.toString().toUtf8().constData(); + else if (column==mColumns.mHair) + record.get().mHair = value.toString().toUtf8().constData(); + else if (column==mColumns.mHead) + record.get().mHead = value.toString().toUtf8().constData(); + else + { + std::map::const_iterator iter = + mColumns.mFlags.find (column); + + if (iter!=mColumns.mFlags.end()) + { + if (value.toInt()!=0) + record.get().mFlags |= iter->second; + else + record.get().mFlags &= ~iter->second; + } + else + ActorRefIdAdapter::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 04cee12d1..04569b16f 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -703,6 +703,34 @@ namespace CSMWorld const QVariant& value) const; ///< If the data type does not match an exception is thrown. }; + + struct NpcColumns : public ActorColumns + { + std::map mFlags; + const RefIdColumn *mRace; + const RefIdColumn *mClass; + const RefIdColumn *mFaction; + const RefIdColumn *mHair; + const RefIdColumn *mHead; + + NpcColumns (const ActorColumns& actorColumns); + }; + + class NpcRefIdAdapter : public ActorRefIdAdapter + { + NpcColumns mColumns; + + public: + + NpcRefIdAdapter (const NpcColumns& 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. + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 0ff3f3fc9..f7c697233 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -189,10 +189,22 @@ CSMWorld::RefIdCollection::RefIdCollection() { 0, 0 } }; + // for re-use in NPC records + const RefIdColumn *essential = 0; + const RefIdColumn *skeletonBlood = 0; + const RefIdColumn *metalBlood = 0; + for (int i=0; sCreatureFlagTable[i].mName; ++i) { mColumns.push_back (RefIdColumn (sCreatureFlagTable[i].mName, ColumnBase::Display_Boolean)); creatureColumns.mFlags.insert (std::make_pair (&mColumns.back(), sCreatureFlagTable[i].mFlag)); + + switch (sCreatureFlagTable[i].mFlag) + { + case ESM::Creature::Essential: essential = &mColumns.back(); break; + case ESM::Creature::Skeleton: skeletonBlood = &mColumns.back(); break; + case ESM::Creature::Metal: metalBlood = &mColumns.back(); break; + } } creatureColumns.mFlags.insert (std::make_pair (respawn, ESM::Creature::Respawn)); @@ -244,6 +256,36 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.push_back (RefIdColumn ("Key", ColumnBase::Display_Boolean)); const RefIdColumn *key = &mColumns.back(); + NpcColumns npcColumns (actorsColumns); + + mColumns.push_back (RefIdColumn ("Race", ColumnBase::Display_String)); + npcColumns.mRace = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Class", ColumnBase::Display_String)); + npcColumns.mClass = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Faction", ColumnBase::Display_String)); + npcColumns.mFaction = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Hair", ColumnBase::Display_String)); + npcColumns.mHair = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Head", ColumnBase::Display_String)); + npcColumns.mHead = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Female", ColumnBase::Display_Boolean)); + npcColumns.mFlags.insert (std::make_pair (&mColumns.back(), ESM::NPC::Female)); + + npcColumns.mFlags.insert (std::make_pair (essential, ESM::NPC::Essential)); + + npcColumns.mFlags.insert (std::make_pair (respawn, ESM::NPC::Respawn)); + + npcColumns.mFlags.insert (std::make_pair (autoCalc, ESM::NPC::Autocalc)); + + npcColumns.mFlags.insert (std::make_pair (skeletonBlood, ESM::NPC::Skeleton)); + + npcColumns.mFlags.insert (std::make_pair (metalBlood, ESM::NPC::Metal)); + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, @@ -276,7 +318,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Miscellaneous, new MiscRefIdAdapter (inventoryColumns, key))); mAdapters.insert (std::make_pair (UniversalId::Type_Npc, - new ActorRefIdAdapter (UniversalId::Type_Npc, actorsColumns))); + new NpcRefIdAdapter (npcColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Probe, new ToolRefIdAdapter (UniversalId::Type_Probe, toolsColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Repair, From ca33d66ed91eff9078e63201f8296ddddd4241ae Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 19 May 2013 14:44:41 +0200 Subject: [PATCH 39/39] added missing columns for weapon records --- apps/opencs/model/world/columnbase.hpp | 3 +- apps/opencs/model/world/refidadapterimp.cpp | 89 +++++++++++++++++++++ apps/opencs/model/world/refidadapterimp.hpp | 30 +++++++ apps/opencs/model/world/refidcollection.cpp | 46 ++++++++++- apps/opencs/view/doc/viewmanager.cpp | 10 +++ 5 files changed, 176 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 001ea4ff6..8cc435f3a 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -40,7 +40,8 @@ namespace CSMWorld Display_ApparatusType, Display_ArmorType, Display_ClothingType, - Display_CreatureType + Display_CreatureType, + Display_WeaponType }; std::string mTitle; diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index 59907b6d6..f00e9fc77 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -483,4 +483,93 @@ void CSMWorld::NpcRefIdAdapter::setData (const RefIdColumn *column, RefIdData& d else ActorRefIdAdapter::setData (column, data, index, value); } +} + +CSMWorld::WeaponColumns::WeaponColumns (const EnchantableColumns& columns) +: EnchantableColumns (columns) {} + +CSMWorld::WeaponRefIdAdapter::WeaponRefIdAdapter (const WeaponColumns& columns) +: EnchantableRefIdAdapter (UniversalId::Type_Weapon, columns), mColumns (columns) +{} + +QVariant CSMWorld::WeaponRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, + int index) const +{ + const Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Weapon))); + + if (column==mColumns.mType) + return record.get().mData.mType; + + if (column==mColumns.mHealth) + return record.get().mData.mHealth; + + if (column==mColumns.mSpeed) + return record.get().mData.mSpeed; + + if (column==mColumns.mReach) + return record.get().mData.mReach; + + for (int i=0; i<2; ++i) + { + if (column==mColumns.mChop[i]) + return record.get().mData.mChop[i]; + + if (column==mColumns.mSlash[i]) + return record.get().mData.mSlash[i]; + + if (column==mColumns.mThrust[i]) + return record.get().mData.mThrust[i]; + } + + std::map::const_iterator iter = + mColumns.mFlags.find (column); + + if (iter!=mColumns.mFlags.end()) + return (record.get().mData.mFlags & iter->second)!=0; + + return EnchantableRefIdAdapter::getData (column, data, index); +} + +void CSMWorld::WeaponRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const +{ + Record& record = static_cast&> ( + data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Weapon))); + + if (column==mColumns.mType) + record.get().mData.mType = value.toInt(); + else if (column==mColumns.mHealth) + record.get().mData.mHealth = value.toInt(); + else if (column==mColumns.mSpeed) + record.get().mData.mSpeed = value.toFloat(); + else if (column==mColumns.mReach) + record.get().mData.mReach = value.toFloat(); + else if (column==mColumns.mChop[0]) + record.get().mData.mChop[0] = value.toInt(); + else if (column==mColumns.mChop[1]) + record.get().mData.mChop[1] = value.toInt(); + else if (column==mColumns.mSlash[0]) + record.get().mData.mSlash[0] = value.toInt(); + else if (column==mColumns.mSlash[1]) + record.get().mData.mSlash[1] = value.toInt(); + else if (column==mColumns.mThrust[0]) + record.get().mData.mThrust[0] = value.toInt(); + else if (column==mColumns.mThrust[1]) + record.get().mData.mThrust[1] = value.toInt(); + else + { + std::map::const_iterator iter = + mColumns.mFlags.find (column); + + if (iter!=mColumns.mFlags.end()) + { + if (value.toInt()!=0) + record.get().mData.mFlags |= iter->second; + else + record.get().mData.mFlags &= ~iter->second; + } + 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 04569b16f..d5d84a8f7 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -731,6 +731,36 @@ namespace CSMWorld const QVariant& value) const; ///< If the data type does not match an exception is thrown. }; + + struct WeaponColumns : public EnchantableColumns + { + const RefIdColumn *mType; + const RefIdColumn *mHealth; + const RefIdColumn *mSpeed; + const RefIdColumn *mReach; + const RefIdColumn *mChop[2]; + const RefIdColumn *mSlash[2]; + const RefIdColumn *mThrust[2]; + std::map mFlags; + + WeaponColumns (const EnchantableColumns& columns); + }; + + class WeaponRefIdAdapter : public EnchantableRefIdAdapter + { + WeaponColumns mColumns; + + public: + + WeaponRefIdAdapter (const WeaponColumns& 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. + }; } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index f7c697233..e11fe0fc8 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -286,6 +286,50 @@ CSMWorld::RefIdCollection::RefIdCollection() npcColumns.mFlags.insert (std::make_pair (metalBlood, ESM::NPC::Metal)); + WeaponColumns weaponColumns (enchantableColumns); + + mColumns.push_back (RefIdColumn ("Weapon Type", ColumnBase::Display_WeaponType)); + weaponColumns.mType = &mColumns.back(); + + weaponColumns.mHealth = health; + + mColumns.push_back (RefIdColumn ("Weapon Speed", ColumnBase::Display_Float)); + weaponColumns.mSpeed = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Weapon Reach", ColumnBase::Display_Float)); + weaponColumns.mReach = &mColumns.back(); + + for (int i=0; i<2; ++i) + { + std::string suffix = i==0 ? "Min " : "Max "; + + mColumns.push_back (RefIdColumn ("Chop" + suffix, ColumnBase::Display_Integer)); + weaponColumns.mChop[i] = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Slash" + suffix, ColumnBase::Display_Integer)); + weaponColumns.mSlash[i] = &mColumns.back(); + + mColumns.push_back (RefIdColumn ("Thrust" + suffix, ColumnBase::Display_Integer)); + weaponColumns.mThrust[i] = &mColumns.back(); + } + + static const struct + { + const char *mName; + unsigned int mFlag; + } sWeaponFlagTable[] = + { + { "Magical", ESM::Weapon::Magical }, + { "Silver", ESM::Weapon::Silver }, + { 0, 0 } + }; + + for (int i=0; sWeaponFlagTable[i].mName; ++i) + { + mColumns.push_back (RefIdColumn (sWeaponFlagTable[i].mName, ColumnBase::Display_Boolean)); + weaponColumns.mFlags.insert (std::make_pair (&mColumns.back(), sWeaponFlagTable[i].mFlag)); + } + mAdapters.insert (std::make_pair (UniversalId::Type_Activator, new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, @@ -326,7 +370,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mAdapters.insert (std::make_pair (UniversalId::Type_Static, new ModelRefIdAdapter (UniversalId::Type_Static, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Weapon, - new EnchantableRefIdAdapter (UniversalId::Type_Weapon, enchantableColumns))); + new WeaponRefIdAdapter (weaponColumns))); } CSMWorld::RefIdCollection::~RefIdCollection() diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 4e0614450..e1c6ab7e1 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -76,6 +76,13 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) "Creature", "Deadra", "Undead", "Humanoid", 0 }; + static const char *sWeaponTypes[] = + { + "Short Blade 1H", "Long Blade 1H", "Long Blade 2H", "Blunt 1H", "Blunt 2H Close", + "Blunt 2H Wide", "Spear 2H", "Axe 1H", "Axe 2H", "Bow", "Crossbow", "Thrown", "Arrow", + "Bolt", 0 + }; + mDelegateFactories = new CSVWorld::CommandDelegateFactoryCollection; mDelegateFactories->add (CSMWorld::ColumnBase::Display_GmstVarType, @@ -104,6 +111,9 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) mDelegateFactories->add (CSMWorld::ColumnBase::Display_CreatureType, new CSVWorld::EnumDelegateFactory (sCreatureTypes)); + + mDelegateFactories->add (CSMWorld::ColumnBase::Display_WeaponType, + new CSVWorld::EnumDelegateFactory (sWeaponTypes)); } CSVDoc::ViewManager::~ViewManager()