From 88bc62e05450fbd5b35a9beb76c0cccb50122e15 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 11 Apr 2015 15:55:26 +1000 Subject: [PATCH] Add Region sounds table to dialogue subview. --- apps/opencs/model/world/columnbase.hpp | 1 + apps/opencs/model/world/columnimp.hpp | 46 ++++++++++++ apps/opencs/model/world/columns.cpp | 4 + apps/opencs/model/world/columns.hpp | 4 + apps/opencs/model/world/data.cpp | 8 +- apps/opencs/model/world/data.hpp | 3 +- apps/opencs/model/world/idadapterimp.hpp | 96 +++++++++++++++++++++++- 7 files changed, 156 insertions(+), 6 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index e6799cf56..3902a009b 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -99,6 +99,7 @@ namespace CSMWorld Display_NestedDestinationsList, Display_PathgridPointList, Display_PathgridEdgeList, + Display_RegionSoundList, Display_EnchantmentType, Display_BodyPartType, diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index 3fb9a4685..06467a632 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -2355,6 +2355,52 @@ namespace CSMWorld return true; } }; + + template + struct RegionSoundListColumn : public Column + { + RegionSoundListColumn () + : Column (Columns::ColumnId_RegionSounds, + ColumnBase::Display_RegionSoundList, ColumnBase::Flag_Dialogue) + {} + + virtual QVariant get (const Record& record) const + { + return true; // required by IdTree::hasChildren() + } + + virtual bool isEditable() const + { + return true; + } + + }; + + struct RegionSoundNameColumn : public NestableColumn + { + RegionSoundNameColumn () + : NestableColumn (Columns::ColumnId_SoundName, + ColumnBase::Display_String, ColumnBase::Flag_Dialogue) + {} + + virtual bool isEditable() const + { + return true; + } + }; + + struct RegionSoundChanceColumn : public NestableColumn + { + RegionSoundChanceColumn () + : NestableColumn (Columns::ColumnId_SoundChance, + ColumnBase::Display_Integer, ColumnBase::Flag_Dialogue) + {} + + virtual bool isEditable() const + { + return true; + } + }; } #endif diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index b65cf7f96..39b3ea2e3 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -233,6 +233,10 @@ namespace CSMWorld { ColumnId_PathgridEdge0, "Point 0"}, { ColumnId_PathgridEdge1, "Point 1"}, + { ColumnId_RegionSounds, "Sounds"}, + { ColumnId_SoundName, "Name"}, + { ColumnId_SoundChance, "Chance"}, + { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, { ColumnId_UseValue3, "Use value 3" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 2cb7101b0..49a9208b0 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -222,6 +222,10 @@ namespace CSMWorld ColumnId_PathgridEdge0 = 206, ColumnId_PathgridEdge1 = 207, + ColumnId_RegionSounds = 208, + ColumnId_SoundName = 209, + ColumnId_SoundChance = 210, + // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. ColumnId_UseValue1 = 0x10000, diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 87d5116f1..c387298d2 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -140,6 +140,12 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mRegions.addColumn (new NameColumn); mRegions.addColumn (new MapColourColumn); mRegions.addColumn (new SleepListColumn); + // see idadapterimpl.hpp and columnimp.hpp + RegionSoundListColumn *soundList = new RegionSoundListColumn (); + mRegions.addColumn (soundList); + mRegions.addAdapter (std::make_pair(soundList, new RegionSoundListAdapter ())); + mRegions.getNestableColumn(mRegions.getColumns()-1)->addColumn(new RegionSoundNameColumn ()); + mRegions.getNestableColumn(mRegions.getColumns()-1)->addColumn(new RegionSoundChanceColumn ()); mBirthsigns.addColumn (new StringIdColumn); mBirthsigns.addColumn (new RecordStateColumn); @@ -339,7 +345,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc addModel (new IdTable (&mRaces), UniversalId::Type_Race); addModel (new IdTable (&mSounds), UniversalId::Type_Sound); addModel (new IdTable (&mScripts), UniversalId::Type_Script); - addModel (new IdTable (&mRegions), UniversalId::Type_Region); + addModel (new IdTree (&mRegions, &mRegions), UniversalId::Type_Region); addModel (new IdTable (&mBirthsigns), UniversalId::Type_Birthsign); addModel (new IdTable (&mSpells), UniversalId::Type_Spell); addModel (new IdTable (&mTopics), UniversalId::Type_Topic); diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index b9e060002..329aceaf7 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -34,6 +34,7 @@ #include "../doc/stage.hpp" #include "idcollection.hpp" +#include "nestedidcollection.hpp" #include "universalid.hpp" #include "cell.hpp" #include "land.hpp" @@ -72,7 +73,7 @@ namespace CSMWorld IdCollection mRaces; IdCollection mSounds; IdCollection mScripts; - IdCollection mRegions; + NestedIdCollection mRegions; IdCollection mBirthsigns; IdCollection mSpells; IdCollection mTopics; diff --git a/apps/opencs/model/world/idadapterimp.hpp b/apps/opencs/model/world/idadapterimp.hpp index 7df653059..d5a44aea2 100644 --- a/apps/opencs/model/world/idadapterimp.hpp +++ b/apps/opencs/model/world/idadapterimp.hpp @@ -4,6 +4,7 @@ #include #include +#include #include "idadapter.hpp" #include "nestedtablewrapper.hpp" @@ -127,7 +128,7 @@ namespace CSMWorld case 1: return point.mX; case 2: return point.mY; case 3: return point.mZ; - default: throw std::logic_error("Pathgrid point subcolumn index out of range"); + default: throw std::runtime_error("Pathgrid point subcolumn index out of range"); } } @@ -142,7 +143,7 @@ namespace CSMWorld case 1: point.mX = value.toInt(); break; case 2: point.mY = value.toInt(); break; case 3: point.mZ = value.toInt(); break; - default: throw std::logic_error("Pathgrid point subcolumn index out of range"); + default: throw std::runtime_error("Pathgrid point subcolumn index out of range"); } pathgrid.mPoints[subRowIndex] = point; @@ -223,7 +224,7 @@ namespace CSMWorld case 0: return subRowIndex; case 1: return edge.mV0; case 2: return edge.mV1; - default: throw std::logic_error("Pathgrid edge subcolumn index out of range"); + default: throw std::runtime_error("Pathgrid edge subcolumn index out of range"); } } @@ -238,7 +239,7 @@ namespace CSMWorld case 0: break; case 1: edge.mV0 = value.toInt(); break; case 2: edge.mV1 = value.toInt(); break; - default: throw std::logic_error("Pathgrid edge subcolumn index out of range"); + default: throw std::runtime_error("Pathgrid edge subcolumn index out of range"); } pathgrid.mEdges[subRowIndex] = edge; @@ -256,6 +257,93 @@ namespace CSMWorld return static_cast(record.get().mEdges.size()); } }; + + template + class RegionSoundListAdapter : public NestedIdAdapter + { + public: + RegionSoundListAdapter () {} + + virtual void addNestedRow(Record& record, int position) const + { + ESXRecordT region = record.get(); + + std::vector& soundList = region.mSoundList; + + // blank row + ESXRecordT::SoundRef soundRef; + soundRef.mSound.assign(""); + soundRef.mChance = 0; + + soundList.insert(soundList.begin()+position, soundRef); + + record.setModified (region); + } + + virtual void removeNestedRow(Record& record, int rowToRemove) const + { + ESXRecordT region = record.get(); + + std::vector& soundList = region.mSoundList; + + if (rowToRemove < 0 || rowToRemove >= static_cast (soundList.size())) + throw std::runtime_error ("index out of range"); + + soundList.erase(soundList.begin()+rowToRemove); + + record.setModified (region); + } + + virtual void setNestedTable(Record& record, const NestedTableWrapperBase& nestedTable) const + { + record.get().mSoundList = + static_cast >&>(nestedTable).mNestedTable; + } + + virtual NestedTableWrapperBase* nestedTable(const Record& record) const + { + // deleted by dtor of NestedTableStoring + return new NestedTableWrapper >(record.get().mSoundList); + } + + virtual QVariant getNestedData(const Record& record, int subRowIndex, int subColIndex) const + { + ESXRecordT::SoundRef soundRef = record.get().mSoundList[subRowIndex]; + switch (subColIndex) + { + case 0: return QString(soundRef.mSound.toString().c_str()); + case 1: return soundRef.mChance; + default: throw std::runtime_error("Region sounds subcolumn index out of range"); + } + } + + virtual void setNestedData(Record& record, const QVariant& value, + int subRowIndex, int subColIndex) const + { + ESXRecordT region = record.get(); + ESXRecordT::SoundRef soundRef = region.mSoundList[subRowIndex]; + switch (subColIndex) + { + case 0: soundRef.mSound.assign(value.toString().toUtf8().constData()); break; + case 1: soundRef.mChance = static_cast(value.toInt()); break; + default: throw std::runtime_error("Region sounds subcolumn index out of range"); + } + + region.mSoundList[subRowIndex] = soundRef; + + record.setModified (region); + } + + virtual int getNestedColumnsCount(const Record& record) const + { + return 2; + } + + virtual int getNestedRowsCount(const Record& record) const + { + return static_cast(record.get().mSoundList.size()); + } + }; } #endif // CSM_WOLRD_IDADAPTERIMP_H