#ifndef CSM_WORLD_NESTEDADAPTORS_H #define CSM_WORLD_NESTEDADAPTORS_H #include #include #include "universalid.hpp" #include "nestedtablewrapper.hpp" #include "record.hpp" #include "refiddata.hpp" #include "refidadapter.hpp" #include #include /*! \brief * Nested adapter redirects responsibility to the helper class. Helper classes are polymorhpic (vide HelperBase and CastableHelper) and most likely templates. */ namespace CSMWorld { class RefIdColumn; class HelperBase { protected: const CSMWorld::UniversalId::Type mType; public: HelperBase(CSMWorld::UniversalId::Type type); virtual ~HelperBase(); virtual void setNestedTable(RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) = 0; virtual NestedTableWrapperBase* nestedTable(const RefIdData& data, int index) const = 0; virtual QVariant getNestedData(const CSMWorld::RefIdData& data, int index, int subRowIndex, int subColIndex) const = 0; virtual void removeNestedRow (RefIdData& data, int index, int rowToRemove) const = 0; virtual void setNestedData (RefIdData& data, int index, const QVariant& value, int subRowIndex, int subColIndex) const = 0; virtual void addNestedRow (RefIdData& data, int index, int position) const = 0; virtual int getNestedColumnsCount(const RefIdData& data) const = 0; virtual int getNestedRowsCount(const RefIdData& data, int index) const = 0; }; template class CastableHelper : public HelperBase { public: CastableHelper(CSMWorld::UniversalId::Type type) : HelperBase(type) {} protected: const Record& getRecord(const RefIdData& data, int index) const { return dynamic_cast&> ( data.getRecord (RefIdData::LocalIndex (index, mType))); } Record& getRecord(RefIdData& data, int index) const { return dynamic_cast&> ( data.getRecord (RefIdData::LocalIndex (index, mType))); } }; template class InventoryHelper : public CastableHelper { public: InventoryHelper(CSMWorld::UniversalId::Type type) : CastableHelper(type) {} virtual void setNestedTable(RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) { CastableHelper::getRecord(data, index).get().mInventory.mList = (static_cast >&>(nestedTable)).mNestedTable; } virtual NestedTableWrapperBase* nestedTable(const RefIdData& data, int index) const { return new NestedTableWrapper >(CastableHelper::getRecord(data, index).get().mInventory.mList); } virtual QVariant getNestedData(const CSMWorld::RefIdData& data, int index, int subRowIndex, int subColIndex) const { const ESM::ContItem& content = CastableHelper::getRecord(data, index).get().mInventory.mList.at(subRowIndex); switch (subColIndex) { case 0: return QString::fromUtf8(content.mItem.toString().c_str()); case 1: return content.mCount; default: throw std::logic_error("Trying to access non-existing column in the nested table!"); } } virtual void removeNestedRow (RefIdData& data, int index, int rowToRemove) const { std::vector& list = CastableHelper::getRecord(data, index).get().mInventory.mList; list.erase (list.begin () + rowToRemove); } void setNestedData (RefIdData& data, int index, const QVariant& value, int subRowIndex, int subColIndex) const { switch(subColIndex) { case 0: CastableHelper::getRecord(data, index).get().mInventory.mList.at(subRowIndex).mItem.assign(std::string(value.toString().toUtf8().constData())); break; case 1: CastableHelper::getRecord(data, index).get().mInventory.mList.at(subRowIndex).mCount = value.toInt(); break; default: throw std::logic_error("Trying to access non-existing column in the nested table!"); } } virtual void addNestedRow (RefIdData& data, int index, int position) const { std::vector& list = CastableHelper::getRecord(data, index).get().mInventory.mList; ESM::ContItem newRow = {0, ""}; if (position >= (int)list.size()) { list.push_back(newRow); return; } list.insert(list.begin()+position, newRow); } virtual int getNestedColumnsCount(const RefIdData& data) const { return 2; } virtual int getNestedRowsCount(const RefIdData& data, int index) const { return CastableHelper::getRecord(data, index).get().mInventory.mList.size(); } }; } #endif