1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-21 07:23:54 +00:00
openmw/apps/opencs/model/world/idadapterimp.hpp

243 lines
8.4 KiB
C++
Raw Normal View History

2015-04-09 09:29:03 +00:00
#ifndef CSM_WOLRD_IDADAPTERIMP_H
#define CSM_WOLRD_IDADAPTERIMP_H
#include <QVariant>
#include <components/esm/loadpgrd.hpp>
#include "idadapter.hpp"
namespace CSMWorld
{
struct NestedTableWrapperBase;
2015-04-09 09:29:03 +00:00
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;
2015-04-09 09:29:03 +00:00
// 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)
{
2015-04-09 11:41:46 +00:00
if ((*iter).mV0 >= position)
(*iter).mV0++;
2015-04-09 11:41:46 +00:00
if ((*iter).mV1 >= position)
(*iter).mV1++;
}
2015-04-09 09:29:03 +00:00
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;
2015-04-09 09:29:03 +00:00
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;
}
}
2015-04-09 09:29:03 +00:00
points.erase(points.begin()+rowToRemove);
pathgrid.mData.mS2 -= 1; // decrement the number of points
record.setModified (pathgrid);
}
virtual void setNestedTable(Record<ESXRecordT>& record, const NestedTableWrapperBase& nestedTable)
{
record.get().mPoints =
static_cast<const NestedTableWrapper<ESM::Pathgrid::PointList> &>(nestedTable).mNestedTable;
2015-04-09 09:29:03 +00:00
}
virtual NestedTableWrapperBase* nestedTable(const Record<ESXRecordT>& record) const
{
// deleted by dtor of NestedTableStoring
return new NestedTableWrapper<ESM::Pathgrid::PointList>(record.get().mPoints);
2015-04-09 09:29:03 +00:00
}
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;
2015-04-09 09:29:03 +00:00
default: throw std::logic_error("Pathgrid point subcolumn index out of range");
}
}
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;
2015-04-09 09:29:03 +00:00
default: throw std::logic_error("Pathgrid point subcolumn index out of range");
}
pathgrid.mPoints[subRowIndex] = point;
record.setModified (pathgrid);
}
virtual int getNestedColumnsCount(const Record<ESXRecordT>& record) const
{
return 4;
2015-04-09 09:29:03 +00:00
}
virtual int getNestedRowsCount(const Record<ESXRecordT>& record) const
{
return static_cast<int>(record.get().mPoints.size());
}
};
template<typename ESXRecordT>
class PathgridEdgeListAdapter : public NestedIdAdapter<ESXRecordT>
{
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;
2015-04-09 09:29:03 +00:00
// 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
2015-04-09 09:29:03 +00:00
// 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
2015-04-09 09:29:03 +00:00
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;
2015-04-09 09:29:03 +00:00
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);
}
virtual void setNestedTable(Record<ESXRecordT>& record, const NestedTableWrapperBase& nestedTable)
{
record.get().mEdges =
static_cast<const NestedTableWrapper<ESM::Pathgrid::EdgeList> &>(nestedTable).mNestedTable;
2015-04-09 09:29:03 +00:00
}
virtual NestedTableWrapperBase* nestedTable(const Record<ESXRecordT>& record) const
{
// deleted by dtor of NestedTableStoring
return new NestedTableWrapper<ESM::Pathgrid::EdgeList>(record.get().mEdges);
2015-04-09 09:29:03 +00:00
}
virtual QVariant getNestedData(const Record<ESXRecordT>& record, int subRowIndex, int subColIndex) const
{
ESM::Pathgrid::Edge edge = record.get().mEdges[subRowIndex];
switch (subColIndex)
{
case 0: return subRowIndex;
case 1: return edge.mV0;
case 2: return edge.mV1;
2015-04-09 09:29:03 +00:00
default: throw std::logic_error("Pathgrid edge subcolumn index out of range");
}
}
// FIXME: detect duplicates in mEdges
2015-04-09 09:29:03 +00:00
virtual void setNestedData(Record<ESXRecordT>& record, const QVariant& value,
int subRowIndex, int subColIndex) const
{
ESXRecordT pathgrid = record.get();
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;
2015-04-09 09:29:03 +00:00
default: throw std::logic_error("Pathgrid edge subcolumn index out of range");
}
pathgrid.mEdges[subRowIndex] = edge;
record.setModified (pathgrid);
}
virtual int getNestedColumnsCount(const Record<ESXRecordT>& record) const
{
return 3;
2015-04-09 09:29:03 +00:00
}
virtual int getNestedRowsCount(const Record<ESXRecordT>& record) const
{
return static_cast<int>(record.get().mEdges.size());
}
};
}
#endif // CSM_WOLRD_IDADAPTERIMP_H