From 0c1ad54e68ef7951505c477e5dee4865bac0ef25 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 27 Jun 2014 09:12:26 +0200 Subject: [PATCH 1/4] refactored object rendering into a separate class --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/view/render/object.cpp | 217 ++++++++++++++++++++++ apps/opencs/view/render/object.hpp | 80 ++++++++ apps/opencs/view/render/previewwidget.cpp | 151 +++------------ apps/opencs/view/render/previewwidget.hpp | 20 +- apps/opencs/view/world/previewsubview.cpp | 4 +- 6 files changed, 329 insertions(+), 145 deletions(-) create mode 100644 apps/opencs/view/render/object.cpp create mode 100644 apps/opencs/view/render/object.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index ddaca7e718..a8cc4ceaea 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -70,7 +70,7 @@ opencs_units (view/render opencs_units_noqt (view/render navigation navigation1st navigationfree navigationorbit lighting lightingday lightingnight - lightingbright + lightingbright object ) opencs_units_noqt (view/world diff --git a/apps/opencs/view/render/object.cpp b/apps/opencs/view/render/object.cpp new file mode 100644 index 0000000000..6fa7e77072 --- /dev/null +++ b/apps/opencs/view/render/object.cpp @@ -0,0 +1,217 @@ + +#include "object.hpp" + +#include +#include +#include + +#include "../../model/world/data.hpp" +#include "../../model/world/ref.hpp" +#include "../../model/world/refidcollection.hpp" + +void CSVRender::Object::clearSceneNode (Ogre::SceneNode *node) +{ + for (Ogre::SceneNode::ObjectIterator iter = node->getAttachedObjectIterator(); + iter.hasMoreElements(); ) + { + Ogre::MovableObject* object = dynamic_cast (iter.getNext()); + node->getCreator()->destroyMovableObject (object); + } + + for (Ogre::SceneNode::ChildNodeIterator iter = node->getChildIterator(); + iter.hasMoreElements(); ) + { + Ogre::SceneNode* childNode = dynamic_cast (iter.getNext()); + clearSceneNode (childNode); + node->getCreator()->destroySceneNode (childNode); + } +} + +void CSVRender::Object::clear() +{ + mObject.setNull(); + + clearSceneNode (mBase); +} + +void CSVRender::Object::update() +{ + clear(); + + std::string model; + int error = 0; // 1 referemceanöe does not exist, 2 referenceable does not specify a mesh + + const CSMWorld::RefIdCollection& referenceables = mData.getReferenceables(); + + int index = referenceables.searchId (mReferenceableId); + + if (index==-1) + error = 1; + else + { + // xxx check for Deleted state (error 1) + + model = referenceables.getData (index, + referenceables.findColumnIndex (CSMWorld::Columns::ColumnId_Model)). + toString().toUtf8().constData(); + + if (model.empty()) + error = 2; + } + + if (error) + { + Ogre::Entity* entity = mBase->getCreator()->createEntity (Ogre::SceneManager::PT_CUBE); + entity->setMaterialName("BaseWhite"); /// \todo adjust material according to error + + mBase->attachObject (entity); + } + else + { + mObject = NifOgre::Loader::createObjects (mBase, "Meshes\\" + model); + } +} + +void CSVRender::Object::adjust() +{ + if (mReferenceId.empty()) + return; + + const CSMWorld::CellRef& reference = getReference(); + + // position + if (!mForceBaseToZero) + { + Ogre::Vector3 (reference.mPos.pos[0], reference.mPos.pos[1], reference.mPos.pos[2]); + + mBase->setPosition (Ogre::Vector3 ( + reference.mPos.pos[0], reference.mPos.pos[1], reference.mPos.pos[2])); + } + + // orientation + Ogre::Quaternion xr (Ogre::Radian (-reference.mPos.pos[0]), Ogre::Vector3::UNIT_X); + + Ogre::Quaternion yr (Ogre::Radian (-reference.mPos.pos[1]), Ogre::Vector3::UNIT_Y); + + Ogre::Quaternion zr (Ogre::Radian (-reference.mPos.pos[2]), Ogre::Vector3::UNIT_Z); + + mBase->setOrientation (xr*yr*zr); + + // scale + mBase->setScale (reference.mScale, reference.mScale, reference.mScale); +} + +const CSMWorld::CellRef& CSVRender::Object::getReference() const +{ + if (mReferenceId.empty()) + throw std::logic_error ("object does not represent a reference"); + + return mData.getReferences().getRecord (mReferenceId).get(); +} + +CSVRender::Object::Object (const CSMWorld::Data& data, Ogre::SceneNode *cellNode, + const std::string& id, bool referenceable, bool forceBaseToZero) +: mData (data), mBase (0), mForceBaseToZero (forceBaseToZero) +{ + mBase = cellNode->createChildSceneNode(); + + if (referenceable) + { + mReferenceableId = id; + } + else + { + mReferenceId = id; + mReferenceableId = getReference().mRefID; + } + + update(); + adjust(); +} + +CSVRender::Object::~Object() +{ + clear(); + + if (mBase) + mBase->getCreator()->destroySceneNode (mBase); +} + +bool CSVRender::Object::ReferenceableDataChanged (const QModelIndex& topLeft, + const QModelIndex& bottomRight) +{ + const CSMWorld::RefIdCollection& referenceables = mData.getReferenceables(); + + int index = referenceables.searchId (mReferenceableId); + + if (index!=-1 && index>=topLeft.row() && index<=bottomRight.row()) + { + update(); + adjust(); + return true; + } + + return false; +} + +bool CSVRender::Object::ReferenceableAboutToBeRemoved (const QModelIndex& parent, int start, + int end) +{ + const CSMWorld::RefIdCollection& referenceables = mData.getReferenceables(); + + int index = referenceables.searchId (mReferenceableId); + + if (index!=-1 && index>=start && index<=end) + { + // Deletion of referenceable-type objects is handled outside of Object. + if (!mReferenceId.empty()) + { + update(); + adjust(); + return true; + } + } + + return false; +} + +bool CSVRender::Object::ReferenceDataChanged (const QModelIndex& topLeft, + const QModelIndex& bottomRight) +{ + if (mReferenceId.empty()) + return false; + + const CSMWorld::RefCollection& references = mData.getReferences(); + + int index = references.searchId (mReferenceId); + + if (index!=-1 && index>=topLeft.row() && index<=bottomRight.row()) + { + int columnIndex = + references.findColumnIndex (CSMWorld::Columns::ColumnId_ReferenceableId); + + if (columnIndex>=topLeft.column() && columnIndex<=bottomRight.row()) + { + mReferenceableId = + references.getData (index, columnIndex).toString().toUtf8().constData(); + + update(); + } + + adjust(); + + return true; + } + + return false; +} + +std::string CSVRender::Object::getReferenceId() const +{ + return mReferenceId; +} + +std::string CSVRender::Object::getReferenceableId() const +{ + return mReferenceableId; +} \ No newline at end of file diff --git a/apps/opencs/view/render/object.hpp b/apps/opencs/view/render/object.hpp new file mode 100644 index 0000000000..d4089307f4 --- /dev/null +++ b/apps/opencs/view/render/object.hpp @@ -0,0 +1,80 @@ +#ifndef OPENCS_VIEW_OBJECT_H +#define OPENCS_VIEW_OBJECT_H + +#include + +class QModelIndex; + +namespace Ogre +{ + class SceneNode; +} + +namespace CSMWorld +{ + class Data; + class CellRef; +} + +namespace CSVRender +{ + class Object + { + const CSMWorld::Data& mData; + std::string mReferenceId; + std::string mReferenceableId; + Ogre::SceneNode *mBase; + NifOgre::ObjectScenePtr mObject; + bool mForceBaseToZero; + + /// Not implemented + Object (const Object&); + + /// Not implemented + Object& operator= (const Object&); + + /// Destroy all scene nodes and movable objects attached to node. + static void clearSceneNode (Ogre::SceneNode *node); + + /// Remove object from node (includes deleting) + void clear(); + + /// Update model + void update(); + + /// Adjust position, orientation and scale + void adjust(); + + /// Throws an exception if *this was constructed with referenceable + const CSMWorld::CellRef& getReference() const; + + public: + + Object (const CSMWorld::Data& data, Ogre::SceneNode *cellNode, + const std::string& id, bool referenceable, bool forceBaseToZero = false); + /// \param forceBaseToZero If this is a reference ignore the coordinates and place + /// it at 0, 0, 0 instead. + + ~Object(); + + /// \return Did this call result in a modification of the visual representation of + /// this object? + bool ReferenceableDataChanged (const QModelIndex& topLeft, + const QModelIndex& bottomRight); + + /// \return Did this call result in a modification of the visual representation of + /// this object? + bool ReferenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end); + + /// \return Did this call result in a modification of the visual representation of + /// this object? + bool ReferenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + + /// Returns an empty string if this is a refereceable-type object. + std::string getReferenceId() const; + + std::string getReferenceableId() const; + }; +} + +#endif \ No newline at end of file diff --git a/apps/opencs/view/render/previewwidget.cpp b/apps/opencs/view/render/previewwidget.cpp index 99e57ea11c..ccc6e4acf8 100644 --- a/apps/opencs/view/render/previewwidget.cpp +++ b/apps/opencs/view/render/previewwidget.cpp @@ -7,15 +7,13 @@ #include "../../model/world/data.hpp" #include "../../model/world/idtable.hpp" -void CSVRender::PreviewWidget::setup() +CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data, + const std::string& id, bool referenceable, QWidget *parent) +: SceneWidget (parent), mData (data), + mObject (data, getSceneManager()->getRootSceneNode(), id, referenceable, true) { setNavigation (&mOrbit); - mNode = getSceneManager()->getRootSceneNode()->createChildSceneNode(); - mNode->setPosition (Ogre::Vector3 (0, 0, 0)); - - setModel(); - QAbstractItemModel *referenceables = mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables); @@ -23,142 +21,57 @@ void CSVRender::PreviewWidget::setup() this, SLOT (ReferenceableDataChanged (const QModelIndex&, const QModelIndex&))); connect (referenceables, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), this, SLOT (ReferenceableAboutToBeRemoved (const QModelIndex&, int, int))); -} -void CSVRender::PreviewWidget::setModel() -{ - if (mNode) + if (!referenceable) { - mObject.setNull(); + QAbstractItemModel *references = + mData.getTableModel (CSMWorld::UniversalId::Type_References); - if (mReferenceableId.empty()) - return; - - int column = - mData.getReferenceables().findColumnIndex (CSMWorld::Columns::ColumnId_Model); - - int row = mData.getReferenceables().searchId (mReferenceableId); - - if (row==-1) - return; - - QVariant value = mData.getReferenceables().getData (row, column); - - if (!value.isValid()) - return; - - std::string model = value.toString().toUtf8().constData(); - - if (model.empty()) - return; - - mObject = NifOgre::Loader::createObjects (mNode, "Meshes\\" + model); + connect (references, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)), + this, SLOT (ReferenceDataChanged (const QModelIndex&, const QModelIndex&))); + connect (references, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), + this, SLOT (ReferenceAboutToBeRemoved (const QModelIndex&, int, int))); } } -void CSVRender::PreviewWidget::adjust() -{ - if (mNode) - { - int row = mData.getReferences().getIndex (mReferenceId); - - float scale = mData.getReferences().getData (row, mData.getReferences(). - findColumnIndex (CSMWorld::Columns::ColumnId_Scale)).toFloat(); - float rotX = mData.getReferences().getData (row, mData.getReferences(). - findColumnIndex (CSMWorld::Columns::ColumnId_PositionXRot)).toFloat(); - float rotY = mData.getReferences().getData (row, mData.getReferences(). - findColumnIndex (CSMWorld::Columns::ColumnId_PositionYRot)).toFloat(); - float rotZ = mData.getReferences().getData (row, mData.getReferences(). - findColumnIndex (CSMWorld::Columns::ColumnId_PositionZRot)).toFloat(); - - mNode->setScale (scale, scale, scale); - - Ogre::Quaternion xr (Ogre::Radian(-rotX), Ogre::Vector3::UNIT_X); - - Ogre::Quaternion yr (Ogre::Radian(-rotY), Ogre::Vector3::UNIT_Y); - - Ogre::Quaternion zr (Ogre::Radian(-rotZ), Ogre::Vector3::UNIT_Z); - - mNode->setOrientation (xr*yr*zr); - } -} - -CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data, - const std::string& referenceableId, QWidget *parent) -: SceneWidget (parent), mData (data), mNode (0), mReferenceableId (referenceableId) -{ - setup(); -} - -CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data, - const std::string& referenceableId, const std::string& referenceId, QWidget *parent) -: SceneWidget (parent), mData (data), mReferenceableId (referenceableId), - mReferenceId (referenceId) -{ - setup(); - - adjust(); - - QAbstractItemModel *references = - mData.getTableModel (CSMWorld::UniversalId::Type_References); - - connect (references, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)), - this, SLOT (ReferenceDataChanged (const QModelIndex&, const QModelIndex&))); - connect (references, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), - this, SLOT (ReferenceAboutToBeRemoved (const QModelIndex&, int, int))); -} - void CSVRender::PreviewWidget::ReferenceableDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) { - if (mReferenceableId.empty()) - return; - - CSMWorld::IdTable& referenceables = dynamic_cast ( - *mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables)); - - QModelIndex index = referenceables.getModelIndex (mReferenceableId, 0); - - if (index.row()>=topLeft.row() && index.row()<=bottomRight.row()) - { - /// \todo possible optimisation; check columns and only update if relevant columns have - /// changed - setModel(); + if (mObject.ReferenceableDataChanged (topLeft, bottomRight)) flagAsModified(); - } } void CSVRender::PreviewWidget::ReferenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end) { - if (mReferenceableId.empty()) + if (mObject.ReferenceableAboutToBeRemoved (parent, start, end)) + flagAsModified(); + + if (mObject.getReferenceableId().empty()) return; CSMWorld::IdTable& referenceables = dynamic_cast ( *mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables)); - QModelIndex index = referenceables.getModelIndex (mReferenceableId, 0); + QModelIndex index = referenceables.getModelIndex (mObject.getReferenceableId(), 0); if (index.row()>=start && index.row()<=end) { - if (mReferenceId.empty()) + if (mObject.getReferenceId().empty()) { // this is a preview for a referenceble emit closeRequest(); } - else - { - // this is a preview for a reference - mObject.setNull(); - flagAsModified(); - } } } void CSVRender::PreviewWidget::ReferenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) { - if (mReferenceId.empty()) + if (mObject.ReferenceDataChanged (topLeft, bottomRight)) + flagAsModified(); + + if (mObject.getReferenceId().empty()) return; CSMWorld::IdTable& references = dynamic_cast ( @@ -166,35 +79,23 @@ void CSVRender::PreviewWidget::ReferenceDataChanged (const QModelIndex& topLeft, int columnIndex = references.findColumnIndex (CSMWorld::Columns::ColumnId_ReferenceableId); - QModelIndex index = references.getModelIndex (mReferenceId, columnIndex); + QModelIndex index = references.getModelIndex (mObject.getReferenceId(), columnIndex); if (index.row()>=topLeft.row() && index.row()<=bottomRight.row()) - { - /// \todo possible optimisation; check columns and only update if relevant columns have - /// changed - adjust(); - if (index.column()>=topLeft.column() && index.column()<=bottomRight.row()) - { - mReferenceableId = references.data (index).toString().toUtf8().constData(); - emit referenceableIdChanged (mReferenceableId); - setModel(); - } - - flagAsModified(); - } + emit referenceableIdChanged (mObject.getReferenceableId()); } void CSVRender::PreviewWidget::ReferenceAboutToBeRemoved (const QModelIndex& parent, int start, int end) { - if (mReferenceId.empty()) + if (mObject.getReferenceId().empty()) return; CSMWorld::IdTable& references = dynamic_cast ( *mData.getTableModel (CSMWorld::UniversalId::Type_References)); - QModelIndex index = references.getModelIndex (mReferenceId, 0); + QModelIndex index = references.getModelIndex (mObject.getReferenceId(), 0); if (index.row()>=start && index.row()<=end) emit closeRequest(); diff --git a/apps/opencs/view/render/previewwidget.hpp b/apps/opencs/view/render/previewwidget.hpp index 7a63d8fb12..09cb19dc7a 100644 --- a/apps/opencs/view/render/previewwidget.hpp +++ b/apps/opencs/view/render/previewwidget.hpp @@ -1,11 +1,10 @@ #ifndef OPENCS_VIEW_PREVIEWWIDGET_H #define OPENCS_VIEW_PREVIEWWIDGET_H -#include - #include "scenewidget.hpp" #include "navigationorbit.hpp" +#include "object.hpp" class QModelIndex; @@ -22,26 +21,13 @@ namespace CSVRender CSMWorld::Data& mData; CSVRender::NavigationOrbit mOrbit; - NifOgre::ObjectScenePtr mObject; - Ogre::SceneNode *mNode; - std::string mReferenceId; - std::string mReferenceableId; - - void setup(); - - void setModel(); - - void adjust(); - ///< Adjust referenceable preview according to the reference + Object mObject; public: - PreviewWidget (CSMWorld::Data& data, const std::string& referenceableId, + PreviewWidget (CSMWorld::Data& data, const std::string& id, bool referenceable, QWidget *parent = 0); - PreviewWidget (CSMWorld::Data& data, const std::string& referenceableId, - const std::string& referenceId, QWidget *parent = 0); - signals: void closeRequest(); diff --git a/apps/opencs/view/world/previewsubview.cpp b/apps/opencs/view/world/previewsubview.cpp index e9a30e65d2..49e6d93618 100644 --- a/apps/opencs/view/world/previewsubview.cpp +++ b/apps/opencs/view/world/previewsubview.cpp @@ -23,10 +23,10 @@ CSVWorld::PreviewSubView::PreviewSubView (const CSMWorld::UniversalId& id, CSMDo referenceableIdChanged (referenceableId); mScene = - new CSVRender::PreviewWidget (document.getData(), referenceableId, id.getId(), this); + new CSVRender::PreviewWidget (document.getData(), id.getId(), false, this); } else - mScene = new CSVRender::PreviewWidget (document.getData(), id.getId(), this); + mScene = new CSVRender::PreviewWidget (document.getData(), id.getId(), true, this); SceneToolbar *toolbar = new SceneToolbar (48+6, this); From 36c1170d09e9d68d64ff2e04a098d004c9b0e150 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 27 Jun 2014 10:35:00 +0200 Subject: [PATCH 2/4] fixed some function names --- apps/opencs/view/render/object.cpp | 6 +++--- apps/opencs/view/render/object.hpp | 6 +++--- apps/opencs/view/render/previewwidget.cpp | 22 +++++++++++----------- apps/opencs/view/render/previewwidget.hpp | 8 ++++---- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/apps/opencs/view/render/object.cpp b/apps/opencs/view/render/object.cpp index 6fa7e77072..59cfd965de 100644 --- a/apps/opencs/view/render/object.cpp +++ b/apps/opencs/view/render/object.cpp @@ -137,7 +137,7 @@ CSVRender::Object::~Object() mBase->getCreator()->destroySceneNode (mBase); } -bool CSVRender::Object::ReferenceableDataChanged (const QModelIndex& topLeft, +bool CSVRender::Object::referenceableDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) { const CSMWorld::RefIdCollection& referenceables = mData.getReferenceables(); @@ -154,7 +154,7 @@ bool CSVRender::Object::ReferenceableDataChanged (const QModelIndex& topLeft, return false; } -bool CSVRender::Object::ReferenceableAboutToBeRemoved (const QModelIndex& parent, int start, +bool CSVRender::Object::referenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end) { const CSMWorld::RefIdCollection& referenceables = mData.getReferenceables(); @@ -175,7 +175,7 @@ bool CSVRender::Object::ReferenceableAboutToBeRemoved (const QModelIndex& parent return false; } -bool CSVRender::Object::ReferenceDataChanged (const QModelIndex& topLeft, +bool CSVRender::Object::referenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) { if (mReferenceId.empty()) diff --git a/apps/opencs/view/render/object.hpp b/apps/opencs/view/render/object.hpp index d4089307f4..df39d7393d 100644 --- a/apps/opencs/view/render/object.hpp +++ b/apps/opencs/view/render/object.hpp @@ -59,16 +59,16 @@ namespace CSVRender /// \return Did this call result in a modification of the visual representation of /// this object? - bool ReferenceableDataChanged (const QModelIndex& topLeft, + bool referenceableDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); /// \return Did this call result in a modification of the visual representation of /// this object? - bool ReferenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end); + bool referenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end); /// \return Did this call result in a modification of the visual representation of /// this object? - bool ReferenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + bool referenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); /// Returns an empty string if this is a refereceable-type object. std::string getReferenceId() const; diff --git a/apps/opencs/view/render/previewwidget.cpp b/apps/opencs/view/render/previewwidget.cpp index ccc6e4acf8..76e9971dd9 100644 --- a/apps/opencs/view/render/previewwidget.cpp +++ b/apps/opencs/view/render/previewwidget.cpp @@ -18,9 +18,9 @@ CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data, mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables); connect (referenceables, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)), - this, SLOT (ReferenceableDataChanged (const QModelIndex&, const QModelIndex&))); + this, SLOT (referenceableDataChanged (const QModelIndex&, const QModelIndex&))); connect (referenceables, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), - this, SLOT (ReferenceableAboutToBeRemoved (const QModelIndex&, int, int))); + this, SLOT (referenceableAboutToBeRemoved (const QModelIndex&, int, int))); if (!referenceable) { @@ -28,23 +28,23 @@ CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data, mData.getTableModel (CSMWorld::UniversalId::Type_References); connect (references, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)), - this, SLOT (ReferenceDataChanged (const QModelIndex&, const QModelIndex&))); + this, SLOT (referenceDataChanged (const QModelIndex&, const QModelIndex&))); connect (references, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), - this, SLOT (ReferenceAboutToBeRemoved (const QModelIndex&, int, int))); + this, SLOT (referenceAboutToBeRemoved (const QModelIndex&, int, int))); } } -void CSVRender::PreviewWidget::ReferenceableDataChanged (const QModelIndex& topLeft, +void CSVRender::PreviewWidget::referenceableDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) { - if (mObject.ReferenceableDataChanged (topLeft, bottomRight)) + if (mObject.referenceableDataChanged (topLeft, bottomRight)) flagAsModified(); } -void CSVRender::PreviewWidget::ReferenceableAboutToBeRemoved (const QModelIndex& parent, int start, +void CSVRender::PreviewWidget::referenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end) { - if (mObject.ReferenceableAboutToBeRemoved (parent, start, end)) + if (mObject.referenceableAboutToBeRemoved (parent, start, end)) flagAsModified(); if (mObject.getReferenceableId().empty()) @@ -65,10 +65,10 @@ void CSVRender::PreviewWidget::ReferenceableAboutToBeRemoved (const QModelIndex& } } -void CSVRender::PreviewWidget::ReferenceDataChanged (const QModelIndex& topLeft, +void CSVRender::PreviewWidget::referenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) { - if (mObject.ReferenceDataChanged (topLeft, bottomRight)) + if (mObject.referenceDataChanged (topLeft, bottomRight)) flagAsModified(); if (mObject.getReferenceId().empty()) @@ -86,7 +86,7 @@ void CSVRender::PreviewWidget::ReferenceDataChanged (const QModelIndex& topLeft, emit referenceableIdChanged (mObject.getReferenceableId()); } -void CSVRender::PreviewWidget::ReferenceAboutToBeRemoved (const QModelIndex& parent, int start, +void CSVRender::PreviewWidget::referenceAboutToBeRemoved (const QModelIndex& parent, int start, int end) { if (mObject.getReferenceId().empty()) diff --git a/apps/opencs/view/render/previewwidget.hpp b/apps/opencs/view/render/previewwidget.hpp index 09cb19dc7a..dd6a99c0f9 100644 --- a/apps/opencs/view/render/previewwidget.hpp +++ b/apps/opencs/view/render/previewwidget.hpp @@ -36,14 +36,14 @@ namespace CSVRender private slots: - void ReferenceableDataChanged (const QModelIndex& topLeft, + void referenceableDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); - void ReferenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end); + void referenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end); - void ReferenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + void referenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); - void ReferenceAboutToBeRemoved (const QModelIndex& parent, int start, int end); + void referenceAboutToBeRemoved (const QModelIndex& parent, int start, int end); }; } From a2f514f024856abd524465927611a1ea6599e006 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 27 Jun 2014 11:38:34 +0200 Subject: [PATCH 3/4] disabled preview function for deleted records --- apps/opencs/view/world/table.cpp | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/apps/opencs/view/world/table.cpp b/apps/opencs/view/world/table.cpp index 877fd51c07..0605e87ff1 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -115,12 +115,12 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event) if (selectedRows.size()==1) { + int row = selectedRows.begin()->row(); + + row = mProxyModel->mapToSource (mProxyModel->index (row, 0)).row(); + if (mModel->getFeatures() & CSMWorld::IdTable::Feature_View) { - int row = selectedRows.begin()->row(); - - row = mProxyModel->mapToSource (mProxyModel->index (row, 0)).row(); - CSMWorld::UniversalId id = mModel->view (row).first; int index = mDocument.getData().getCells().searchId (id.getId()); @@ -132,7 +132,16 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event) } if (mModel->getFeatures() & CSMWorld::IdTable::Feature_Preview) - menu.addAction (mPreviewAction); + { + QModelIndex index = mModel->index (row, + mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Modification)); + + CSMWorld::RecordBase::State state = static_cast ( + mModel->data (index).toInt()); + + if (state!=CSMWorld::RecordBase::State_Deleted) + menu.addAction (mPreviewAction); + } } menu.exec (event->globalPos()); @@ -377,7 +386,12 @@ void CSVWorld::Table::previewRecord() { std::string id = getUniversalId (selectedRows.begin()->row()).getId(); - emit editRequest (CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Preview, id) , ""); + QModelIndex index = mModel->getModelIndex (id, + mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Modification)); + + if (mModel->data (index)!=CSMWorld::RecordBase::State_Deleted) + emit editRequest (CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Preview, id), + ""); } } From 6020edf60f7408f214d415ca66a310b0055cf521 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 27 Jun 2014 11:55:02 +0200 Subject: [PATCH 4/4] make preview watch for changes in modification state of relevant records --- apps/opencs/view/render/previewwidget.cpp | 24 +++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/apps/opencs/view/render/previewwidget.cpp b/apps/opencs/view/render/previewwidget.cpp index 76e9971dd9..75b4e93967 100644 --- a/apps/opencs/view/render/previewwidget.cpp +++ b/apps/opencs/view/render/previewwidget.cpp @@ -39,6 +39,18 @@ void CSVRender::PreviewWidget::referenceableDataChanged (const QModelIndex& topL { if (mObject.referenceableDataChanged (topLeft, bottomRight)) flagAsModified(); + + if (mObject.getReferenceId().empty()) + { + CSMWorld::IdTable& referenceables = dynamic_cast ( + *mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables)); + + QModelIndex index = referenceables.getModelIndex (mObject.getReferenceableId(), + referenceables.findColumnIndex (CSMWorld::Columns::ColumnId_Modification)); + + if (referenceables.data (index).toInt()==CSMWorld::RecordBase::State_Deleted) + emit closeRequest(); + } } void CSVRender::PreviewWidget::referenceableAboutToBeRemoved (const QModelIndex& parent, int start, @@ -77,6 +89,18 @@ void CSVRender::PreviewWidget::referenceDataChanged (const QModelIndex& topLeft, CSMWorld::IdTable& references = dynamic_cast ( *mData.getTableModel (CSMWorld::UniversalId::Type_References)); + // check for deleted state + { + QModelIndex index = references.getModelIndex (mObject.getReferenceId(), + references.findColumnIndex (CSMWorld::Columns::ColumnId_Modification)); + + if (references.data (index).toInt()==CSMWorld::RecordBase::State_Deleted) + { + emit closeRequest(); + return; + } + } + int columnIndex = references.findColumnIndex (CSMWorld::Columns::ColumnId_ReferenceableId); QModelIndex index = references.getModelIndex (mObject.getReferenceId(), columnIndex);