diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 5822b433a..35d5e5d3c 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -18,7 +18,8 @@ opencs_hdrs_noqt (model/doc opencs_units (model/world - idtable idtableproxymodel regionmap data commanddispatcher idtablebase resourcetable nestedtableproxymodel idtree + idtable idtableproxymodel regionmap data commanddispatcher idtablebase resourcetable + nestedtableproxymodel idtree pathgridcommands ) diff --git a/apps/opencs/model/world/commands.cpp b/apps/opencs/model/world/commands.cpp index 172211d7b..d12c5d228 100644 --- a/apps/opencs/model/world/commands.cpp +++ b/apps/opencs/model/world/commands.cpp @@ -6,7 +6,6 @@ #include "idtree.hpp" #include #include "nestedtablewrapper.hpp" -#include "../../view/render/cell.hpp" CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelIndex& index, const QVariant& new_, QUndoCommand* parent) @@ -245,31 +244,3 @@ const CSMWorld::NestedTableWrapperBase& CSMWorld::NestedTableStoring::getOld() c { 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, CSVRender::Cell *cell, - NestedTableWrapperBase* newRecord, QUndoCommand* parent) - : mModel(model), mId(id), mParentColumn(parentColumn), mRecord(newRecord), mCell(cell) - , 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()); - - mCell->clearPathgrid(); - mCell->buildPathgrid(); -} diff --git a/apps/opencs/model/world/commands.hpp b/apps/opencs/model/world/commands.hpp index 8661f987a..0cd8a00f8 100644 --- a/apps/opencs/model/world/commands.hpp +++ b/apps/opencs/model/world/commands.hpp @@ -12,16 +12,11 @@ #include #include "universalid.hpp" -#include "nestedtablewrapper.hpp" +//#include "nestedtablewrapper.hpp" class QModelIndex; class QAbstractItemModel; -namespace CSVRender -{ - class Cell; -} - namespace CSMWorld { class IdTable; @@ -200,28 +195,6 @@ namespace CSMWorld virtual void undo(); }; - - class ModifyPathgridCommand : public QUndoCommand, private NestedTableStoring - { - IdTree& mModel; - std::string mId; - - int mParentColumn; - - NestedTableWrapperBase* mRecord; - CSVRender::Cell *mCell; - - public: - - // if newEdges is NULL, only the paths are updated - ModifyPathgridCommand(IdTree& model, - const std::string& id, int parentColumn, CSVRender::Cell *cell, - NestedTableWrapperBase* newRecord, QUndoCommand* parent = 0); - - virtual void redo(); - - virtual void undo(); - }; } #endif diff --git a/apps/opencs/model/world/pathgridcommands.cpp b/apps/opencs/model/world/pathgridcommands.cpp new file mode 100644 index 000000000..356806dcd --- /dev/null +++ b/apps/opencs/model/world/pathgridcommands.cpp @@ -0,0 +1,48 @@ +#include "pathgridcommands.hpp" + +#include "../../view/render/cell.hpp" +#include "idtree.hpp" +#include "nestedtablewrapper.hpp" + +// 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()); + + emit undoActioned(); +} + +void CSMWorld::SignalHandler::rebuildPathgrid() +{ + mParent->clearPathgrid(); + mParent->buildPathgrid(); + + emit flagAsModified(); +} + +CSMWorld::SignalHandler::SignalHandler (CSVRender::Cell *parent) : mParent(parent) +{} + +void CSMWorld::SignalHandler::connectToCommand(const CSMWorld::ModifyPathgridCommand *command) +{ + connect (command, SIGNAL(undoActioned()), + this, SLOT(rebuildPathgrid())); +} diff --git a/apps/opencs/model/world/pathgridcommands.hpp b/apps/opencs/model/world/pathgridcommands.hpp new file mode 100644 index 000000000..335e3a893 --- /dev/null +++ b/apps/opencs/model/world/pathgridcommands.hpp @@ -0,0 +1,65 @@ +#ifndef CSM_WOLRD_PATHGRIDCOMMANDS_H +#define CSM_WOLRD_PATHGRIDCOMMANDS_H + +#include + +#include "commands.hpp" + +namespace CSVRender +{ + class Cell; +} + +namespace CSMWorld +{ + class IdTree; + class NestedTableWrapperBase; + + class ModifyPathgridCommand : public QObject, public QUndoCommand, private NestedTableStoring + { + Q_OBJECT + + IdTree& mModel; + std::string mId; + + int mParentColumn; + + NestedTableWrapperBase* mRecord; + + public: + + ModifyPathgridCommand(IdTree& model, + const std::string& id, int parentColumn, NestedTableWrapperBase* newRecord, + QUndoCommand* parent = 0); + + virtual void redo(); + + virtual void undo(); + + signals: + + void undoActioned(); + }; + + class SignalHandler : public QObject + { + Q_OBJECT + + CSVRender::Cell *mParent; + + public: + + SignalHandler (CSVRender::Cell *parent); + + void connectToCommand(const ModifyPathgridCommand *command); + + private slots: + + void rebuildPathgrid(); + + signals: + + void flagAsModified(); + }; +} +#endif // CSM_WOLRD_PATHGRIDCOMMANDS_H diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index 87f70b48e..7976fd55e 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -16,6 +16,7 @@ #include "../../model/world/refcollection.hpp" #include "../../model/world/pathgrid.hpp" #include "../../model/world/commands.hpp" +#include "../../model/world/pathgridcommands.hpp" #include "../../model/world/pathgridpointswrap.hpp" #include "../../model/world/nestedtableproxymodel.hpp" #include "../world/physicssystem.hpp" @@ -119,8 +120,9 @@ bool CSVRender::Cell::addObjects (int start, int end) CSVRender::Cell::Cell (CSMDoc::Document& document, Ogre::SceneManager *sceneManager, const std::string& id, boost::shared_ptr physics, const Ogre::Vector3& origin) -: mDocument (document), mId (Misc::StringUtils::lowerCase (id)), mSceneMgr(sceneManager) -, mPhysics(physics), mX(0), mY(0), mPgIndex(-1), mModel(0), mProxyModel(0) + : mDocument (document), mId (Misc::StringUtils::lowerCase (id)), mSceneMgr(sceneManager) + , mPhysics(physics), mX(0), mY(0), mPgIndex(-1), mModel(0), mProxyModel(0) + , mHandler(new CSMWorld::SignalHandler(this)) { mCellNode = sceneManager->getRootSceneNode()->createChildSceneNode(); mCellNode->setPosition (origin); @@ -163,6 +165,7 @@ CSVRender::Cell::~Cell() destroyGridMaterials(); delete mProxyModel; + delete mHandler; if (mTerrain.get()) mPhysics->removeHeightField(mSceneMgr, mX, mY); @@ -431,10 +434,12 @@ void CSVRender::Cell::pathgridPointAdded(const Ogre::Vector3 &pos, bool interior 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(), this, - new CSMWorld::PathgridPointsWrap(pathgrid))); + // FIXME: possible issue if this cell is deleted and undo() is actioned afterwards + CSMWorld::ModifyPathgridCommand *cmd = new CSMWorld::ModifyPathgridCommand(*mModel, + mProxyModel->getParentId(), mProxyModel->getParentColumn(), + new CSMWorld::PathgridPointsWrap(pathgrid)); + mHandler->connectToCommand(cmd); + mDocument.getUndoStack().push(cmd); // emit signal here? } @@ -488,10 +493,12 @@ void CSVRender::Cell::pathgridPointRemoved(const std::string &name) << pathgridId + "_" + QString::number(index).toStdString() << std::endl; } - // 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(), this, - new CSMWorld::PathgridPointsWrap(pathgrid))); + // FIXME: possible issue if this cell is deleted and undo() is actioned afterwards + CSMWorld::ModifyPathgridCommand *cmd = new CSMWorld::ModifyPathgridCommand(*mModel, + mProxyModel->getParentId(), mProxyModel->getParentColumn(), + new CSMWorld::PathgridPointsWrap(pathgrid)); + mHandler->connectToCommand(cmd); + mDocument.getUndoStack().push(cmd); clearPathgrid(); buildPathgrid(); @@ -529,10 +536,12 @@ void CSVRender::Cell::pathgridPointMoved(const std::string &name, pathgrid.mPoints[index].mY = y; pathgrid.mPoints[index].mZ = newPos.z; - // 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(), this, - new CSMWorld::PathgridPointsWrap(pathgrid))); + // FIXME: possible issue if this cell is deleted and undo() is actioned afterwards + CSMWorld::ModifyPathgridCommand *cmd = new CSMWorld::ModifyPathgridCommand(*mModel, + mProxyModel->getParentId(), mProxyModel->getParentColumn(), + new CSMWorld::PathgridPointsWrap(pathgrid)); + mHandler->connectToCommand(cmd); + mDocument.getUndoStack().push(cmd); clearPathgrid(); buildPathgrid(); @@ -551,3 +560,8 @@ void CSVRender::Cell::addPathgridEdge() void CSVRender::Cell::removePathgridEdge() { } + +CSMWorld::SignalHandler *CSVRender::Cell::getSignalHandler() +{ + return mHandler; +} diff --git a/apps/opencs/view/render/cell.hpp b/apps/opencs/view/render/cell.hpp index fac4ded59..cc00ee1c8 100644 --- a/apps/opencs/view/render/cell.hpp +++ b/apps/opencs/view/render/cell.hpp @@ -31,10 +31,10 @@ namespace CSMDoc namespace CSMWorld { - //class Data; class Pathgrid; class NestedTableProxyModel; class IdTree; + class SignalHandler; } namespace CSVWorld @@ -58,6 +58,7 @@ namespace CSVRender CSMWorld::NestedTableProxyModel *mProxyModel; CSMWorld::IdTree *mModel; int mPgIndex; + CSMWorld::SignalHandler *mHandler; std::auto_ptr mTerrain; boost::shared_ptr mPhysics; @@ -126,6 +127,7 @@ namespace CSVRender void clearPathgrid(); void buildPathgrid(); + CSMWorld::SignalHandler *getSignalHandler(); }; } diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index cc00b9159..130f5c409 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -19,6 +19,7 @@ #include "../../model/world/tablemimedata.hpp" #include "../../model/world/idtable.hpp" +#include "../../model/world/pathgridcommands.hpp" #include "../widget/scenetooltoggle.hpp" #include "../widget/scenetoolmode.hpp" @@ -115,6 +116,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() { Cell *cell = new Cell (mDocument, getSceneManager(), iter->getId (mWorldspace), mDocument.getPhysics()); + connect (cell->getSignalHandler(), SIGNAL(flagAsModified()), this, SLOT(flagAsModSlot())); mCells.insert (std::make_pair (*iter, cell)); float height = cell->getTerrainHeightAt(Ogre::Vector3( @@ -637,3 +639,8 @@ void CSVRender::PagedWorldspaceWidget::cellAdded (const QModelIndex& index, int if (adjustCells()) flagAsModified(); } + +void CSVRender::PagedWorldspaceWidget::flagAsModSlot () +{ + flagAsModified(); +} diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index 45e5dd8f7..099b4db25 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -120,6 +120,7 @@ namespace CSVRender virtual void cellAdded (const QModelIndex& index, int start, int end); + virtual void flagAsModSlot(); }; } diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index b5e9504f3..c95a87d03 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -13,6 +13,7 @@ #include "../../model/world/data.hpp" #include "../../model/world/idtable.hpp" #include "../../model/world/tablemimedata.hpp" +#include "../../model/world/pathgridcommands.hpp" #include "../widget/scenetooltoggle.hpp" #include "../widget/scenetooltoggle2.hpp" @@ -49,7 +50,9 @@ CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string& update(); - mCell.reset (new Cell (document, getSceneManager(), mCellId, document.getPhysics())); + Cell *cell = new Cell (document, getSceneManager(), mCellId, document.getPhysics()); + connect (cell->getSignalHandler(), SIGNAL(flagAsModified()), this, SLOT(flagAsModSlot())); + mCell.reset (cell); } void CSVRender::UnpagedWorldspaceWidget::cellDataChanged (const QModelIndex& topLeft, @@ -91,7 +94,9 @@ bool CSVRender::UnpagedWorldspaceWidget::handleDrop (const std::vectorgetId(); - mCell.reset (new Cell (getDocument(), getSceneManager(), mCellId, getDocument().getPhysics())); + Cell *cell = new Cell (getDocument(), getSceneManager(), mCellId, getDocument().getPhysics()); + connect (cell->getSignalHandler(), SIGNAL(flagAsModified()), this, SLOT(flagAsModSlot())); + mCell.reset (cell); update(); emit cellChanged(*data.begin()); @@ -212,3 +217,8 @@ CSVRender::WorldspaceWidget::dropRequirments CSVRender::UnpagedWorldspaceWidget: return ignored; } } + +void CSVRender::UnpagedWorldspaceWidget::flagAsModSlot () +{ + flagAsModified(); +} diff --git a/apps/opencs/view/render/unpagedworldspacewidget.hpp b/apps/opencs/view/render/unpagedworldspacewidget.hpp index 11bfaeca3..468c48739 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.hpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.hpp @@ -76,6 +76,8 @@ namespace CSVRender void cellRowsAboutToBeRemoved (const QModelIndex& parent, int start, int end); + virtual void flagAsModSlot(); + signals: void cellChanged(const CSMWorld::UniversalId& id);