1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-02-03 13:45:32 +00:00

Saving to document via UndoStack implemented.

This commit is contained in:
cc9cii 2015-04-23 08:50:05 +10:00
parent 0e3e3cbae2
commit 27a73a25e3
10 changed files with 186 additions and 72 deletions

View file

@ -244,3 +244,29 @@ const CSMWorld::NestedTableWrapperBase& CSMWorld::NestedTableStoring::getOld() c
{ {
return *mOld; return *mOld;
} }
// Current interface does not allow adding a non-blank row, so we're forced to modify
// the whole record.
CSMWorld::ModifyPathgridCommand::ModifyPathgridCommand(IdTree& model,
const std::string& id, int parentColumn, NestedTableWrapperBase* newRecord, QUndoCommand* parent)
: mModel(model), mId(id), mParentColumn(parentColumn), mRecord(newRecord)
, QUndoCommand(parent), NestedTableStoring(model, id, parentColumn)
{
setText (("Modify Pathgrid record " + mId).c_str()); // FIXME: better description
}
void CSMWorld::ModifyPathgridCommand::redo()
{
const QModelIndex& parentIndex = mModel.getModelIndex(mId, mParentColumn);
mModel.setNestedTable(parentIndex, *mRecord);
}
void CSMWorld::ModifyPathgridCommand::undo()
{
const QModelIndex& parentIndex = mModel.getModelIndex(mId, mParentColumn);
mModel.setNestedTable(parentIndex, getOld());
// FIXME: needs to tell the cell to redraw, possibly using signals
}

View file

@ -168,7 +168,8 @@ namespace CSMWorld
public: public:
DeleteNestedCommand (IdTree& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent = 0); DeleteNestedCommand (IdTree& model,
const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent = 0);
virtual void redo(); virtual void redo();
@ -187,7 +188,28 @@ namespace CSMWorld
public: public:
AddNestedCommand(IdTree& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent = 0); AddNestedCommand(IdTree& model,
const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent = 0);
virtual void redo();
virtual void undo();
};
class ModifyPathgridCommand : public QUndoCommand, private NestedTableStoring
{
IdTree& mModel;
std::string mId;
int mParentColumn;
NestedTableWrapperBase* mRecord;
public:
// if newEdges is NULL, only the paths are updated
ModifyPathgridCommand(IdTree& model, const std::string& id, int parentColumn,
NestedTableWrapperBase* newRecord, QUndoCommand* parent = 0);
virtual void redo(); virtual void redo();

View file

@ -248,6 +248,10 @@ void CSMWorld::IdTree::setNestedTable(const QModelIndex& index, const CSMWorld::
{ {
emit resetEnd(this->index(index.row(), 0).data().toString()); emit resetEnd(this->index(index.row(), 0).data().toString());
} }
// FIXME: Removing pathgrid points will also remove pathgrid edges, but we have
// no way of emitting signals to indicate those changes. In addition, the
// removed edges can be any index (and there can be several edges removed
// but always by a factor of two)
} }
CSMWorld::NestedTableWrapperBase* CSMWorld::IdTree::nestedTable(const QModelIndex& index) const CSMWorld::NestedTableWrapperBase* CSMWorld::IdTree::nestedTable(const QModelIndex& index) const

View file

@ -6,6 +6,7 @@
#include "idcollection.hpp" #include "idcollection.hpp"
#include "pathgrid.hpp" #include "pathgrid.hpp"
#include "info.hpp" #include "info.hpp"
#include "pathgridpointswrap.hpp"
namespace CSMWorld namespace CSMWorld
{ {
@ -147,6 +148,8 @@ namespace CSMWorld
PathgridEdgeListAdapter::PathgridEdgeListAdapter () {} PathgridEdgeListAdapter::PathgridEdgeListAdapter () {}
// ToDo: seems to be auto-sorted in the dialog table display after insertion // ToDo: seems to be auto-sorted in the dialog table display after insertion
//
// FIXME: edges should be added in pairs
void PathgridEdgeListAdapter::addRow(Record<Pathgrid>& record, int position) const void PathgridEdgeListAdapter::addRow(Record<Pathgrid>& record, int position) const
{ {
Pathgrid pathgrid = record.get(); Pathgrid pathgrid = record.get();
@ -168,6 +171,7 @@ namespace CSMWorld
record.setModified (pathgrid); record.setModified (pathgrid);
} }
// FIXME: edges should be removed in pairs and Point.mConnectionNum updated
void PathgridEdgeListAdapter::removeRow(Record<Pathgrid>& record, int rowToRemove) const void PathgridEdgeListAdapter::removeRow(Record<Pathgrid>& record, int rowToRemove) const
{ {
Pathgrid pathgrid = record.get(); Pathgrid pathgrid = record.get();
@ -218,6 +222,8 @@ namespace CSMWorld
} }
// ToDo: detect duplicates in mEdges // ToDo: detect duplicates in mEdges
//
// FIXME: Point.mConnectionNum needs to be updated
void PathgridEdgeListAdapter::setData(Record<Pathgrid>& record, void PathgridEdgeListAdapter::setData(Record<Pathgrid>& record,
const QVariant& value, int subRowIndex, int subColIndex) const const QVariant& value, int subRowIndex, int subColIndex) const
{ {

View file

@ -3,7 +3,6 @@
#include <QVariant> #include <QVariant>
#include <components/esm/loadpgrd.hpp>
#include <components/esm/effectlist.hpp> #include <components/esm/effectlist.hpp>
#include <components/esm/loadmgef.hpp> // for converting magic effect id to string & back #include <components/esm/loadmgef.hpp> // for converting magic effect id to string & back
#include <components/esm/loadskil.hpp> // for converting skill names #include <components/esm/loadskil.hpp> // for converting skill names
@ -23,21 +22,6 @@ namespace CSMWorld
struct Pathgrid; struct Pathgrid;
struct Info; struct Info;
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()
}
};
class PathgridPointListAdapter : public NestedColumnAdapter<Pathgrid> class PathgridPointListAdapter : public NestedColumnAdapter<Pathgrid>
{ {
public: public:

View file

@ -0,0 +1,26 @@
#ifndef CSM_WOLRD_PATHGRIDPOINTSWRAP_H
#define CSM_WOLRD_PATHGRIDPOINTSWRAP_H
#include <components/esm/loadpgrd.hpp>
#include "nestedtablewrapper.hpp"
namespace CSMWorld
{
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()
}
};
}
#endif // CSM_WOLRD_PATHGRIDPOINTSWRAP_H

View file

@ -8,11 +8,16 @@
#include <components/misc/stringops.hpp> #include <components/misc/stringops.hpp>
#include <components/esm/loadland.hpp> #include <components/esm/loadland.hpp>
#include "../../model/doc/document.hpp"
#include "../../model/world/idtable.hpp" #include "../../model/world/idtable.hpp"
#include "../../model/world/idtree.hpp"
#include "../../model/world/columns.hpp" #include "../../model/world/columns.hpp"
#include "../../model/world/data.hpp" #include "../../model/world/data.hpp"
#include "../../model/world/refcollection.hpp" #include "../../model/world/refcollection.hpp"
#include "../../model/world/pathgrid.hpp" #include "../../model/world/pathgrid.hpp"
#include "../../model/world/commands.hpp"
#include "../../model/world/pathgridpointswrap.hpp"
#include "../../model/world/nestedtableproxymodel.hpp"
#include "../world/physicssystem.hpp" #include "../world/physicssystem.hpp"
#include "elements.hpp" #include "elements.hpp"
@ -92,7 +97,7 @@ bool CSVRender::Cell::addObjects (int start, int end)
{ {
bool modified = false; bool modified = false;
const CSMWorld::RefCollection& collection = mData.getReferences(); const CSMWorld::RefCollection& collection = mDocument.getData().getReferences();
for (int i=start; i<=end; ++i) for (int i=start; i<=end; ++i)
{ {
@ -104,7 +109,7 @@ bool CSVRender::Cell::addObjects (int start, int end)
{ {
std::string id = Misc::StringUtils::lowerCase (collection.getRecord (i).get().mId); std::string id = Misc::StringUtils::lowerCase (collection.getRecord (i).get().mId);
mObjects.insert (std::make_pair (id, new Object (mData, mCellNode, id, false, mPhysics))); mObjects.insert (std::make_pair (id, new Object (mDocument.getData(), mCellNode, id, false, mPhysics)));
modified = true; modified = true;
} }
} }
@ -112,29 +117,29 @@ bool CSVRender::Cell::addObjects (int start, int end)
return modified; return modified;
} }
CSVRender::Cell::Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager, CSVRender::Cell::Cell (CSMDoc::Document& document, Ogre::SceneManager *sceneManager,
const std::string& id, boost::shared_ptr<CSVWorld::PhysicsSystem> physics, const Ogre::Vector3& origin) const std::string& id, boost::shared_ptr<CSVWorld::PhysicsSystem> physics, const Ogre::Vector3& origin)
: mData (data), mId (Misc::StringUtils::lowerCase (id)), mSceneMgr(sceneManager), mPhysics(physics), mX(0), mY(0), : mDocument (document), mId (Misc::StringUtils::lowerCase (id)), mSceneMgr(sceneManager)
mPathgridId("") , mPhysics(physics), mX(0), mY(0), mPgIndex(-1), mModel(0), mProxyModel(0)// ,mPathgridId("")
{ {
mCellNode = sceneManager->getRootSceneNode()->createChildSceneNode(); mCellNode = sceneManager->getRootSceneNode()->createChildSceneNode();
mCellNode->setPosition (origin); mCellNode->setPosition (origin);
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> ( CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
*mData.getTableModel (CSMWorld::UniversalId::Type_References)); *mDocument.getData().getTableModel (CSMWorld::UniversalId::Type_References));
int rows = references.rowCount(); int rows = references.rowCount();
addObjects (0, rows-1); addObjects (0, rows-1);
const CSMWorld::IdCollection<CSMWorld::Land>& land = mData.getLand(); const CSMWorld::IdCollection<CSMWorld::Land>& land = mDocument.getData().getLand();
int landIndex = land.searchId(mId); int landIndex = land.searchId(mId);
if (landIndex != -1) if (landIndex != -1)
{ {
const ESM::Land* esmLand = land.getRecord(mId).get().mLand.get(); const ESM::Land* esmLand = land.getRecord(mId).get().mLand.get();
if(esmLand && esmLand->mDataTypes&ESM::Land::DATA_VHGT) if(esmLand && esmLand->mDataTypes&ESM::Land::DATA_VHGT)
{ {
mTerrain.reset(new Terrain::TerrainGrid(sceneManager, new TerrainStorage(mData), Element_Terrain, true, mTerrain.reset(new Terrain::TerrainGrid(sceneManager, new TerrainStorage(mDocument.getData()), Element_Terrain, true,
Terrain::Align_XY)); Terrain::Align_XY));
mTerrain->loadCell(esmLand->mX, mTerrain->loadCell(esmLand->mX,
esmLand->mY); esmLand->mY);
@ -174,6 +179,8 @@ CSVRender::Cell::~Cell()
delete iter->second; delete iter->second;
} }
delete mProxyModel;
if (mTerrain.get()) if (mTerrain.get())
mPhysics->removeHeightField(mSceneMgr, mX, mY); mPhysics->removeHeightField(mSceneMgr, mX, mY);
@ -217,7 +224,7 @@ bool CSVRender::Cell::referenceDataChanged (const QModelIndex& topLeft,
const QModelIndex& bottomRight) const QModelIndex& bottomRight)
{ {
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> ( CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
*mData.getTableModel (CSMWorld::UniversalId::Type_References)); *mDocument.getData().getTableModel (CSMWorld::UniversalId::Type_References));
int idColumn = references.findColumnIndex (CSMWorld::Columns::ColumnId_Id); int idColumn = references.findColumnIndex (CSMWorld::Columns::ColumnId_Id);
int cellColumn = references.findColumnIndex (CSMWorld::Columns::ColumnId_Cell); int cellColumn = references.findColumnIndex (CSMWorld::Columns::ColumnId_Cell);
@ -269,7 +276,7 @@ bool CSVRender::Cell::referenceDataChanged (const QModelIndex& topLeft,
for (std::map<std::string, bool>::iterator iter (ids.begin()); iter!=ids.end(); ++iter) for (std::map<std::string, bool>::iterator iter (ids.begin()); iter!=ids.end(); ++iter)
{ {
mObjects.insert (std::make_pair ( mObjects.insert (std::make_pair (
iter->first, new Object (mData, mCellNode, iter->first, false, mPhysics))); iter->first, new Object (mDocument.getData(), mCellNode, iter->first, false, mPhysics)));
modified = true; modified = true;
} }
@ -284,7 +291,7 @@ bool CSVRender::Cell::referenceAboutToBeRemoved (const QModelIndex& parent, int
return false; return false;
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> ( CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
*mData.getTableModel (CSMWorld::UniversalId::Type_References)); *mDocument.getData().getTableModel (CSMWorld::UniversalId::Type_References));
int idColumn = references.findColumnIndex (CSMWorld::Columns::ColumnId_Id); int idColumn = references.findColumnIndex (CSMWorld::Columns::ColumnId_Id);
@ -323,14 +330,22 @@ void CSVRender::Cell::loadPathgrid()
{ {
int worldsize = ESM::Land::REAL_SIZE; int worldsize = ESM::Land::REAL_SIZE;
CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& pathgridCollection = mData.getPathgrids(); const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& pathgrids = mDocument.getData().getPathgrids();
int index = pathgridCollection.searchId(mId); int index = pathgrids.searchId(mId);
if(index != -1) if(index != -1)
{ {
const CSMWorld::Pathgrid &pathgrid = pathgridCollection.getRecord(index).get(); mPgIndex = index; // keep a copy to save from searching mId all the time
mPathgridId = pathgrid.mId; // FIXME: temporary storage (should be document)
int col = pathgrids.findColumnIndex(CSMWorld::Columns::ColumnId_PathgridPoints);
mModel = dynamic_cast<CSMWorld::IdTree *>(
mDocument.getData().getTableModel(CSMWorld::UniversalId::Type_Pathgrid));
mProxyModel = new CSMWorld::NestedTableProxyModel (mModel->index(mPgIndex, col),
CSMWorld::ColumnBase::Display_NestedHeader, mModel);
const CSMWorld::Pathgrid &pathgrid = pathgrids.getRecord(index).get();
mPoints.resize(pathgrid.mPoints.size());
std::vector<ESM::Pathgrid::Point>::const_iterator iter = pathgrid.mPoints.begin(); std::vector<ESM::Pathgrid::Point>::const_iterator iter = pathgrid.mPoints.begin();
for(index = 0; iter != pathgrid.mPoints.end(); ++iter, ++index) for(index = 0; iter != pathgrid.mPoints.end(); ++iter, ++index)
{ {
@ -340,7 +355,6 @@ void CSVRender::Cell::loadPathgrid()
Ogre::Vector3(worldsize*mX+(*iter).mX, worldsize*mY+(*iter).mY, (*iter).mZ); Ogre::Vector3(worldsize*mX+(*iter).mX, worldsize*mY+(*iter).mY, (*iter).mZ);
mPgPoints.insert(std::make_pair(name, new PathgridPoint(name, mCellNode, pos, mPhysics))); mPgPoints.insert(std::make_pair(name, new PathgridPoint(name, mCellNode, pos, mPhysics)));
mPoints[index] = *iter; // FIXME: temporary storage (should be document)
} }
for(ESM::Pathgrid::EdgeList::const_iterator it = pathgrid.mEdges.begin(); for(ESM::Pathgrid::EdgeList::const_iterator it = pathgrid.mEdges.begin();
@ -363,16 +377,17 @@ void CSVRender::Cell::loadPathgrid()
node->attachObject(line); node->attachObject(line);
mPgEdges.insert(std::make_pair(std::make_pair(edge.mV0, edge.mV1), name)); mPgEdges.insert(std::make_pair(std::make_pair(edge.mV0, edge.mV1), name));
mEdges.push_back(*it); // FIXME: temporary storage (should be document)
} }
} }
} }
// NOTE: pos is in world coordinates // NOTE: pos is in world coordinates
// FIXME: save to the document
void CSVRender::Cell::pathgridPointAdded(const Ogre::Vector3 &pos, bool interior) void CSVRender::Cell::pathgridPointAdded(const Ogre::Vector3 &pos, bool interior)
{ {
std::string name = PathgridPoint::getName(mId, mPoints.size()); const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& pathgrids = mDocument.getData().getPathgrids();
CSMWorld::Pathgrid pathgrid = pathgrids.getRecord(mPgIndex).get();
std::string name = PathgridPoint::getName(mId, pathgrid.mPoints.size()); // generate a new name
mPgPoints.insert(std::make_pair(name, new PathgridPoint(name, mCellNode, pos, mPhysics))); mPgPoints.insert(std::make_pair(name, new PathgridPoint(name, mCellNode, pos, mPhysics)));
@ -389,12 +404,18 @@ void CSVRender::Cell::pathgridPointAdded(const Ogre::Vector3 &pos, bool interior
ESM::Pathgrid::Point point(x, y, (int)pos.z); ESM::Pathgrid::Point point(x, y, (int)pos.z);
point.mConnectionNum = 0; point.mConnectionNum = 0;
mPoints.push_back(point); pathgrid.mPoints.push_back(point);
mPathgridId = mId;
// FIXME: update other scene managers // FIXME: update other scene managers
pathgrid.mData.mS2 += 1; // increment the number of points
// FIXME: probably will crash if this cell is deleted and undo() is actioned afterwards
mDocument.getUndoStack().push(new CSMWorld::ModifyPathgridCommand(*mModel,
mProxyModel->getParentId(), mProxyModel->getParentColumn(),
new CSMWorld::PathgridPointsWrap(pathgrid)));
// emit signal here?
} }
// FIXME: save to the document
void CSVRender::Cell::pathgridPointRemoved(const std::string &name) void CSVRender::Cell::pathgridPointRemoved(const std::string &name)
{ {
std::pair<std::string, int> result = PathgridPoint::getIdAndIndex(name); std::pair<std::string, int> result = PathgridPoint::getIdAndIndex(name);
@ -404,18 +425,21 @@ void CSVRender::Cell::pathgridPointRemoved(const std::string &name)
std::string pathgridId = result.first; std::string pathgridId = result.first;
int index = result.second; int index = result.second;
const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& pathgrids = mDocument.getData().getPathgrids();
CSMWorld::Pathgrid pathgrid = pathgrids.getRecord(mPgIndex).get();
// check if the point exists // check if the point exists
if(index < 0 || mPathgridId != pathgridId || (unsigned int)index >= mPoints.size()) if(index < 0 || (unsigned int)index >= pathgrid.mPoints.size())
return; return;
int numToDelete = mPoints[index].mConnectionNum * 2; // for sanity check later int numToDelete = pathgrid.mPoints[index].mConnectionNum * 2; // for sanity check later
int edgeCount = 0; int edgeCount = 0;
// find edges to delete // find edges to delete
std::vector<std::pair<int, int> > edges; std::vector<std::pair<int, int> > edges;
for(unsigned i = 0; i < mEdges.size(); ++i) for(unsigned i = 0; i < pathgrid.mEdges.size(); ++i)
{ {
if(mEdges[i].mV0 == index || mEdges[i].mV1 == index) if(pathgrid.mEdges[i].mV0 == index || pathgrid.mEdges[i].mV1 == index)
{ {
for(std::map<std::pair<int, int>, std::string>::iterator iter = mPgEdges.begin(); for(std::map<std::pair<int, int>, std::string>::iterator iter = mPgEdges.begin();
iter != mPgEdges.end(); ++iter) iter != mPgEdges.end(); ++iter)
@ -448,12 +472,12 @@ void CSVRender::Cell::pathgridPointRemoved(const std::string &name)
mPgEdges.erase(*iter); mPgEdges.erase(*iter);
// update document // update document
assert(mPoints[(*iter).first].mConnectionNum > 0); assert(pathgrid.mPoints[(*iter).first].mConnectionNum > 0);
mPoints[(*iter).first].mConnectionNum -= 1; pathgrid.mPoints[(*iter).first].mConnectionNum -= 1;
for(unsigned i = mEdges.size() - 1; i > 0; --i) for(unsigned i = pathgrid.mEdges.size() - 1; i > 0; --i)
{ {
if(mEdges[i].mV0 == index || mEdges[i].mV1 == index) if(pathgrid.mEdges[i].mV0 == index || pathgrid.mEdges[i].mV1 == index)
mEdges.erase(mEdges.begin() + i); pathgrid.mEdges.erase(pathgrid.mEdges.begin() + i);
} }
} }
} }
@ -462,10 +486,10 @@ void CSVRender::Cell::pathgridPointRemoved(const std::string &name)
{ {
// WARNING: continue anyway? Or should this be an exception? // WARNING: continue anyway? Or should this be an exception?
std::cerr << "The no of edges del does not match the no of conn for: " std::cerr << "The no of edges del does not match the no of conn for: "
<< mPathgridId + "_" + QString::number(index).toStdString() << std::endl; << pathgridId + "_" + QString::number(index).toStdString() << std::endl;
} }
if(edgeCount || mPoints[index].mConnectionNum == 0) if(edgeCount || pathgrid.mPoints[index].mConnectionNum == 0)
{ {
// remove the point // remove the point
delete mPgPoints[name]; delete mPgPoints[name];
@ -477,6 +501,13 @@ void CSVRender::Cell::pathgridPointRemoved(const std::string &name)
//mPoints.erase(mPoints.begin() + index); // WARNING: Can't erase because the index will change //mPoints.erase(mPoints.begin() + index); // WARNING: Can't erase because the index will change
// FIXME: it should be possible to refresh indicies but that means index values // FIXME: it should be possible to refresh indicies but that means index values
// can't be stored in maps, names, etc // can't be stored in maps, names, etc
// FIXME: probably will crash if this cell is deleted and undo() is actioned afterwards
mDocument.getUndoStack().push(new CSMWorld::ModifyPathgridCommand(*mModel,
mProxyModel->getParentId(), mProxyModel->getParentColumn(), new CSMWorld::PathgridPointsWrap(pathgrid)));
} }
// NOTE: newPos is in world coordinates // NOTE: newPos is in world coordinates
@ -490,8 +521,11 @@ void CSVRender::Cell::pathgridPointMoved(const std::string &name,
std::string pathgridId = result.first; std::string pathgridId = result.first;
int index = result.second; int index = result.second;
const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& pathgrids = mDocument.getData().getPathgrids();
CSMWorld::Pathgrid pathgrid = pathgrids.getRecord(mPgIndex).get();
// check if the point exists // check if the point exists
if(index < 0 || mPathgridId != pathgridId || (unsigned int)index >= mPoints.size()) if(index < 0 || (unsigned int)index >= pathgrid.mPoints.size())
return; return;
int worldsize = ESM::Land::REAL_SIZE; int worldsize = ESM::Land::REAL_SIZE;
@ -504,17 +538,17 @@ void CSVRender::Cell::pathgridPointMoved(const std::string &name,
y = y - (worldsize * mY); y = y - (worldsize * mY);
} }
mPoints[index].mX = x; pathgrid.mPoints[index].mX = x;
mPoints[index].mY = y; pathgrid.mPoints[index].mY = y;
mPoints[index].mZ = newPos.z; pathgrid.mPoints[index].mZ = newPos.z;
// delete then recreate the edges // delete then recreate the edges
for(unsigned i = 0; i < mEdges.size(); ++i) for(unsigned i = 0; i < pathgrid.mEdges.size(); ++i)
{ {
if(mEdges[i].mV0 == index || mEdges[i].mV1 == index) if(pathgrid.mEdges[i].mV0 == index || pathgrid.mEdges[i].mV1 == index)
{ {
std::ostringstream stream; std::ostringstream stream;
stream << pathgridId << "_" << mEdges[i].mV0 << " " << mEdges[i].mV1; stream << pathgridId << "_" << pathgrid.mEdges[i].mV0 << " " << pathgrid.mEdges[i].mV1;
std::string name = stream.str(); std::string name = stream.str();
if(mSceneMgr->hasManualObject(name)) if(mSceneMgr->hasManualObject(name))
@ -524,9 +558,9 @@ void CSVRender::Cell::pathgridPointMoved(const std::string &name,
Ogre::SceneNode *node = manual->getParentSceneNode(); Ogre::SceneNode *node = manual->getParentSceneNode();
mSceneMgr->destroyManualObject(name); mSceneMgr->destroyManualObject(name);
if(mEdges[i].mV0 == index) if(pathgrid.mEdges[i].mV0 == index)
{ {
const ESM::Pathgrid::Point &p1 = mPoints[mEdges[i].mV1]; const ESM::Pathgrid::Point &p1 = pathgrid.mPoints[pathgrid.mEdges[i].mV1];
Ogre::ManualObject *line = createPathgridEdge(name, Ogre::ManualObject *line = createPathgridEdge(name,
newPos, newPos,
@ -534,9 +568,9 @@ void CSVRender::Cell::pathgridPointMoved(const std::string &name,
line->setVisibilityFlags(Element_Pathgrid); line->setVisibilityFlags(Element_Pathgrid);
node->attachObject(line); node->attachObject(line);
} }
else if(mEdges[i].mV1 == index) else if(pathgrid.mEdges[i].mV1 == index)
{ {
const ESM::Pathgrid::Point &p0 = mPoints[mEdges[i].mV0]; const ESM::Pathgrid::Point &p0 = pathgrid.mPoints[pathgrid.mEdges[i].mV0];
Ogre::ManualObject *line = createPathgridEdge(name, Ogre::ManualObject *line = createPathgridEdge(name,
Ogre::Vector3(worldsize*mX+p0.mX, worldsize*mY+p0.mY, p0.mZ), Ogre::Vector3(worldsize*mX+p0.mX, worldsize*mY+p0.mY, p0.mZ),
@ -547,6 +581,11 @@ void CSVRender::Cell::pathgridPointMoved(const std::string &name,
} }
} }
} }
// FIXME: probably will crash if this cell is deleted and undo() is actioned afterwards
mDocument.getUndoStack().push(new CSMWorld::ModifyPathgridCommand(*mModel,
mProxyModel->getParentId(), mProxyModel->getParentColumn(),
new CSMWorld::PathgridPointsWrap(pathgrid)));
} }
// FIXME: save to the document // FIXME: save to the document

View file

@ -25,10 +25,17 @@ namespace Ogre
class ManualObject; class ManualObject;
} }
namespace CSMDoc
{
class Document;
}
namespace CSMWorld namespace CSMWorld
{ {
class Data; //class Data;
class Pathgrid; class Pathgrid;
class NestedTableProxyModel;
class IdTree;
} }
namespace CSVWorld namespace CSVWorld
@ -42,16 +49,16 @@ namespace CSVRender
class Cell class Cell
{ {
CSMWorld::Data& mData; CSMDoc::Document& mDocument;
std::string mId; std::string mId;
Ogre::SceneNode *mCellNode; Ogre::SceneNode *mCellNode;
std::map<std::string, Object *> mObjects; std::map<std::string, Object *> mObjects;
std::map<std::string, PathgridPoint *> mPgPoints; std::map<std::string, PathgridPoint *> mPgPoints;
std::map<std::pair<int, int>, std::string> mPgEdges; std::map<std::pair<int, int>, std::string> mPgEdges;
ESM::Pathgrid::PointList mPoints; // FIXME: temporary storage until saving to document CSMWorld::NestedTableProxyModel *mProxyModel;
ESM::Pathgrid::EdgeList mEdges; // FIXME: temporary storage until saving to document CSMWorld::IdTree *mModel;
std::string mPathgridId; // FIXME: temporary storage until saving to document int mPgIndex;
std::auto_ptr<Terrain::TerrainGrid> mTerrain; std::auto_ptr<Terrain::TerrainGrid> mTerrain;
boost::shared_ptr<CSVWorld::PhysicsSystem> mPhysics; boost::shared_ptr<CSVWorld::PhysicsSystem> mPhysics;
@ -71,7 +78,7 @@ namespace CSVRender
public: public:
Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager, const std::string& id, Cell (CSMDoc::Document& document, Ogre::SceneManager *sceneManager, const std::string& id,
boost::shared_ptr<CSVWorld::PhysicsSystem> physics, const Ogre::Vector3& origin = Ogre::Vector3 (0, 0, 0)); boost::shared_ptr<CSVWorld::PhysicsSystem> physics, const Ogre::Vector3& origin = Ogre::Vector3 (0, 0, 0));
~Cell(); ~Cell();

View file

@ -113,7 +113,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells()
if (index > 0 && cells.getRecord (index).mState!=CSMWorld::RecordBase::State_Deleted && if (index > 0 && cells.getRecord (index).mState!=CSMWorld::RecordBase::State_Deleted &&
mCells.find (*iter)==mCells.end()) mCells.find (*iter)==mCells.end())
{ {
Cell *cell = new Cell (mDocument.getData(), getSceneManager(), Cell *cell = new Cell (mDocument, getSceneManager(),
iter->getId (mWorldspace), mDocument.getPhysics()); iter->getId (mWorldspace), mDocument.getPhysics());
mCells.insert (std::make_pair (*iter, cell)); mCells.insert (std::make_pair (*iter, cell));

View file

@ -49,7 +49,7 @@ CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string&
update(); update();
mCell.reset (new Cell (document.getData(), getSceneManager(), mCellId, document.getPhysics())); mCell.reset (new Cell (document, getSceneManager(), mCellId, document.getPhysics()));
} }
void CSVRender::UnpagedWorldspaceWidget::cellDataChanged (const QModelIndex& topLeft, void CSVRender::UnpagedWorldspaceWidget::cellDataChanged (const QModelIndex& topLeft,
@ -91,7 +91,7 @@ bool CSVRender::UnpagedWorldspaceWidget::handleDrop (const std::vector<CSMWorld:
return false; return false;
mCellId = data.begin()->getId(); mCellId = data.begin()->getId();
mCell.reset (new Cell (getDocument().getData(), getSceneManager(), mCellId, getDocument().getPhysics())); mCell.reset (new Cell (getDocument(), getSceneManager(), mCellId, getDocument().getPhysics()));
update(); update();
emit cellChanged(*data.begin()); emit cellChanged(*data.begin());