Moved templated code around a bit.

test
cc9cii 10 years ago
parent 4b9c9bf095
commit 41b368a759

@ -25,7 +25,7 @@ opencs_units (model/world
opencs_units_noqt (model/world
universalid record commands columnbase scriptcontext cell refidcollection
refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope
pathgrid landtexture land nestedtablewrapper nestedadapters nestedcollection
pathgrid landtexture land nestedtablewrapper nestedadapters nestedcollection idadapterimp
)
opencs_hdrs_noqt (model/world

@ -169,7 +169,8 @@ namespace CSMWorld
template<typename ESXRecordT>
struct NestedParentColumn : public Column<ESXRecordT>
{
NestedParentColumn (int id) : Column<ESXRecordT> (id, Display_NestedHeader, Flag_Dialogue)
NestedParentColumn (int id) : Column<ESXRecordT> (id,
ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue)
{}
virtual QVariant get (const Record<ESXRecordT>& record) const

@ -112,7 +112,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
NestedParentColumn<ESM::Faction> *reactions =
new NestedParentColumn<ESM::Faction> (Columns::ColumnId_FactionReactions);
mFactions.addColumn (reactions);
mFactions.addAdapter (std::make_pair(reactions, new FactionReactionsAdapter<ESM::Faction> ()));
mFactions.addAdapter (std::make_pair(reactions, new FactionReactionsAdapter ()));
mFactions.getNestableColumn(mFactions.getColumns()-1)->addColumn(
new NestedChildColumn (Columns::ColumnId_Faction, ColumnBase::Display_String));
mFactions.getNestableColumn(mFactions.getColumns()-1)->addColumn(
@ -160,7 +160,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
NestedParentColumn<ESM::Region> *soundList =
new NestedParentColumn<ESM::Region> (Columns::ColumnId_RegionSounds);
mRegions.addColumn (soundList);
mRegions.addAdapter (std::make_pair(soundList, new RegionSoundListAdapter<ESM::Region> ()));
mRegions.addAdapter (std::make_pair(soundList, new RegionSoundListAdapter ()));
mRegions.getNestableColumn(mRegions.getColumns()-1)->addColumn(
new NestedChildColumn (Columns::ColumnId_SoundName, ColumnBase::Display_String));
mRegions.getNestableColumn(mRegions.getColumns()-1)->addColumn(
@ -335,7 +335,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
new NestedParentColumn<Pathgrid> (Columns::ColumnId_PathgridPoints);
mPathgrids.addColumn (pointList);
// new object deleted in dtor of SubCellCollection<T,A>
mPathgrids.addAdapter (std::make_pair(pointList, new PathgridPointListAdapter<Pathgrid> ()));
mPathgrids.addAdapter (std::make_pair(pointList, new PathgridPointListAdapter ()));
// new objects deleted in dtor of NestableColumn
// WARNING: The order of the columns below are assumed in PathgridPointListAdapter
mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(
@ -350,7 +350,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
NestedParentColumn<Pathgrid> *edgeList =
new NestedParentColumn<Pathgrid> (Columns::ColumnId_PathgridEdges);
mPathgrids.addColumn (edgeList);
mPathgrids.addAdapter (std::make_pair(edgeList, new PathgridEdgeListAdapter<Pathgrid> ()));
mPathgrids.addAdapter (std::make_pair(edgeList, new PathgridEdgeListAdapter ()));
mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(
new NestedChildColumn (Columns::ColumnId_PathgridEdgeIndex, ColumnBase::Display_Integer, false));
mPathgrids.getNestableColumn(mPathgrids.getColumns()-1)->addColumn(

@ -0,0 +1,457 @@
#include "idadapterimp.hpp"
#include <components/esm/loadregn.hpp>
#include <components/esm/loadfact.hpp>
#include "idcollection.hpp"
#include "pathgrid.hpp"
namespace CSMWorld
{
PathgridPointListAdapter::PathgridPointListAdapter () {}
void PathgridPointListAdapter::addNestedRow(Record<Pathgrid>& record, int position) const
{
Pathgrid pathgrid = record.get();
ESM::Pathgrid::PointList& points = pathgrid.mPoints;
// blank row
ESM::Pathgrid::Point point;
point.mX = 0;
point.mY = 0;
point.mZ = 0;
point.mAutogenerated = 0;
point.mConnectionNum = 0;
point.mUnknown = 0;
// inserting a point should trigger re-indexing of the edges
//
// FIXME: does not auto refresh edges table view
std::vector<ESM::Pathgrid::Edge>::iterator iter = pathgrid.mEdges.begin();
for (;iter != pathgrid.mEdges.end(); ++iter)
{
if ((*iter).mV0 >= position)
(*iter).mV0++;
if ((*iter).mV1 >= position)
(*iter).mV1++;
}
points.insert(points.begin()+position, point);
pathgrid.mData.mS2 += 1; // increment the number of points
record.setModified (pathgrid);
}
void PathgridPointListAdapter::removeNestedRow(Record<Pathgrid>& record, int rowToRemove) const
{
Pathgrid pathgrid = record.get();
ESM::Pathgrid::PointList& points = pathgrid.mPoints;
if (rowToRemove < 0 || rowToRemove >= static_cast<int> (points.size()))
throw std::runtime_error ("index out of range");
// deleting a point should trigger re-indexing of the edges
// dangling edges are not allowed and hence removed
//
// FIXME: does not auto refresh edges table view
std::vector<ESM::Pathgrid::Edge>::iterator iter = pathgrid.mEdges.begin();
for (; iter != pathgrid.mEdges.end();)
{
if (((*iter).mV0 == rowToRemove) || ((*iter).mV1 == rowToRemove))
iter = pathgrid.mEdges.erase(iter);
else
{
if ((*iter).mV0 > rowToRemove)
(*iter).mV0--;
if ((*iter).mV1 > rowToRemove)
(*iter).mV1--;
++iter;
}
}
points.erase(points.begin()+rowToRemove);
pathgrid.mData.mS2 -= 1; // decrement the number of points
record.setModified (pathgrid);
}
void PathgridPointListAdapter::setNestedTable(Record<Pathgrid>& record,
const NestedTableWrapperBase& nestedTable) const
{
record.get().mPoints =
static_cast<const PathgridPointsWrap &>(nestedTable).mRecord.mPoints;
record.get().mData.mS2 =
static_cast<const PathgridPointsWrap &>(nestedTable).mRecord.mData.mS2;
// also update edges in case points were added/removed
record.get().mEdges =
static_cast<const PathgridPointsWrap &>(nestedTable).mRecord.mEdges;
}
NestedTableWrapperBase* PathgridPointListAdapter::nestedTable(const Record<Pathgrid>& record) const
{
// deleted by dtor of NestedTableStoring
return new PathgridPointsWrap(record.get());
}
QVariant PathgridPointListAdapter::getNestedData(const Record<Pathgrid>& record,
int subRowIndex, int subColIndex) const
{
ESM::Pathgrid::Point point = record.get().mPoints[subRowIndex];
switch (subColIndex)
{
case 0: return subRowIndex;
case 1: return point.mX;
case 2: return point.mY;
case 3: return point.mZ;
default: throw std::runtime_error("Pathgrid point subcolumn index out of range");
}
}
void PathgridPointListAdapter::setNestedData(Record<Pathgrid>& record,
const QVariant& value, int subRowIndex, int subColIndex) const
{
Pathgrid pathgrid = record.get();
ESM::Pathgrid::Point point = pathgrid.mPoints[subRowIndex];
switch (subColIndex)
{
case 0: break;
case 1: point.mX = value.toInt(); break;
case 2: point.mY = value.toInt(); break;
case 3: point.mZ = value.toInt(); break;
default: throw std::runtime_error("Pathgrid point subcolumn index out of range");
}
pathgrid.mPoints[subRowIndex] = point;
record.setModified (pathgrid);
}
int PathgridPointListAdapter::getNestedColumnsCount(const Record<Pathgrid>& record) const
{
return 4;
}
int PathgridPointListAdapter::getNestedRowsCount(const Record<Pathgrid>& record) const
{
return static_cast<int>(record.get().mPoints.size());
}
PathgridEdgeListAdapter::PathgridEdgeListAdapter () {}
// ToDo: seems to be auto-sorted in the dialog table display after insertion
void PathgridEdgeListAdapter::addNestedRow(Record<Pathgrid>& record, int position) const
{
Pathgrid pathgrid = record.get();
ESM::Pathgrid::EdgeList& edges = pathgrid.mEdges;
// blank row
ESM::Pathgrid::Edge edge;
edge.mV0 = 0;
edge.mV1 = 0;
// NOTE: inserting a blank edge does not really make sense, perhaps this should be a
// logic_error exception
//
// Currently the code assumes that the end user to know what he/she is doing.
// e.g. Edges come in pairs, from points a->b and b->a
edges.insert(edges.begin()+position, edge);
record.setModified (pathgrid);
}
void PathgridEdgeListAdapter::removeNestedRow(Record<Pathgrid>& record, int rowToRemove) const
{
Pathgrid pathgrid = record.get();
ESM::Pathgrid::EdgeList& edges = pathgrid.mEdges;
if (rowToRemove < 0 || rowToRemove >= static_cast<int> (edges.size()))
throw std::runtime_error ("index out of range");
edges.erase(edges.begin()+rowToRemove);
record.setModified (pathgrid);
}
void PathgridEdgeListAdapter::setNestedTable(Record<Pathgrid>& record,
const NestedTableWrapperBase& nestedTable) const
{
record.get().mEdges =
static_cast<const NestedTableWrapper<ESM::Pathgrid::EdgeList> &>(nestedTable).mNestedTable;
}
NestedTableWrapperBase* PathgridEdgeListAdapter::nestedTable(const Record<Pathgrid>& record) const
{
// deleted by dtor of NestedTableStoring
return new NestedTableWrapper<ESM::Pathgrid::EdgeList>(record.get().mEdges);
}
QVariant PathgridEdgeListAdapter::getNestedData(const Record<Pathgrid>& record,
int subRowIndex, int subColIndex) const
{
Pathgrid pathgrid = record.get();
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (pathgrid.mEdges.size()))
throw std::runtime_error ("index out of range");
ESM::Pathgrid::Edge edge = pathgrid.mEdges[subRowIndex];
switch (subColIndex)
{
case 0: return subRowIndex;
case 1: return edge.mV0;
case 2: return edge.mV1;
default: throw std::runtime_error("Pathgrid edge subcolumn index out of range");
}
}
// ToDo: detect duplicates in mEdges
void PathgridEdgeListAdapter::setNestedData(Record<Pathgrid>& record,
const QVariant& value, int subRowIndex, int subColIndex) const
{
Pathgrid pathgrid = record.get();
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (pathgrid.mEdges.size()))
throw std::runtime_error ("index out of range");
ESM::Pathgrid::Edge edge = pathgrid.mEdges[subRowIndex];
switch (subColIndex)
{
case 0: break;
case 1: edge.mV0 = value.toInt(); break;
case 2: edge.mV1 = value.toInt(); break;
default: throw std::runtime_error("Pathgrid edge subcolumn index out of range");
}
pathgrid.mEdges[subRowIndex] = edge;
record.setModified (pathgrid);
}
int PathgridEdgeListAdapter::getNestedColumnsCount(const Record<Pathgrid>& record) const
{
return 3;
}
int PathgridEdgeListAdapter::getNestedRowsCount(const Record<Pathgrid>& record) const
{
return static_cast<int>(record.get().mEdges.size());
}
FactionReactionsAdapter::FactionReactionsAdapter () {}
void FactionReactionsAdapter::addNestedRow(Record<ESM::Faction>& record, int position) const
{
ESM::Faction faction = record.get();
std::map<std::string, int>& reactions = faction.mReactions;
// blank row
reactions.insert(std::make_pair("", 0));
record.setModified (faction);
}
void FactionReactionsAdapter::removeNestedRow(Record<ESM::Faction>& record, int rowToRemove) const
{
ESM::Faction faction = record.get();
std::map<std::string, int>& reactions = faction.mReactions;
if (rowToRemove < 0 || rowToRemove >= static_cast<int> (reactions.size()))
throw std::runtime_error ("index out of range");
// FIXME: how to ensure that the map entries correspond to table indicies?
// WARNING: Assumed that the table view has the same order as std::map
std::map<std::string, int>::iterator iter = reactions.begin();
for(int i = 0; i < rowToRemove; ++i)
iter++;
reactions.erase(iter);
record.setModified (faction);
}
void FactionReactionsAdapter::setNestedTable(Record<ESM::Faction>& record,
const NestedTableWrapperBase& nestedTable) const
{
record.get().mReactions =
static_cast<const NestedTableWrapper<std::map<std::string, int> >&>(nestedTable).mNestedTable;
}
NestedTableWrapperBase* FactionReactionsAdapter::nestedTable(const Record<ESM::Faction>& record) const
{
// deleted by dtor of NestedTableStoring
return new NestedTableWrapper<std::map<std::string, int> >(record.get().mReactions);
}
QVariant FactionReactionsAdapter::getNestedData(const Record<ESM::Faction>& record,
int subRowIndex, int subColIndex) const
{
ESM::Faction faction = record.get();
std::map<std::string, int>& reactions = faction.mReactions;
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (reactions.size()))
throw std::runtime_error ("index out of range");
// FIXME: how to ensure that the map entries correspond to table indicies?
// WARNING: Assumed that the table view has the same order as std::map
std::map<std::string, int>::const_iterator iter = reactions.begin();
for(int i = 0; i < subRowIndex; ++i)
iter++;
switch (subColIndex)
{
case 0: return QString((*iter).first.c_str());
case 1: return (*iter).second;
default: throw std::runtime_error("Faction reactions subcolumn index out of range");
}
}
void FactionReactionsAdapter::setNestedData(Record<ESM::Faction>& record,
const QVariant& value, int subRowIndex, int subColIndex) const
{
ESM::Faction faction = record.get();
std::map<std::string, int>& reactions = faction.mReactions;
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (reactions.size()))
throw std::runtime_error ("index out of range");
// FIXME: how to ensure that the map entries correspond to table indicies?
// WARNING: Assumed that the table view has the same order as std::map
std::map<std::string, int>::iterator iter = reactions.begin();
for(int i = 0; i < subRowIndex; ++i)
iter++;
std::string factionId = (*iter).first;
int reaction = (*iter).second;
switch (subColIndex)
{
case 0:
{
reactions.erase(iter);
reactions.insert(std::make_pair(value.toString().toUtf8().constData(), reaction));
break;
}
case 1:
{
reactions[factionId] = value.toInt();
break;
}
default: throw std::runtime_error("Faction reactions subcolumn index out of range");
}
record.setModified (faction);
}
int FactionReactionsAdapter::getNestedColumnsCount(const Record<ESM::Faction>& record) const
{
return 2;
}
int FactionReactionsAdapter::getNestedRowsCount(const Record<ESM::Faction>& record) const
{
return static_cast<int>(record.get().mReactions.size());
}
RegionSoundListAdapter::RegionSoundListAdapter () {}
void RegionSoundListAdapter::addNestedRow(Record<ESM::Region>& record, int position) const
{
ESM::Region region = record.get();
std::vector<ESM::Region::SoundRef>& soundList = region.mSoundList;
// blank row
ESM::Region::SoundRef soundRef;
soundRef.mSound.assign("");
soundRef.mChance = 0;
soundList.insert(soundList.begin()+position, soundRef);
record.setModified (region);
}
void RegionSoundListAdapter::removeNestedRow(Record<ESM::Region>& record, int rowToRemove) const
{
ESM::Region region = record.get();
std::vector<ESM::Region::SoundRef>& soundList = region.mSoundList;
if (rowToRemove < 0 || rowToRemove >= static_cast<int> (soundList.size()))
throw std::runtime_error ("index out of range");
soundList.erase(soundList.begin()+rowToRemove);
record.setModified (region);
}
void RegionSoundListAdapter::setNestedTable(Record<ESM::Region>& record,
const NestedTableWrapperBase& nestedTable) const
{
record.get().mSoundList =
static_cast<const NestedTableWrapper<std::vector<ESM::Region::SoundRef> >&>(nestedTable).mNestedTable;
}
NestedTableWrapperBase* RegionSoundListAdapter::nestedTable(const Record<ESM::Region>& record) const
{
// deleted by dtor of NestedTableStoring
return new NestedTableWrapper<std::vector<ESM::Region::SoundRef> >(record.get().mSoundList);
}
QVariant RegionSoundListAdapter::getNestedData(const Record<ESM::Region>& record,
int subRowIndex, int subColIndex) const
{
ESM::Region region = record.get();
std::vector<ESM::Region::SoundRef>& soundList = region.mSoundList;
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (soundList.size()))
throw std::runtime_error ("index out of range");
ESM::Region::SoundRef soundRef = soundList[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");
}
}
void RegionSoundListAdapter::setNestedData(Record<ESM::Region>& record,
const QVariant& value, int subRowIndex, int subColIndex) const
{
ESM::Region region = record.get();
std::vector<ESM::Region::SoundRef>& soundList = region.mSoundList;
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (soundList.size()))
throw std::runtime_error ("index out of range");
ESM::Region::SoundRef soundRef = soundList[subRowIndex];
switch (subColIndex)
{
case 0: soundRef.mSound.assign(value.toString().toUtf8().constData()); break;
case 1: soundRef.mChance = static_cast<unsigned char>(value.toInt()); break;
default: throw std::runtime_error("Region sounds subcolumn index out of range");
}
region.mSoundList[subRowIndex] = soundRef;
record.setModified (region);
}
int RegionSoundListAdapter::getNestedColumnsCount(const Record<ESM::Region>& record) const
{
return 2;
}
int RegionSoundListAdapter::getNestedRowsCount(const Record<ESM::Region>& record) const
{
return static_cast<int>(record.get().mSoundList.size());
}
}

@ -4,8 +4,6 @@
#include <QVariant>
#include <components/esm/loadpgrd.hpp>
#include <components/esm/loadregn.hpp>
#include <components/esm/loadfact.hpp>
#include <components/esm/effectlist.hpp>
#include <components/esm/loadmgef.hpp> // for converting magic effect id to string & back
#include <components/esm/loadskil.hpp> // for converting skill names
@ -14,482 +12,129 @@
#include "idadapter.hpp"
#include "nestedtablewrapper.hpp"
namespace CSMWorld
namespace ESM
{
template<typename ESXRecordT>
class PathgridPointListAdapter : public NestedIdAdapter<ESXRecordT>
{
public:
PathgridPointListAdapter () {}
virtual void addNestedRow(Record<ESXRecordT>& record, int position) const
{
ESXRecordT pathgrid = record.get();
ESM::Pathgrid::PointList& points = pathgrid.mPoints;
// blank row
ESM::Pathgrid::Point point;
point.mX = 0;
point.mY = 0;
point.mZ = 0;
point.mAutogenerated = 0;
point.mConnectionNum = 0;
point.mUnknown = 0;
// inserting a point should trigger re-indexing of the edges
//
// FIXME: undo does not restore edges table view
// FIXME: does not auto refresh edges table view
std::vector<ESM::Pathgrid::Edge>::iterator iter = pathgrid.mEdges.begin();
for (;iter != pathgrid.mEdges.end(); ++iter)
{
if ((*iter).mV0 >= position)
(*iter).mV0++;
if ((*iter).mV1 >= position)
(*iter).mV1++;
}
points.insert(points.begin()+position, point);
pathgrid.mData.mS2 += 1; // increment the number of points
record.setModified (pathgrid);
}
virtual void removeNestedRow(Record<ESXRecordT>& record, int rowToRemove) const
{
ESXRecordT pathgrid = record.get();
ESM::Pathgrid::PointList& points = pathgrid.mPoints;
if (rowToRemove < 0 || rowToRemove >= static_cast<int> (points.size()))
throw std::runtime_error ("index out of range");
// deleting a point should trigger re-indexing of the edges
// dangling edges are not allowed and hence removed
//
// FIXME: undo does not restore edges table view
// FIXME: does not auto refresh edges table view
std::vector<ESM::Pathgrid::Edge>::iterator iter = pathgrid.mEdges.begin();
for (; iter != pathgrid.mEdges.end();)
{
if (((*iter).mV0 == rowToRemove) || ((*iter).mV1 == rowToRemove))
iter = pathgrid.mEdges.erase(iter);
else
{
if ((*iter).mV0 > rowToRemove)
(*iter).mV0--;
if ((*iter).mV1 > rowToRemove)
(*iter).mV1--;
++iter;
}
}
points.erase(points.begin()+rowToRemove);
pathgrid.mData.mS2 -= 1; // decrement the number of points
record.setModified (pathgrid);
}
struct PathgridPointsWrap : public NestedTableWrapperBase
{
ESM::Pathgrid mRecord;
PathgridPointsWrap(ESM::Pathgrid pathgrid)
: mRecord(pathgrid) {}
virtual ~PathgridPointsWrap() {}
virtual int size() const
{
return mRecord.mPoints.size(); // used in IdTree::setNestedTable()
}
};
virtual void setNestedTable(Record<ESXRecordT>& record, const NestedTableWrapperBase& nestedTable) const
{
record.get().mPoints =
static_cast<const PathgridPointsWrap &>(nestedTable).mRecord.mPoints;
record.get().mData.mS2 =
static_cast<const PathgridPointsWrap &>(nestedTable).mRecord.mData.mS2;
// also update edges in case points were added/removed
record.get().mEdges =
static_cast<const PathgridPointsWrap &>(nestedTable).mRecord.mEdges;
}
virtual NestedTableWrapperBase* nestedTable(const Record<ESXRecordT>& record) const
{
// deleted by dtor of NestedTableStoring
return new PathgridPointsWrap(record.get());
}
virtual QVariant getNestedData(const Record<ESXRecordT>& record, int subRowIndex, int subColIndex) const
{
ESM::Pathgrid::Point point = record.get().mPoints[subRowIndex];
switch (subColIndex)
{
case 0: return subRowIndex;
case 1: return point.mX;
case 2: return point.mY;
case 3: return point.mZ;
default: throw std::runtime_error("Pathgrid point subcolumn index out of range");
}
}
struct Faction;
struct Region;
}
virtual void setNestedData(Record<ESXRecordT>& record, const QVariant& value,
int subRowIndex, int subColIndex) const
{
ESXRecordT pathgrid = record.get();
ESM::Pathgrid::Point point = pathgrid.mPoints[subRowIndex];
switch (subColIndex)
{
case 0: break;
case 1: point.mX = value.toInt(); break;
case 2: point.mY = value.toInt(); break;
case 3: point.mZ = value.toInt(); break;
default: throw std::runtime_error("Pathgrid point subcolumn index out of range");
}
namespace CSMWorld
{
struct Pathgrid;
pathgrid.mPoints[subRowIndex] = point;
struct PathgridPointsWrap : public NestedTableWrapperBase
{
ESM::Pathgrid mRecord;
record.setModified (pathgrid);
}
PathgridPointsWrap(ESM::Pathgrid pathgrid)
: mRecord(pathgrid) {}
virtual int getNestedColumnsCount(const Record<ESXRecordT>& record) const
{
return 4;
}
virtual ~PathgridPointsWrap() {}
virtual int getNestedRowsCount(const Record<ESXRecordT>& record) const
virtual int size() const
{
return static_cast<int>(record.get().mPoints.size());
return mRecord.mPoints.size(); // used in IdTree::setNestedTable()
}
};
template<typename ESXRecordT>
class PathgridEdgeListAdapter : public NestedIdAdapter<ESXRecordT>
class PathgridPointListAdapter : public NestedIdAdapter<Pathgrid>
{
public:
PathgridEdgeListAdapter () {}
// FIXME: seems to be auto-sorted in the dialog table display after insertion
virtual void addNestedRow(Record<ESXRecordT>& record, int position) const
{
ESXRecordT pathgrid = record.get();
ESM::Pathgrid::EdgeList& edges = pathgrid.mEdges;
// blank row
ESM::Pathgrid::Edge edge;
edge.mV0 = 0;
edge.mV1 = 0;
// NOTE: inserting a blank edge does not really make sense, perhaps this should be a
// logic_error exception
//
// Currently the code assumes that the end user to know what he/she is doing.
// e.g. Edges come in pairs, from points a->b and b->a
edges.insert(edges.begin()+position, edge);
record.setModified (pathgrid);
}
virtual void removeNestedRow(Record<ESXRecordT>& record, int rowToRemove) const
{
ESXRecordT pathgrid = record.get();
ESM::Pathgrid::EdgeList& edges = pathgrid.mEdges;
if (rowToRemove < 0 || rowToRemove >= static_cast<int> (edges.size()))
throw std::runtime_error ("index out of range");
edges.erase(edges.begin()+rowToRemove);
record.setModified (pathgrid);
}
PathgridPointListAdapter ();
virtual void setNestedTable(Record<ESXRecordT>& record, const NestedTableWrapperBase& nestedTable) const
{
record.get().mEdges =
static_cast<const NestedTableWrapper<ESM::Pathgrid::EdgeList> &>(nestedTable).mNestedTable;
}
virtual NestedTableWrapperBase* nestedTable(const Record<ESXRecordT>& record) const
{
// deleted by dtor of NestedTableStoring
return new NestedTableWrapper<ESM::Pathgrid::EdgeList>(record.get().mEdges);
}
virtual QVariant getNestedData(const Record<ESXRecordT>& record, int subRowIndex, int subColIndex) const
{
ESXRecordT pathgrid = record.get();
virtual void addNestedRow(Record<Pathgrid>& record, int position) const;
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (pathgrid.mEdges.size()))
throw std::runtime_error ("index out of range");
ESM::Pathgrid::Edge edge = pathgrid.mEdges[subRowIndex];
switch (subColIndex)
{
case 0: return subRowIndex;
case 1: return edge.mV0;
case 2: return edge.mV1;
default: throw std::runtime_error("Pathgrid edge subcolumn index out of range");
}
}
virtual void removeNestedRow(Record<Pathgrid>& record, int rowToRemove) const;
// FIXME: detect duplicates in mEdges
virtual void setNestedData(Record<ESXRecordT>& record, const QVariant& value,
int subRowIndex, int subColIndex) const
{
ESXRecordT pathgrid = record.get();
virtual void setNestedTable(Record<Pathgrid>& record,
const NestedTableWrapperBase& nestedTable) const;
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (pathgrid.mEdges.size()))
throw std::runtime_error ("index out of range");
virtual NestedTableWrapperBase* nestedTable(const Record<Pathgrid>& record) const;
ESM::Pathgrid::Edge edge = pathgrid.mEdges[subRowIndex];
switch (subColIndex)
{
case 0: break;
case 1: edge.mV0 = value.toInt(); break;
case 2: edge.mV1 = value.toInt(); break;
default: throw std::runtime_error("Pathgrid edge subcolumn index out of range");
}
virtual QVariant getNestedData(const Record<Pathgrid>& record,
int subRowIndex, int subColIndex) const;
pathgrid.mEdges[subRowIndex] = edge;
virtual void setNestedData(Record<Pathgrid>& record,
const QVariant& value, int subRowIndex, int subColIndex) const;
record.setModified (pathgrid);
}
virtual int getNestedColumnsCount(const Record<Pathgrid>& record) const;
virtual int getNestedColumnsCount(const Record<ESXRecordT>& record) const
{
return 3;
}
virtual int getNestedRowsCount(const Record<ESXRecordT>& record) const
{
return static_cast<int>(record.get().mEdges.size());
}
virtual int getNestedRowsCount(const Record<Pathgrid>& record) const;
};
template<typename ESXRecordT>
class FactionReactionsAdapter : public NestedIdAdapter<ESXRecordT>
class PathgridEdgeListAdapter : public NestedIdAdapter<Pathgrid>
{
public:
FactionReactionsAdapter () {}
virtual void addNestedRow(Record<ESXRecordT>& record, int position) const
{
ESXRecordT faction = record.get();
std::map<std::string, int>& reactions = faction.mReactions;
// blank row
reactions.insert(std::make_pair("", 0));
record.setModified (faction);
}
virtual void removeNestedRow(Record<ESXRecordT>& record, int rowToRemove) const
{
ESXRecordT faction = record.get();
std::map<std::string, int>& reactions = faction.mReactions;
if (rowToRemove < 0 || rowToRemove >= static_cast<int> (reactions.size()))
throw std::runtime_error ("index out of range");
// FIXME: how to ensure that the map entries correspond to table indicies?
// WARNING: Assumed that the table view has the same order as std::map
std::map<std::string, int>::iterator iter = reactions.begin();
for(int i = 0; i < rowToRemove; ++i)
iter++;
reactions.erase(iter);
record.setModified (faction);
}
virtual void setNestedTable(Record<ESXRecordT>& record, const NestedTableWrapperBase& nestedTable) const
{
record.get().mReactions =
static_cast<const NestedTableWrapper<std::map<std::string, int> >&>(nestedTable).mNestedTable;
}
virtual NestedTableWrapperBase* nestedTable(const Record<ESXRecordT>& record) const
{
// deleted by dtor of NestedTableStoring
return new NestedTableWrapper<std::map<std::string, int> >(record.get().mReactions);
}
virtual QVariant getNestedData(const Record<ESXRecordT>& record, int subRowIndex, int subColIndex) const
{
ESXRecordT faction = record.get();
std::map<std::string, int>& reactions = faction.mReactions;
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (reactions.size()))
throw std::runtime_error ("index out of range");
// FIXME: how to ensure that the map entries correspond to table indicies?
// WARNING: Assumed that the table view has the same order as std::map
std::map<std::string, int>::const_iterator iter = reactions.begin();
for(int i = 0; i < subRowIndex; ++i)
iter++;
switch (subColIndex)
{
case 0: return QString((*iter).first.c_str());
case 1: return (*iter).second;
default: throw std::runtime_error("Faction reactions subcolumn index out of range");
}
}
PathgridEdgeListAdapter ();
virtual void setNestedData(Record<ESXRecordT>& record, const QVariant& value,
int subRowIndex, int subColIndex) const
{
ESXRecordT faction = record.get();
virtual void addNestedRow(Record<Pathgrid>& record, int position) const;
std::map<std::string, int>& reactions = faction.mReactions;
virtual void removeNestedRow(Record<Pathgrid>& record, int rowToRemove) const;
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (reactions.size()))
throw std::runtime_error ("index out of range");
virtual void setNestedTable(Record<Pathgrid>& record,
const NestedTableWrapperBase& nestedTable) const;
// FIXME: how to ensure that the map entries correspond to table indicies?
// WARNING: Assumed that the table view has the same order as std::map
std::map<std::string, int>::iterator iter = reactions.begin();
for(int i = 0; i < subRowIndex; ++i)
iter++;
virtual NestedTableWrapperBase* nestedTable(const Record<Pathgrid>& record) const;
std::string factionId = (*iter).first;
int reaction = (*iter).second;
switch (subColIndex)
{
case 0:
{
reactions.erase(iter);
reactions.insert(std::make_pair(value.toString().toUtf8().constData(), reaction));
break;
}
case 1:
{
reactions[factionId] = value.toInt();
break;
}
default: throw std::runtime_error("Faction reactions subcolumn index out of range");
}
virtual QVariant getNestedData(const Record<Pathgrid>& record,
int subRowIndex, int subColIndex) const;
record.setModified (faction);
}
virtual void setNestedData(Record<Pathgrid>& record,
const QVariant& value, int subRowIndex, int subColIndex) const;
virtual int getNestedColumnsCount(const Record<ESXRecordT>& record) const
{
return 2;
}
virtual int getNestedColumnsCount(const Record<Pathgrid>& record) const;
virtual int getNestedRowsCount(const Record<ESXRecordT>& record) const
{
return static_cast<int>(record.get().mReactions.size());
}
virtual int getNestedRowsCount(const Record<Pathgrid>& record) const;
};
template<typename ESXRecordT>
class RegionSoundListAdapter : public NestedIdAdapter<ESXRecordT>
class FactionReactionsAdapter : public NestedIdAdapter<ESM::Faction>
{
public:
RegionSoundListAdapter () {}
virtual void addNestedRow(Record<ESXRecordT>& record, int position) const
{
ESXRecordT region = record.get();
std::vector<typename ESXRecordT::SoundRef>& soundList = region.mSoundList;
FactionReactionsAdapter ();
// blank row
typename ESXRecordT::SoundRef soundRef;
soundRef.mSound.assign("");
soundRef.mChance = 0;
soundList.insert(soundList.begin()+position, soundRef);
record.setModified (region);
}
virtual void removeNestedRow(Record<ESXRecordT>& record, int rowToRemove) const
{
ESXRecordT region = record.get();
virtual void addNestedRow(Record<ESM::Faction>& record, int position) const;
std::vector<typename ESXRecordT::SoundRef>& soundList = region.mSoundList;
virtual void removeNestedRow(Record<ESM::Faction>& record, int rowToRemove) const;
if (rowToRemove < 0 || rowToRemove >= static_cast<int> (soundList.size()))
throw std::runtime_error ("index out of range");
soundList.erase(soundList.begin()+rowToRemove);
record.setModified (region);
}
virtual void setNestedTable(Record<ESM::Faction>& record,
const NestedTableWrapperBase& nestedTable) const;
virtual void setNestedTable(Record<ESXRecordT>& record, const NestedTableWrapperBase& nestedTable) const
{
record.get().mSoundList =
static_cast<const NestedTableWrapper<std::vector<typename ESXRecordT::SoundRef> >&>(nestedTable).mNestedTable;
}
virtual NestedTableWrapperBase* nestedTable(const Record<ESM::Faction>& record) const;
virtual NestedTableWrapperBase* nestedTable(const Record<ESXRecordT>& record) const
{
// deleted by dtor of NestedTableStoring
return new NestedTableWrapper<std::vector<typename ESXRecordT::SoundRef> >(record.get().mSoundList);
}
virtual QVariant getNestedData(const Record<ESM::Faction>& record,
int subRowIndex, int subColIndex) const;
virtual QVariant getNestedData(const Record<ESXRecordT>& record, int subRowIndex, int subColIndex) const
{
ESXRecordT region = record.get();
virtual void setNestedData(Record<ESM::Faction>& record,
const QVariant& value, int subRowIndex, int subColIndex) const;
std::vector<typename ESXRecordT::SoundRef>& soundList = region.mSoundList;
virtual int getNestedColumnsCount(const Record<ESM::Faction>& record) const;
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (soundList.size()))
throw std::runtime_error ("index out of range");
virtual int getNestedRowsCount(const Record<ESM::Faction>& record) const;
};
typename ESXRecordT::SoundRef soundRef = soundList[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");
}
}
class RegionSoundListAdapter : public NestedIdAdapter<ESM::Region>
{
public:
RegionSoundListAdapter ();
virtual void setNestedData(Record<ESXRecordT>& record, const QVariant& value,
int subRowIndex, int subColIndex) const
{
ESXRecordT region = record.get();
virtual void addNestedRow(Record<ESM::Region>& record, int position) const;
std::vector<typename ESXRecordT::SoundRef>& soundList = region.mSoundList;
virtual void removeNestedRow(Record<ESM::Region>& record, int rowToRemove) const;
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (soundList.size()))
throw std::runtime_error ("index out of range");
virtual void setNestedTable(Record<ESM::Region>& record,
const NestedTableWrapperBase& nestedTable) const;
typename ESXRecordT::SoundRef soundRef = soundList[subRowIndex];
switch (subColIndex)
{
case 0: soundRef.mSound.assign(value.toString().toUtf8().constData()); break;
case 1: soundRef.mChance = static_cast<unsigned char>(value.toInt()); break;
default: throw std::runtime_error("Region sounds subcolumn index out of range");
}
virtual NestedTableWrapperBase* nestedTable(const Record<ESM::Region>& record) const;
region.mSoundList[subRowIndex] = soundRef;
virtual QVariant getNestedData(const Record<ESM::Region>& record,
int subRowIndex, int subColIndex) const;
record.setModified (region);
}
virtual void setNestedData(Record<ESM::Region>& record,
const QVariant& value, int subRowIndex, int subColIndex) const;
virtual int getNestedColumnsCount(const Record<ESXRecordT>& record) const
{
return 2;
}
virtual int getNestedColumnsCount(const Record<ESM::Region>& record) const;
virtual int getNestedRowsCount(const Record<ESXRecordT>& record) const
{
return static_cast<int>(record.get().mSoundList.size());
}
virtual int getNestedRowsCount(const Record<ESM::Region>& record) const;
};
template<typename ESXRecordT>

Loading…
Cancel
Save