diff --git a/apps/opencs/model/world/record.hpp b/apps/opencs/model/world/record.hpp index 853ed1559a..861fc47a3b 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 <typename ESXRecordT> + ESXRecordT& Record<ESXRecordT>::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 <typename ESXRecordT> const ESXRecordT& Record<ESXRecordT>::getBase() const { diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 814ac9023f..55aaa536e4 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<typename RecordT> 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<typename RecordT> @@ -82,6 +85,69 @@ namespace CSMWorld if (column==mBase.mModified) record.mState = static_cast<RecordBase::State> (value.toInt()); } + + template<typename RecordT> + UniversalId::Type BaseRefIdAdapter<RecordT>::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<typename RecordT> + class ModelRefIdAdapter : public BaseRefIdAdapter<RecordT> + { + 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<typename RecordT> + ModelRefIdAdapter<RecordT>::ModelRefIdAdapter (UniversalId::Type type, const ModelColumns& columns) + : BaseRefIdAdapter<RecordT> (type, columns), mModel (columns) + {} + + template<typename RecordT> + QVariant ModelRefIdAdapter<RecordT>::getData (const RefIdColumn *column, const RefIdData& data, + int index) const + { + const Record<RecordT>& record = static_cast<const Record<RecordT>&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType()))); + + if (column==mModel.mModel) + return QString::fromUtf8 (record.get().mModel.c_str()); + + return BaseRefIdAdapter<RecordT>::getData (column, data, index); + } + + template<typename RecordT> + void ModelRefIdAdapter<RecordT>::setData (const RefIdColumn *column, RefIdData& data, int index, + const QVariant& value) const + { + Record<RecordT>& record = static_cast<Record<RecordT>&> ( + data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter<RecordT>::getType()))); + + if (column==mModel.mModel) + record.get().mModel = value.toString().toUtf8().constData(); + else + BaseRefIdAdapter<RecordT>::setData (column, data, index, value); + } } #endif diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index 782b080c07..9806f260f9 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<ESM::Activator> (UniversalId::Type_Activator, baseColumns))); + new ModelRefIdAdapter<ESM::Activator> (UniversalId::Type_Activator, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Potion, - new BaseRefIdAdapter<ESM::Potion> (UniversalId::Type_Potion, baseColumns))); + new ModelRefIdAdapter<ESM::Potion> (UniversalId::Type_Potion, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Apparatus, - new BaseRefIdAdapter<ESM::Apparatus> (UniversalId::Type_Apparatus, baseColumns))); + new ModelRefIdAdapter<ESM::Apparatus> (UniversalId::Type_Apparatus, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Armor, - new BaseRefIdAdapter<ESM::Armor> (UniversalId::Type_Armor, baseColumns))); + new ModelRefIdAdapter<ESM::Armor> (UniversalId::Type_Armor, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Book, - new BaseRefIdAdapter<ESM::Book> (UniversalId::Type_Book, baseColumns))); + new ModelRefIdAdapter<ESM::Book> (UniversalId::Type_Book, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Clothing, - new BaseRefIdAdapter<ESM::Clothing> (UniversalId::Type_Clothing, baseColumns))); + new ModelRefIdAdapter<ESM::Clothing> (UniversalId::Type_Clothing, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Container, - new BaseRefIdAdapter<ESM::Container> (UniversalId::Type_Container, baseColumns))); + new ModelRefIdAdapter<ESM::Container> (UniversalId::Type_Container, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Creature, - new BaseRefIdAdapter<ESM::Creature> (UniversalId::Type_Creature, baseColumns))); + new ModelRefIdAdapter<ESM::Creature> (UniversalId::Type_Creature, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Door, - new BaseRefIdAdapter<ESM::Door> (UniversalId::Type_Door, baseColumns))); + new ModelRefIdAdapter<ESM::Door> (UniversalId::Type_Door, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Ingredient, - new BaseRefIdAdapter<ESM::Ingredient> (UniversalId::Type_Ingredient, baseColumns))); + new ModelRefIdAdapter<ESM::Ingredient> (UniversalId::Type_Ingredient, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_CreatureLevelledList, new BaseRefIdAdapter<ESM::CreatureLevList> ( UniversalId::Type_CreatureLevelledList, baseColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_ItemLevelledList, new BaseRefIdAdapter<ESM::ItemLevList> (UniversalId::Type_ItemLevelledList, baseColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Light, - new BaseRefIdAdapter<ESM::Light> (UniversalId::Type_Light, baseColumns))); + new ModelRefIdAdapter<ESM::Light> (UniversalId::Type_Light, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Lockpick, - new BaseRefIdAdapter<ESM::Lockpick> (UniversalId::Type_Lockpick, baseColumns))); + new ModelRefIdAdapter<ESM::Lockpick> (UniversalId::Type_Lockpick, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Miscellaneous, - new BaseRefIdAdapter<ESM::Miscellaneous> (UniversalId::Type_Miscellaneous, baseColumns))); + new ModelRefIdAdapter<ESM::Miscellaneous> (UniversalId::Type_Miscellaneous, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Npc, - new BaseRefIdAdapter<ESM::NPC> (UniversalId::Type_Npc, baseColumns))); + new ModelRefIdAdapter<ESM::NPC> (UniversalId::Type_Npc, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Probe, - new BaseRefIdAdapter<ESM::Probe> (UniversalId::Type_Probe, baseColumns))); + new ModelRefIdAdapter<ESM::Probe> (UniversalId::Type_Probe, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Repair, - new BaseRefIdAdapter<ESM::Repair> (UniversalId::Type_Repair, baseColumns))); + new ModelRefIdAdapter<ESM::Repair> (UniversalId::Type_Repair, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Static, - new BaseRefIdAdapter<ESM::Static> (UniversalId::Type_Static, baseColumns))); + new ModelRefIdAdapter<ESM::Static> (UniversalId::Type_Static, modelColumns))); mAdapters.insert (std::make_pair (UniversalId::Type_Weapon, - new BaseRefIdAdapter<ESM::Weapon> (UniversalId::Type_Weapon, baseColumns))); + new ModelRefIdAdapter<ESM::Weapon> (UniversalId::Type_Weapon, modelColumns))); } CSMWorld::RefIdCollection::~RefIdCollection()