#ifndef CSM_WOLRD_REFIDADAPTERIMP_H #define CSM_WOLRD_REFIDADAPTERIMP_H #include #include #include #include "record.hpp" #include "refiddata.hpp" #include "universalid.hpp" #include "refidadapter.hpp" namespace CSMWorld { struct BaseColumns { const RefIdColumn *mId; const RefIdColumn *mModified; const RefIdColumn *mType; }; /// \brief Base adapter for all refereceable record types template class BaseRefIdAdapter : public RefIdAdapter { UniversalId::Type mType; BaseColumns mBase; public: BaseRefIdAdapter (UniversalId::Type type, const BaseColumns& base); 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. UniversalId::Type getType() 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); } if (column==mBase.mType) return static_cast (mType); 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()); } 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); } struct NameColumns : public ModelColumns { const RefIdColumn *mName; const RefIdColumn *mScript; 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()); if (column==mName.mScript) return QString::fromUtf8 (record.get().mScript.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 if (column==mName.mScript) record.get().mScript = value.toString().toUtf8().constData(); 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); } 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. }; 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