#ifndef CSM_WOLRD_COLUMNIMP_H #define CSM_WOLRD_COLUMNIMP_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "columnbase.hpp" #include "columns.hpp" #include "info.hpp" #include "land.hpp" #include "landtexture.hpp" #include "record.hpp" namespace CSMWorld { std::optional getSkillIndex(std::string_view value); std::string getStringId(ESM::RefId value); /// \note Shares ID with VarValueColumn. A table can not have both. template struct FloatValueColumn : public Column { FloatValueColumn() : Column(Columns::ColumnId_Value, ColumnBase::Display_Float) { } QVariant get(const Record& record) const override { return record.get().mValue.getFloat(); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mValue.setFloat(data.toFloat()); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct StringIdColumn : public Column { StringIdColumn(bool hidden = false) : Column(Columns::ColumnId_Id, ColumnBase::Display_Id, hidden ? 0 : ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue) { } QVariant get(const Record& record) const override { return QString::fromStdString(getStringId(record.get().mId)); } bool isEditable() const override { return false; } }; template <> inline QVariant StringIdColumn::get(const Record& record) const { const Land& land = record.get(); return QString::fromUtf8(Land::createUniqueRecordId(land.mX, land.mY).c_str()); } template <> inline QVariant StringIdColumn::get(const Record& record) const { const LandTexture& ltex = record.get(); return QString::fromUtf8(LandTexture::createUniqueRecordId(ltex.mPluginIndex, ltex.mIndex).c_str()); } template struct RecordStateColumn : public Column { RecordStateColumn() : Column(Columns::ColumnId_Modification, ColumnBase::Display_RecordState) { } QVariant get(const Record& record) const override { if (record.mState == Record::State_Erased) return static_cast(Record::State_Deleted); return static_cast(record.mState); } void set(Record& record, const QVariant& data) override { record.mState = static_cast(data.toInt()); } bool isEditable() const override { return true; } bool isUserEditable() const override { return false; } }; template struct FixedRecordTypeColumn : public Column { int mType; FixedRecordTypeColumn(int type) : Column(Columns::ColumnId_RecordType, ColumnBase::Display_Integer, 0) , mType(type) { } QVariant get(const Record& record) const override { return mType; } bool isEditable() const override { return false; } }; /// \attention A var type column must be immediately followed by a suitable value column. template struct VarTypeColumn : public Column { VarTypeColumn(ColumnBase::Display display) : Column(Columns::ColumnId_ValueType, display, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh) { } QVariant get(const Record& record) const override { return static_cast(record.get().mValue.getType()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mValue.setType(static_cast(data.toInt())); record.setModified(record2); } bool isEditable() const override { return true; } }; /// \note Shares ID with FloatValueColumn. A table can not have both. template struct VarValueColumn : public Column { VarValueColumn() : Column(Columns::ColumnId_Value, ColumnBase::Display_Var, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh) { } QVariant get(const Record& record) const override { switch (record.get().mValue.getType()) { case ESM::VT_String: return QString::fromUtf8(record.get().mValue.getString().c_str()); case ESM::VT_Int: case ESM::VT_Short: case ESM::VT_Long: return record.get().mValue.getInteger(); case ESM::VT_Float: return record.get().mValue.getFloat(); default: return QVariant(); } } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); switch (record2.mValue.getType()) { case ESM::VT_String: record2.mValue.setString(data.toString().toUtf8().constData()); break; case ESM::VT_Int: case ESM::VT_Short: case ESM::VT_Long: record2.mValue.setInteger(data.toInt()); break; case ESM::VT_Float: record2.mValue.setFloat(data.toFloat()); break; default: break; } record.setModified(record2); } bool isEditable() const override { return true; } }; template struct DescriptionColumn : public Column { DescriptionColumn() : Column(Columns::ColumnId_Description, ColumnBase::Display_LongString) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mDescription.c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mDescription = data.toString().toUtf8().constData(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct SpecialisationColumn : public Column { SpecialisationColumn() : Column(Columns::ColumnId_Specialisation, ColumnBase::Display_Specialisation) { } QVariant get(const Record& record) const override { return record.get().mData.mSpecialization; } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mSpecialization = data.toInt(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct UseValueColumn : public Column { int mIndex; UseValueColumn(int index) : Column(Columns::ColumnId_UseValue1 + index, ColumnBase::Display_Float) , mIndex(index) { } QVariant get(const Record& record) const override { return record.get().mData.mUseValue[mIndex]; } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mUseValue[mIndex] = data.toFloat(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct AttributeColumn : public Column { AttributeColumn() : Column(Columns::ColumnId_Attribute, ColumnBase::Display_Attribute) { } QVariant get(const Record& record) const override { return record.get().mData.mAttribute; } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mAttribute = data.toInt(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct NameColumn : public Column { NameColumn(ColumnBase::Display display = ColumnBase::Display_String) : Column(Columns::ColumnId_Name, display) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mName.c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mName = data.toString().toUtf8().constData(); record.setModified(record2); } bool isEditable() const override { return true; } }; template <> struct NameColumn : public Column { NameColumn(ColumnBase::Display display = ColumnBase::Display_String) : Column(Columns::ColumnId_Name, display) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mName.c_str()); } void set(Record& record, const QVariant& data) override { CSMWorld::Cell record2 = record.get(); record2.mName = data.toString().toUtf8().constData(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct AttributesColumn : public Column { int mIndex; AttributesColumn(int index) : Column(Columns::ColumnId_Attribute1 + index, ColumnBase::Display_Attribute) , mIndex(index) { } QVariant get(const Record& record) const override { return record.get().mData.mAttribute[mIndex]; } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mAttribute[mIndex] = data.toInt(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct SkillsColumn : public Column { int mIndex; bool mMajor; SkillsColumn(int index, bool typePrefix = false, bool major = false) : Column((typePrefix ? (major ? Columns::ColumnId_MajorSkill1 : Columns::ColumnId_MinorSkill1) : Columns::ColumnId_Skill1) + index, ColumnBase::Display_Skill) , mIndex(index) , mMajor(major) { } QVariant get(const Record& record) const override { return QString::fromStdString( ESM::Skill::indexToRefId(record.get().mData.getSkill(mIndex, mMajor)).getRefIdString()); } void set(Record& record, const QVariant& data) override { if (const auto index = getSkillIndex(data.toString().toStdString())) { ESXRecordT record2 = record.get(); record2.mData.getSkill(mIndex, mMajor) = static_cast(*index); record.setModified(record2); } } bool isEditable() const override { return true; } }; template struct PlayableColumn : public Column { PlayableColumn() : Column(Columns::ColumnId_Playable, ColumnBase::Display_Boolean) { } QVariant get(const Record& record) const override { return record.get().mData.mIsPlayable != 0; } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mIsPlayable = data.toInt(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct HiddenColumn : public Column { HiddenColumn() : Column(Columns::ColumnId_Hidden, ColumnBase::Display_Boolean) { } QVariant get(const Record& record) const override { return record.get().mData.mIsHidden != 0; } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mIsHidden = data.toInt(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct FlagColumn : public Column { int mMask; bool mInverted; FlagColumn(int columnId, int mask, int flags = ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, bool inverted = false) : Column(columnId, ColumnBase::Display_Boolean, flags) , mMask(mask) , mInverted(inverted) { } QVariant get(const Record& record) const override { bool flag = (record.get().mData.mFlags & mMask) != 0; if (mInverted) flag = !flag; return flag; } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); int flags = record2.mData.mFlags & ~mMask; if ((data.toInt() != 0) != mInverted) flags |= mMask; record2.mData.mFlags = flags; record.setModified(record2); } bool isEditable() const override { return true; } }; template struct FlagColumn2 : public Column { int mMask; bool mInverted; FlagColumn2(int columnId, int mask, bool inverted = false) : Column(columnId, ColumnBase::Display_Boolean) , mMask(mask) , mInverted(inverted) { } QVariant get(const Record& record) const override { bool flag = (record.get().mFlags & mMask) != 0; if (mInverted) flag = !flag; return flag; } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); int flags = record2.mFlags & ~mMask; if ((data.toInt() != 0) != mInverted) flags |= mMask; record2.mFlags = flags; record.setModified(record2); } bool isEditable() const override { return true; } }; template struct WeightHeightColumn : public Column { bool mMale; bool mWeight; WeightHeightColumn(bool male, bool weight) : Column(male ? (weight ? Columns::ColumnId_MaleWeight : Columns::ColumnId_MaleHeight) : (weight ? Columns::ColumnId_FemaleWeight : Columns::ColumnId_FemaleHeight), ColumnBase::Display_Float) , mMale(male) , mWeight(weight) { } QVariant get(const Record& record) const override { if (mWeight) { if (mMale) return record.get().mData.mMaleWeight; return record.get().mData.mFemaleWeight; } if (mMale) return record.get().mData.mMaleHeight; return record.get().mData.mFemaleHeight; } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); float bodyAttr = std::clamp(data.toFloat(), 0.5f, 2.0f); if (mWeight) { if (mMale) record2.mData.mMaleWeight = bodyAttr; else record2.mData.mFemaleWeight = bodyAttr; } else { if (mMale) record2.mData.mMaleHeight = bodyAttr; else record2.mData.mFemaleHeight = bodyAttr; } record.setModified(record2); } bool isEditable() const override { return true; } }; template struct SoundParamColumn : public Column { enum Type { Type_Volume, Type_MinRange, Type_MaxRange }; Type mType; SoundParamColumn(Type type) : Column(type == Type_Volume ? Columns::ColumnId_Volume : (type == Type_MinRange ? Columns::ColumnId_MinRange : Columns::ColumnId_MaxRange), ColumnBase::Display_Integer) , mType(type) { } QVariant get(const Record& record) const override { int value = 0; switch (mType) { case Type_Volume: value = record.get().mData.mVolume; break; case Type_MinRange: value = record.get().mData.mMinRange; break; case Type_MaxRange: value = record.get().mData.mMaxRange; break; } return value; } void set(Record& record, const QVariant& data) override { int value = data.toInt(); if (value < 0) value = 0; else if (value > 255) value = 255; ESXRecordT record2 = record.get(); switch (mType) { case Type_Volume: record2.mData.mVolume = static_cast(value); break; case Type_MinRange: record2.mData.mMinRange = static_cast(value); break; case Type_MaxRange: record2.mData.mMaxRange = static_cast(value); break; } record.setModified(record2); } bool isEditable() const override { return true; } }; template struct SoundFileColumn : public Column { SoundFileColumn() : Column(Columns::ColumnId_SoundFile, ColumnBase::Display_SoundRes) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mSound.c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mSound = data.toString().toUtf8().constData(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct MapColourColumn : public Column { MapColourColumn() : Column(Columns::ColumnId_MapColour, ColumnBase::Display_Colour) { } QVariant get(const Record& record) const override { return record.get().mMapColor; } void set(Record& record, const QVariant& data) override { ESXRecordT copy = record.get(); copy.mMapColor = data.toInt(); record.setModified(copy); } bool isEditable() const override { return true; } }; template struct SleepListColumn : public Column { SleepListColumn() : Column(Columns::ColumnId_SleepEncounter, ColumnBase::Display_CreatureLevelledList) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mSleepList.getRefIdString().c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mSleepList = ESM::RefId::stringRefId(data.toString().toUtf8().constData()); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct TextureColumn : public Column { TextureColumn() : Column(Columns::ColumnId_Texture, ColumnBase::Display_Texture) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mTexture.c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mTexture = data.toString().toUtf8().constData(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct SpellTypeColumn : public Column { SpellTypeColumn() : Column(Columns::ColumnId_SpellType, ColumnBase::Display_SpellType) { } QVariant get(const Record& record) const override { return record.get().mData.mType; } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mType = data.toInt(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct CostColumn : public Column { CostColumn() : Column(Columns::ColumnId_Cost, ColumnBase::Display_Integer) { } QVariant get(const Record& record) const override { return record.get().mData.mCost; } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mCost = data.toInt(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct ScriptColumn : public Column { enum Type { Type_File, // regular script record Type_Lines, // console context Type_Info // dialogue context (not implemented yet) }; ScriptColumn(Type type) : Column(Columns::ColumnId_ScriptText, type == Type_File ? ColumnBase::Display_ScriptFile : ColumnBase::Display_ScriptLines, type == Type_File ? 0 : ColumnBase::Flag_Dialogue) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mScriptText.c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mScriptText = data.toString().toUtf8().constData(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct RegionColumn : public Column { RegionColumn() : Column(Columns::ColumnId_Region, ColumnBase::Display_Region) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mRegion.getRefIdString().c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mRegion = ESM::RefId::stringRefId(data.toString().toUtf8().constData()); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct CellColumn : public Column { bool mBlocked; /// \param blocked Do not allow user-modification CellColumn(bool blocked = false) : Column(Columns::ColumnId_Cell, ColumnBase::Display_Cell) , mBlocked(blocked) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mCell.toString().c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mCell = ESM::RefId::stringRefId(data.toString().toUtf8().constData()); record.setModified(record2); } bool isEditable() const override { return true; } bool isUserEditable() const override { return !mBlocked; } }; template struct OriginalCellColumn : public Column { OriginalCellColumn() : Column(Columns::ColumnId_OriginalCell, ColumnBase::Display_Cell) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mOriginalCell.getRefIdString().c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mOriginalCell = ESM::RefId::stringRefId(data.toString().toUtf8().constData()); record.setModified(record2); } bool isEditable() const override { return true; } bool isUserEditable() const override { return false; } }; template struct IdColumn : public Column { IdColumn() : Column(Columns::ColumnId_ReferenceableId, ColumnBase::Display_Referenceable) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mRefID.getRefIdString().c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mRefID = ESM::RefId::stringRefId(data.toString().toUtf8().constData()); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct ScaleColumn : public Column { ScaleColumn() : Column(Columns::ColumnId_Scale, ColumnBase::Display_Float) { } QVariant get(const Record& record) const override { return record.get().mScale; } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mScale = std::clamp(data.toFloat(), 0.5f, 2.0f); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct OwnerColumn : public Column { OwnerColumn() : Column(Columns::ColumnId_Owner, ColumnBase::Display_Npc) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mOwner.getRefIdString().c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mOwner = ESM::RefId::stringRefId(data.toString().toUtf8().constData()); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct SoulColumn : public Column { SoulColumn() : Column(Columns::ColumnId_Soul, ColumnBase::Display_Creature) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mSoul.getRefIdString().c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mSoul = ESM::RefId::stringRefId(data.toString().toUtf8().constData()); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct FactionColumn : public Column { FactionColumn() : Column(Columns::ColumnId_Faction, ColumnBase::Display_Faction) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mFaction.getRefIdString().c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mFaction = ESM::RefId::stringRefId(data.toString().toUtf8().constData()); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct FactionIndexColumn : public Column { FactionIndexColumn() : Column(Columns::ColumnId_FactionIndex, ColumnBase::Display_Integer) { } QVariant get(const Record& record) const override { return record.get().mFactionRank; } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mFactionRank = data.toInt(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct ChargesColumn : public Column { ChargesColumn() : Column(Columns::ColumnId_Charges, ColumnBase::Display_Integer) { } QVariant get(const Record& record) const override { return record.get().mChargeInt; } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mChargeInt = data.toInt(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct EnchantmentChargesColumn : public Column { EnchantmentChargesColumn() : Column(Columns::ColumnId_Enchantment, ColumnBase::Display_Float) { } QVariant get(const Record& record) const override { return record.get().mEnchantmentCharge; } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mEnchantmentCharge = data.toFloat(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct StackSizeColumn : public Column { StackSizeColumn() : Column(Columns::ColumnId_StackCount, ColumnBase::Display_Integer) { } QVariant get(const Record& record) const override { return record.get().mCount; } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mCount = data.toInt(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct TeleportColumn : public Column { TeleportColumn(int flags) : Column(Columns::ColumnId_Teleport, ColumnBase::Display_Boolean, flags) { } QVariant get(const Record& record) const override { return record.get().mTeleport; } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mTeleport = data.toInt(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct TeleportCellColumn : public Column { TeleportCellColumn() : Column(Columns::ColumnId_TeleportCell, ColumnBase::Display_Cell) { } QVariant get(const Record& record) const override { if (!record.get().mTeleport) return QVariant(); return QString::fromUtf8(record.get().mDestCell.c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mDestCell = data.toString().toUtf8().constData(); record.setModified(record2); } bool isEditable() const override { return true; } bool isUserEditable() const override { return true; } }; template struct IsLockedColumn : public Column { IsLockedColumn(int flags) : Column(Columns::ColumnId_IsLocked, ColumnBase::Display_Boolean, flags) { } QVariant get(const Record& record) const override { return record.get().mIsLocked; } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mIsLocked = data.toBool(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct LockLevelColumn : public Column { LockLevelColumn() : Column(Columns::ColumnId_LockLevel, ColumnBase::Display_Integer) { } QVariant get(const Record& record) const override { if (record.get().mIsLocked) return record.get().mLockLevel; return QVariant(); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mLockLevel = data.toInt(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct KeyColumn : public Column { KeyColumn() : Column(Columns::ColumnId_Key, ColumnBase::Display_Miscellaneous) { } QVariant get(const Record& record) const override { if (record.get().mIsLocked) return QString::fromUtf8(record.get().mKey.getRefIdString().c_str()); return QVariant(); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mKey = ESM::RefId::stringRefId(data.toString().toUtf8().constData()); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct TrapColumn : public Column { TrapColumn() : Column(Columns::ColumnId_Trap, ColumnBase::Display_Spell) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mTrap.getRefIdString().c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mTrap = ESM::RefId::stringRefId(data.toString().toUtf8().constData()); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct FilterColumn : public Column { FilterColumn() : Column(Columns::ColumnId_Filter, ColumnBase::Display_Filter) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mFilter.c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mFilter = data.toString().toUtf8().constData(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct PosColumn : public Column { ESM::Position ESXRecordT::*mPosition; int mIndex; bool mIsDoor; PosColumn(ESM::Position ESXRecordT::*position, int index, bool door) : Column((door ? Columns::ColumnId_DoorPositionXPos : Columns::ColumnId_PositionXPos) + index, ColumnBase::Display_Float) , mPosition(position) , mIndex(index) , mIsDoor(door) { } QVariant get(const Record& record) const override { if (!record.get().mTeleport && mIsDoor) return QVariant(); const ESM::Position& position = record.get().*mPosition; return position.pos[mIndex]; } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); ESM::Position& position = record2.*mPosition; position.pos[mIndex] = data.toFloat(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct RotColumn : public Column { ESM::Position ESXRecordT::*mPosition; int mIndex; bool mIsDoor; RotColumn(ESM::Position ESXRecordT::*position, int index, bool door) : Column((door ? Columns::ColumnId_DoorPositionXRot : Columns::ColumnId_PositionXRot) + index, ColumnBase::Display_Double) , mPosition(position) , mIndex(index) , mIsDoor(door) { } QVariant get(const Record& record) const override { if (!record.get().mTeleport && mIsDoor) return QVariant(); const ESM::Position& position = record.get().*mPosition; return osg::RadiansToDegrees(position.rot[mIndex]); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); ESM::Position& position = record2.*mPosition; position.rot[mIndex] = osg::DegreesToRadians(data.toFloat()); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct DialogueTypeColumn : public Column { DialogueTypeColumn(bool hidden = false) : Column(Columns::ColumnId_DialogueType, ColumnBase::Display_DialogueType, hidden ? 0 : ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue) { } QVariant get(const Record& record) const override { return static_cast(record.get().mType); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mType = static_cast(data.toInt()); record.setModified(record2); } bool isEditable() const override { return true; } bool isUserEditable() const override { return false; } }; template struct QuestStatusTypeColumn : public Column { QuestStatusTypeColumn() : Column(Columns::ColumnId_QuestStatusType, ColumnBase::Display_QuestStatusType) { } QVariant get(const Record& record) const override { return static_cast(record.get().mQuestStatus); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mQuestStatus = static_cast(data.toInt()); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct QuestDescriptionColumn : public Column { QuestDescriptionColumn() : Column(Columns::ColumnId_QuestDescription, ColumnBase::Display_LongString) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mResponse.c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mResponse = data.toString().toUtf8().constData(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct QuestIndexColumn : public Column { QuestIndexColumn() : Column(Columns::ColumnId_QuestIndex, ColumnBase::Display_Integer) { } QVariant get(const Record& record) const override { return record.get().mData.mDisposition; } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mDisposition = data.toInt(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct TopicColumn : public Column { TopicColumn(bool journal) : Column(journal ? Columns::ColumnId_Journal : Columns::ColumnId_Topic, journal ? ColumnBase::Display_Journal : ColumnBase::Display_Topic) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mTopicId.getRefIdString().c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mTopicId = ESM::RefId::stringRefId(data.toString().toUtf8().constData()); record.setModified(record2); } bool isEditable() const override { return true; } bool isUserEditable() const override { return false; } }; template struct ActorColumn : public Column { ActorColumn() : Column(Columns::ColumnId_Actor, ColumnBase::Display_Npc) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mActor.getRefIdString().c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mActor = ESM::RefId::stringRefId(data.toString().toUtf8().constData()); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct RaceColumn : public Column { RaceColumn() : Column(Columns::ColumnId_Race, ColumnBase::Display_Race) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mRace.getRefIdString().c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mRace = ESM::RefId::stringRefId(data.toString().toUtf8().constData()); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct ClassColumn : public Column { ClassColumn() : Column(Columns::ColumnId_Class, ColumnBase::Display_Class) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mClass.getRefIdString().c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mClass = ESM::RefId::stringRefId(data.toString().toUtf8().constData()); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct PcFactionColumn : public Column { PcFactionColumn() : Column(Columns::ColumnId_PcFaction, ColumnBase::Display_Faction) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mPcFaction.getRefIdString().c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mPcFaction = ESM::RefId::stringRefId(data.toString().toUtf8().constData()); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct ResponseColumn : public Column { ResponseColumn() : Column(Columns::ColumnId_Response, ColumnBase::Display_LongString) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mResponse.c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mResponse = data.toString().toUtf8().constData(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct DispositionColumn : public Column { DispositionColumn() : Column(Columns::ColumnId_Disposition, ColumnBase::Display_Integer) { } QVariant get(const Record& record) const override { return record.get().mData.mDisposition; } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mDisposition = data.toInt(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct RankColumn : public Column { RankColumn() : Column(Columns::ColumnId_Rank, ColumnBase::Display_Integer) { } QVariant get(const Record& record) const override { return static_cast(record.get().mData.mRank); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mRank = static_cast(data.toInt()); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct PcRankColumn : public Column { PcRankColumn() : Column(Columns::ColumnId_PcRank, ColumnBase::Display_Integer) { } QVariant get(const Record& record) const override { return static_cast(record.get().mData.mPCrank); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mPCrank = static_cast(data.toInt()); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct GenderColumn : public Column { GenderColumn() : Column(Columns::ColumnId_Gender, ColumnBase::Display_Gender) { } QVariant get(const Record& record) const override { return static_cast(record.get().mData.mGender); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mGender = data.toInt(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct GenderNpcColumn : public Column { GenderNpcColumn() : Column(Columns::ColumnId_Gender, ColumnBase::Display_GenderNpc) { } QVariant get(const Record& record) const override { // Implemented this way to allow additional gender types in the future. if ((record.get().mData.mFlags & ESM::BodyPart::BPF_Female) == ESM::BodyPart::BPF_Female) return 1; return 0; } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); // Implemented this way to allow additional gender types in the future. if (data.toInt() == 1) record2.mData.mFlags = (record2.mData.mFlags & ~ESM::BodyPart::BPF_Female) | ESM::BodyPart::BPF_Female; else record2.mData.mFlags = record2.mData.mFlags & ~ESM::BodyPart::BPF_Female; record.setModified(record2); } bool isEditable() const override { return true; } }; template struct EnchantmentTypeColumn : public Column { EnchantmentTypeColumn() : Column(Columns::ColumnId_EnchantmentType, ColumnBase::Display_EnchantmentType) { } QVariant get(const Record& record) const override { return static_cast(record.get().mData.mType); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mType = data.toInt(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct ChargesColumn2 : public Column { ChargesColumn2() : Column(Columns::ColumnId_Charges, ColumnBase::Display_Integer) { } QVariant get(const Record& record) const override { return record.get().mData.mCharge; } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mCharge = data.toInt(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct AutoCalcColumn : public Column { AutoCalcColumn() : Column(Columns::ColumnId_AutoCalc, ColumnBase::Display_Boolean) { } QVariant get(const Record& record) const override { return record.get().mData.mAutocalc != 0; } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mAutocalc = data.toInt(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct ModelColumn : public Column { ModelColumn() : Column(Columns::ColumnId_Model, ColumnBase::Display_Mesh) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mModel.c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mModel = data.toString().toUtf8().constData(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct VampireColumn : public Column { VampireColumn() : Column(Columns::ColumnId_Vampire, ColumnBase::Display_Boolean) { } QVariant get(const Record& record) const override { return record.get().mData.mVampire != 0; } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mVampire = data.toInt(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct BodyPartTypeColumn : public Column { BodyPartTypeColumn() : Column(Columns::ColumnId_BodyPartType, ColumnBase::Display_BodyPartType) { } QVariant get(const Record& record) const override { return static_cast(record.get().mData.mPart); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mPart = data.toInt(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct MeshTypeColumn : public Column { MeshTypeColumn(int flags = ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue) : Column(Columns::ColumnId_MeshType, ColumnBase::Display_MeshType, flags) { } QVariant get(const Record& record) const override { return static_cast(record.get().mData.mType); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mType = data.toInt(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct OwnerGlobalColumn : public Column { OwnerGlobalColumn() : Column(Columns::ColumnId_OwnerGlobal, ColumnBase::Display_GlobalVariable) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mGlobalVariable.c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mGlobalVariable = data.toString().toUtf8().constData(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct RefNumCounterColumn : public Column { RefNumCounterColumn() : Column(Columns::ColumnId_RefNumCounter, ColumnBase::Display_Integer, 0) { } QVariant get(const Record& record) const override { return static_cast(record.get().mRefNumCounter); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mRefNumCounter = data.toInt(); record.setModified(record2); } bool isEditable() const override { return true; } bool isUserEditable() const override { return false; } }; template struct RefNumColumn : public Column { RefNumColumn() : Column(Columns::ColumnId_RefNum, ColumnBase::Display_Integer, 0) { } QVariant get(const Record& record) const override { return static_cast(record.get().mRefNum.mIndex); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mRefNum.mIndex = data.toInt(); record.setModified(record2); } bool isEditable() const override { return true; } bool isUserEditable() const override { return false; } }; template struct SoundColumn : public Column { SoundColumn() : Column(Columns::ColumnId_Sound, ColumnBase::Display_Sound) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mSound.getRefIdString().c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mSound = ESM::RefId::stringRefId(data.toString().toUtf8().constData()); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct CreatureColumn : public Column { CreatureColumn() : Column(Columns::ColumnId_Creature, ColumnBase::Display_Creature) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mCreature.getRefIdString().c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mCreature = ESM::RefId::stringRefId(data.toString().toUtf8().constData()); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct SoundGeneratorTypeColumn : public Column { SoundGeneratorTypeColumn() : Column(Columns::ColumnId_SoundGeneratorType, ColumnBase::Display_SoundGeneratorType) { } QVariant get(const Record& record) const override { return static_cast(record.get().mType); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mType = data.toInt(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct BaseCostColumn : public Column { BaseCostColumn() : Column(Columns::ColumnId_BaseCost, ColumnBase::Display_Float) { } QVariant get(const Record& record) const override { return record.get().mData.mBaseCost; } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mBaseCost = data.toFloat(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct ProjectileSpeedColumn : public Column { ProjectileSpeedColumn() : Column(Columns::ColumnId_ProjectileSpeed, ColumnBase::Display_Float) { } QVariant get(const Record& record) const override { return record.get().mData.mSpeed; } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mSpeed = data.toFloat(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct SchoolColumn : public Column { SchoolColumn() : Column(Columns::ColumnId_School, ColumnBase::Display_School) { } QVariant get(const Record& record) const override { return ESM::MagicSchool::skillRefIdToIndex(record.get().mData.mSchool); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mSchool = ESM::MagicSchool::indexToSkillRefId(data.toInt()); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct EffectTextureColumn : public Column { EffectTextureColumn(Columns::ColumnId columnId) : Column(columnId, columnId == Columns::ColumnId_Particle ? ColumnBase::Display_Texture : ColumnBase::Display_Icon) { assert(this->mColumnId == Columns::ColumnId_Icon || this->mColumnId == Columns::ColumnId_Particle); } QVariant get(const Record& record) const override { return QString::fromUtf8( (this->mColumnId == Columns::ColumnId_Icon ? record.get().mIcon : record.get().mParticle).c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); (this->mColumnId == Columns::ColumnId_Icon ? record2.mIcon : record2.mParticle) = data.toString().toUtf8().constData(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct EffectObjectColumn : public Column { EffectObjectColumn(Columns::ColumnId columnId) : Column(columnId, columnId == Columns::ColumnId_BoltObject ? ColumnBase::Display_Weapon : ColumnBase::Display_Static) { assert(this->mColumnId == Columns::ColumnId_CastingObject || this->mColumnId == Columns::ColumnId_HitObject || this->mColumnId == Columns::ColumnId_AreaObject || this->mColumnId == Columns::ColumnId_BoltObject); } QVariant get(const Record& record) const override { const ESM::RefId* string = nullptr; switch (this->mColumnId) { case Columns::ColumnId_CastingObject: string = &record.get().mCasting; break; case Columns::ColumnId_HitObject: string = &record.get().mHit; break; case Columns::ColumnId_AreaObject: string = &record.get().mArea; break; case Columns::ColumnId_BoltObject: string = &record.get().mBolt; break; } if (!string) throw std::logic_error("Unsupported column ID"); return QString::fromUtf8(string->getRefIdString().c_str()); } void set(Record& record, const QVariant& data) override { ESM::RefId* id = nullptr; ESXRecordT record2 = record.get(); switch (this->mColumnId) { case Columns::ColumnId_CastingObject: id = &record2.mCasting; break; case Columns::ColumnId_HitObject: id = &record2.mHit; break; case Columns::ColumnId_AreaObject: id = &record2.mArea; break; case Columns::ColumnId_BoltObject: id = &record2.mBolt; break; } if (!id) throw std::logic_error("Unsupported column ID"); *id = ESM::RefId::stringRefId(data.toString().toUtf8().constData()); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct EffectSoundColumn : public Column { EffectSoundColumn(Columns::ColumnId columnId) : Column(columnId, ColumnBase::Display_Sound) { assert(this->mColumnId == Columns::ColumnId_CastingSound || this->mColumnId == Columns::ColumnId_HitSound || this->mColumnId == Columns::ColumnId_AreaSound || this->mColumnId == Columns::ColumnId_BoltSound); } QVariant get(const Record& record) const override { const ESM::RefId* id = nullptr; switch (this->mColumnId) { case Columns::ColumnId_CastingSound: id = &record.get().mCastSound; break; case Columns::ColumnId_HitSound: id = &record.get().mHitSound; break; case Columns::ColumnId_AreaSound: id = &record.get().mAreaSound; break; case Columns::ColumnId_BoltSound: id = &record.get().mBoltSound; break; } if (!id) throw std::logic_error("Unsupported column ID"); return QString::fromUtf8(id->getRefIdString().c_str()); } void set(Record& record, const QVariant& data) override { ESM::RefId* id = nullptr; ESXRecordT record2 = record.get(); switch (this->mColumnId) { case Columns::ColumnId_CastingSound: id = &record2.mCastSound; break; case Columns::ColumnId_HitSound: id = &record2.mHitSound; break; case Columns::ColumnId_AreaSound: id = &record2.mAreaSound; break; case Columns::ColumnId_BoltSound: id = &record2.mBoltSound; break; } if (!id) throw std::logic_error("Unsupported column ID"); *id = ESM::RefId::stringRefId(data.toString().toUtf8().constData()); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct FormatColumn : public Column { FormatColumn() : Column(Columns::ColumnId_FileFormat, ColumnBase::Display_Integer) { } QVariant get(const Record& record) const override { return record.get().mFormatVersion; } bool isEditable() const override { return false; } }; template struct AuthorColumn : public Column { AuthorColumn() : Column(Columns::ColumnId_Author, ColumnBase::Display_String32) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mAuthor.c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mAuthor = data.toString().toUtf8().constData(); record.setModified(record2); } bool isEditable() const override { return true; } }; template struct FileDescriptionColumn : public Column { FileDescriptionColumn() : Column(Columns::ColumnId_FileDescription, ColumnBase::Display_LongString256) { } QVariant get(const Record& record) const override { return QString::fromUtf8(record.get().mDescription.c_str()); } void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mDescription = data.toString().toUtf8().constData(); record.setModified(record2); } bool isEditable() const override { return true; } }; struct LandTextureNicknameColumn : public Column { LandTextureNicknameColumn(); QVariant get(const Record& record) const override; void set(Record& record, const QVariant& data) override; bool isEditable() const override; }; struct LandTextureIndexColumn : public Column { LandTextureIndexColumn(); QVariant get(const Record& record) const override; bool isEditable() const override; }; struct LandPluginIndexColumn : public Column { LandPluginIndexColumn(); QVariant get(const Record& record) const override; bool isEditable() const override; }; struct LandTexturePluginIndexColumn : public Column { LandTexturePluginIndexColumn(); QVariant get(const Record& record) const override; bool isEditable() const override; }; struct LandNormalsColumn : public Column { using DataType = QVector; LandNormalsColumn(); QVariant get(const Record& record) const override; void set(Record& record, const QVariant& data) override; bool isEditable() const override; }; struct LandHeightsColumn : public Column { using DataType = QVector; LandHeightsColumn(); QVariant get(const Record& record) const override; void set(Record& record, const QVariant& data) override; bool isEditable() const override; }; struct LandColoursColumn : public Column { using DataType = QVector; LandColoursColumn(); QVariant get(const Record& record) const override; void set(Record& record, const QVariant& data) override; bool isEditable() const override; }; struct LandTexturesColumn : public Column { using DataType = QVector; LandTexturesColumn(); QVariant get(const Record& record) const override; void set(Record& record, const QVariant& data) override; bool isEditable() const override; }; struct BodyPartRaceColumn : public RaceColumn { const MeshTypeColumn* mMeshType; BodyPartRaceColumn(const MeshTypeColumn* meshType); QVariant get(const Record& record) const override; void set(Record& record, const QVariant& data) override; bool isEditable() const override; }; struct SelectionGroupColumn : public Column { SelectionGroupColumn(); QVariant get(const Record& record) const override; void set(Record& record, const QVariant& data) override; bool isEditable() const override; }; } // This is required to access the type as a QVariant. Q_DECLARE_METATYPE(CSMWorld::LandNormalsColumn::DataType) Q_DECLARE_METATYPE(CSMWorld::LandHeightsColumn::DataType) Q_DECLARE_METATYPE(CSMWorld::LandColoursColumn::DataType) Q_DECLARE_METATYPE(CSMWorld::LandTexturesColumn::DataType) #endif