mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-30 22:26:41 +00:00 
			
		
		
		
	Saving to document via UndoStack implemented.
This commit is contained in:
		
							parent
							
								
									0e3e3cbae2
								
							
						
					
					
						commit
						27a73a25e3
					
				
					 10 changed files with 186 additions and 72 deletions
				
			
		|  | @ -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
 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -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(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
|     { |     { | ||||||
|  |  | ||||||
|  | @ -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: | ||||||
|  |  | ||||||
							
								
								
									
										26
									
								
								apps/opencs/model/world/pathgridpointswrap.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								apps/opencs/model/world/pathgridpointswrap.hpp
									
									
									
									
									
										Normal 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
 | ||||||
|  | @ -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
 | ||||||
|  |  | ||||||
|  | @ -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(); | ||||||
|  |  | ||||||
|  | @ -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)); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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()); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue