diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 0addaab52..f6349aa7d 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -18,7 +18,7 @@ opencs_hdrs_noqt (model/doc opencs_units (model/world - idtable idtableproxymodel regionmap data commanddispatcher + idtable idtableproxymodel regionmap data commanddispatcher idtablebase ) diff --git a/apps/opencs/model/filter/andnode.cpp b/apps/opencs/model/filter/andnode.cpp index dfaa56e78..4249fc228 100644 --- a/apps/opencs/model/filter/andnode.cpp +++ b/apps/opencs/model/filter/andnode.cpp @@ -7,7 +7,7 @@ CSMFilter::AndNode::AndNode (const std::vector >& nodes) : NAryNode (nodes, "and") {} -bool CSMFilter::AndNode::test (const CSMWorld::IdTable& table, int row, +bool CSMFilter::AndNode::test (const CSMWorld::IdTableBase& table, int row, const std::map& columns) const { int size = getSize(); diff --git a/apps/opencs/model/filter/andnode.hpp b/apps/opencs/model/filter/andnode.hpp index 887175700..3838b451d 100644 --- a/apps/opencs/model/filter/andnode.hpp +++ b/apps/opencs/model/filter/andnode.hpp @@ -11,7 +11,7 @@ namespace CSMFilter AndNode (const std::vector >& nodes); - virtual bool test (const CSMWorld::IdTable& table, int row, + virtual bool test (const CSMWorld::IdTableBase& table, int row, const std::map& columns) const; ///< \return Can the specified table row pass through to filter? /// \param columns column ID to column index mapping diff --git a/apps/opencs/model/filter/booleannode.cpp b/apps/opencs/model/filter/booleannode.cpp index 267e06a64..2daa1b6d8 100644 --- a/apps/opencs/model/filter/booleannode.cpp +++ b/apps/opencs/model/filter/booleannode.cpp @@ -3,7 +3,7 @@ CSMFilter::BooleanNode::BooleanNode (bool true_) : mTrue (true_) {} -bool CSMFilter::BooleanNode::test (const CSMWorld::IdTable& table, int row, +bool CSMFilter::BooleanNode::test (const CSMWorld::IdTableBase& table, int row, const std::map& columns) const { return mTrue; diff --git a/apps/opencs/model/filter/booleannode.hpp b/apps/opencs/model/filter/booleannode.hpp index d19219e35..d9635746c 100644 --- a/apps/opencs/model/filter/booleannode.hpp +++ b/apps/opencs/model/filter/booleannode.hpp @@ -13,7 +13,7 @@ namespace CSMFilter BooleanNode (bool true_); - virtual bool test (const CSMWorld::IdTable& table, int row, + virtual bool test (const CSMWorld::IdTableBase& table, int row, const std::map& columns) const; ///< \return Can the specified table row pass through to filter? /// \param columns column ID to column index mapping diff --git a/apps/opencs/model/filter/node.hpp b/apps/opencs/model/filter/node.hpp index ef18353a4..58588bdc5 100644 --- a/apps/opencs/model/filter/node.hpp +++ b/apps/opencs/model/filter/node.hpp @@ -11,7 +11,7 @@ namespace CSMWorld { - class IdTable; + class IdTableBase; } namespace CSMFilter @@ -32,7 +32,7 @@ namespace CSMFilter virtual ~Node(); - virtual bool test (const CSMWorld::IdTable& table, int row, + virtual bool test (const CSMWorld::IdTableBase& table, int row, const std::map& columns) const = 0; ///< \return Can the specified table row pass through to filter? /// \param columns column ID to column index mapping diff --git a/apps/opencs/model/filter/notnode.cpp b/apps/opencs/model/filter/notnode.cpp index 1b22ea7a6..231773075 100644 --- a/apps/opencs/model/filter/notnode.cpp +++ b/apps/opencs/model/filter/notnode.cpp @@ -3,7 +3,7 @@ CSMFilter::NotNode::NotNode (boost::shared_ptr child) : UnaryNode (child, "not") {} -bool CSMFilter::NotNode::test (const CSMWorld::IdTable& table, int row, +bool CSMFilter::NotNode::test (const CSMWorld::IdTableBase& table, int row, const std::map& columns) const { return !getChild().test (table, row, columns); diff --git a/apps/opencs/model/filter/notnode.hpp b/apps/opencs/model/filter/notnode.hpp index b9e80b8c6..0281d99da 100644 --- a/apps/opencs/model/filter/notnode.hpp +++ b/apps/opencs/model/filter/notnode.hpp @@ -11,7 +11,7 @@ namespace CSMFilter NotNode (boost::shared_ptr child); - virtual bool test (const CSMWorld::IdTable& table, int row, + virtual bool test (const CSMWorld::IdTableBase& table, int row, const std::map& columns) const; ///< \return Can the specified table row pass through to filter? /// \param columns column ID to column index mapping diff --git a/apps/opencs/model/filter/ornode.cpp b/apps/opencs/model/filter/ornode.cpp index 4fc34e1d5..c5d15a384 100644 --- a/apps/opencs/model/filter/ornode.cpp +++ b/apps/opencs/model/filter/ornode.cpp @@ -7,7 +7,7 @@ CSMFilter::OrNode::OrNode (const std::vector >& nodes) : NAryNode (nodes, "or") {} -bool CSMFilter::OrNode::test (const CSMWorld::IdTable& table, int row, +bool CSMFilter::OrNode::test (const CSMWorld::IdTableBase& table, int row, const std::map& columns) const { int size = getSize(); diff --git a/apps/opencs/model/filter/ornode.hpp b/apps/opencs/model/filter/ornode.hpp index c39e35095..07ab51a6a 100644 --- a/apps/opencs/model/filter/ornode.hpp +++ b/apps/opencs/model/filter/ornode.hpp @@ -11,7 +11,7 @@ namespace CSMFilter OrNode (const std::vector >& nodes); - virtual bool test (const CSMWorld::IdTable& table, int row, + virtual bool test (const CSMWorld::IdTableBase& table, int row, const std::map& columns) const; ///< \return Can the specified table row pass through to filter? /// \param columns column ID to column index mapping diff --git a/apps/opencs/model/filter/textnode.cpp b/apps/opencs/model/filter/textnode.cpp index 7d1a4845f..24cdce4f5 100644 --- a/apps/opencs/model/filter/textnode.cpp +++ b/apps/opencs/model/filter/textnode.cpp @@ -7,13 +7,13 @@ #include #include "../world/columns.hpp" -#include "../world/idtable.hpp" +#include "../world/idtablebase.hpp" CSMFilter::TextNode::TextNode (int columnId, const std::string& text) : mColumnId (columnId), mText (text) {} -bool CSMFilter::TextNode::test (const CSMWorld::IdTable& table, int row, +bool CSMFilter::TextNode::test (const CSMWorld::IdTableBase& table, int row, const std::map& columns) const { const std::map::const_iterator iter = columns.find (mColumnId); diff --git a/apps/opencs/model/filter/textnode.hpp b/apps/opencs/model/filter/textnode.hpp index 663fa7382..60ead85de 100644 --- a/apps/opencs/model/filter/textnode.hpp +++ b/apps/opencs/model/filter/textnode.hpp @@ -14,7 +14,7 @@ namespace CSMFilter TextNode (int columnId, const std::string& text); - virtual bool test (const CSMWorld::IdTable& table, int row, + virtual bool test (const CSMWorld::IdTableBase& table, int row, const std::map& columns) const; ///< \return Can the specified table row pass through to filter? /// \param columns column ID to column index mapping diff --git a/apps/opencs/model/filter/valuenode.cpp b/apps/opencs/model/filter/valuenode.cpp index fdcce00ab..66b6282d7 100644 --- a/apps/opencs/model/filter/valuenode.cpp +++ b/apps/opencs/model/filter/valuenode.cpp @@ -5,13 +5,13 @@ #include #include "../world/columns.hpp" -#include "../world/idtable.hpp" +#include "../world/idtablebase.hpp" CSMFilter::ValueNode::ValueNode (int columnId, Type lowerType, Type upperType, double lower, double upper) : mColumnId (columnId), mLowerType (lowerType), mUpperType (upperType), mLower (lower), mUpper (upper){} -bool CSMFilter::ValueNode::test (const CSMWorld::IdTable& table, int row, +bool CSMFilter::ValueNode::test (const CSMWorld::IdTableBase& table, int row, const std::map& columns) const { const std::map::const_iterator iter = columns.find (mColumnId); diff --git a/apps/opencs/model/filter/valuenode.hpp b/apps/opencs/model/filter/valuenode.hpp index b1050709d..5b7ffec4e 100644 --- a/apps/opencs/model/filter/valuenode.hpp +++ b/apps/opencs/model/filter/valuenode.hpp @@ -27,7 +27,7 @@ namespace CSMFilter ValueNode (int columnId, Type lowerType, Type upperType, double lower, double upper); - virtual bool test (const CSMWorld::IdTable& table, int row, + virtual bool test (const CSMWorld::IdTableBase& table, int row, const std::map& columns) const; ///< \return Can the specified table row pass through to filter? /// \param columns column ID to column index mapping diff --git a/apps/opencs/model/world/commands.hpp b/apps/opencs/model/world/commands.hpp index ec6350658..947be68fd 100644 --- a/apps/opencs/model/world/commands.hpp +++ b/apps/opencs/model/world/commands.hpp @@ -49,7 +49,7 @@ namespace CSMWorld public: - CloneCommand (IdTable& model, const std::string& idOrigin, + CloneCommand (IdTable& model, const std::string& idOrigin, const std::string& IdDestination, const UniversalId::Type type, QUndoCommand* parent = 0); diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index a481ce143..3a48317ef 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -5,7 +5,7 @@ #include "columnbase.hpp" CSMWorld::IdTable::IdTable (CollectionBase *idCollection, unsigned int features) -: mIdCollection (idCollection), mFeatures (features) +: IdTableBase (features), mIdCollection (idCollection) {} CSMWorld::IdTable::~IdTable() @@ -185,17 +185,12 @@ void CSMWorld::IdTable::reorderRows (int baseIndex, const std::vector& newO index (baseIndex+newOrder.size()-1, mIdCollection->getColumns()-1)); } -unsigned int CSMWorld::IdTable::getFeatures() const -{ - return mFeatures; -} - std::pair CSMWorld::IdTable::view (int row) const { std::string id; std::string hint; - if (mFeatures & Feature_ViewCell) + if (getFeatures() & Feature_ViewCell) { int cellColumn = mIdCollection->searchColumnIndex (Columns::ColumnId_Cell); int idColumn = mIdCollection->searchColumnIndex (Columns::ColumnId_Id); @@ -206,7 +201,7 @@ std::pair CSMWorld::IdTable::view (int row) hint = "r:" + std::string (mIdCollection->getData (row, idColumn).toString().toUtf8().constData()); } } - else if (mFeatures & Feature_ViewId) + else if (getFeatures() & Feature_ViewId) { int column = mIdCollection->searchColumnIndex (Columns::ColumnId_Id); @@ -226,6 +221,11 @@ std::pair CSMWorld::IdTable::view (int row) return std::make_pair (UniversalId (UniversalId::Type_Scene, id), hint); } +bool CSMWorld::IdTable::isDeleted (const std::string& id) const +{ + return getRecord (id).isDeleted(); +} + int CSMWorld::IdTable::getColumnId(int column) const { return mIdCollection->getColumn(column).getId(); diff --git a/apps/opencs/model/world/idtable.hpp b/apps/opencs/model/world/idtable.hpp index de3adef7c..707d7133b 100644 --- a/apps/opencs/model/world/idtable.hpp +++ b/apps/opencs/model/world/idtable.hpp @@ -3,8 +3,7 @@ #include -#include - +#include "idtablebase.hpp" #include "universalid.hpp" #include "columns.hpp" @@ -13,33 +12,13 @@ namespace CSMWorld class CollectionBase; class RecordBase; - class IdTable : public QAbstractItemModel + class IdTable : public IdTableBase { Q_OBJECT - public: - - enum Features - { - Feature_ReorderWithinTopic = 1, - - /// Use ID column to generate view request (ID is transformed into - /// worldspace and original ID is passed as hint with c: prefix). - Feature_ViewId = 2, - - /// Use cell column to generate view request (cell ID is transformed - /// into worldspace and record ID is passed as hint with r: prefix). - Feature_ViewCell = 4, - - Feature_View = Feature_ViewId | Feature_ViewCell, - - Feature_Preview = 8 - }; - private: CollectionBase *mIdCollection; - unsigned int mFeatures; // not implemented IdTable (const IdTable&); @@ -78,17 +57,17 @@ namespace CSMWorld const std::string& destination, UniversalId::Type type = UniversalId::Type_None); - QModelIndex getModelIndex (const std::string& id, int column) const; + virtual QModelIndex getModelIndex (const std::string& id, int column) const; void setRecord (const std::string& id, const RecordBase& record); ///< Add record or overwrite existing recrod. const RecordBase& getRecord (const std::string& id) const; - int searchColumnIndex (Columns::ColumnId id) const; + virtual int searchColumnIndex (Columns::ColumnId id) const; ///< Return index of column with the given \a id. If no such column exists, -1 is returned. - int findColumnIndex (Columns::ColumnId id) const; + virtual int findColumnIndex (Columns::ColumnId id) const; ///< Return index of column with the given \a id. If no such column exists, an exception is /// thrown. @@ -96,12 +75,13 @@ namespace CSMWorld ///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices /// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex). - unsigned int getFeatures() const; - - std::pair view (int row) const; + virtual std::pair view (int row) const; ///< Return the UniversalId and the hint for viewing \a row. If viewing is not /// supported by this table, return (UniversalId::Type_None, ""). + /// Is \a id flagged as deleted? + virtual bool isDeleted (const std::string& id) const; + int getColumnId(int column) const; }; } diff --git a/apps/opencs/model/world/idtablebase.cpp b/apps/opencs/model/world/idtablebase.cpp new file mode 100644 index 000000000..31d8d461e --- /dev/null +++ b/apps/opencs/model/world/idtablebase.cpp @@ -0,0 +1,9 @@ + +#include "idtablebase.hpp" + +CSMWorld::IdTableBase::IdTableBase (unsigned int features) : mFeatures (features) {} + +unsigned int CSMWorld::IdTableBase::getFeatures() const +{ + return mFeatures; +} \ No newline at end of file diff --git a/apps/opencs/model/world/idtablebase.hpp b/apps/opencs/model/world/idtablebase.hpp new file mode 100644 index 000000000..e6aaea1d6 --- /dev/null +++ b/apps/opencs/model/world/idtablebase.hpp @@ -0,0 +1,64 @@ +#ifndef CSM_WOLRD_IDTABLEBASE_H +#define CSM_WOLRD_IDTABLEBASE_H + +#include + +#include "columns.hpp" + +namespace CSMWorld +{ + class UniversalId; + + class IdTableBase : public QAbstractItemModel + { + Q_OBJECT + + public: + + enum Features + { + Feature_ReorderWithinTopic = 1, + + /// Use ID column to generate view request (ID is transformed into + /// worldspace and original ID is passed as hint with c: prefix). + Feature_ViewId = 2, + + /// Use cell column to generate view request (cell ID is transformed + /// into worldspace and record ID is passed as hint with r: prefix). + Feature_ViewCell = 4, + + Feature_View = Feature_ViewId | Feature_ViewCell, + + Feature_Preview = 8 + }; + + private: + + unsigned int mFeatures; + + public: + + IdTableBase (unsigned int features); + + virtual QModelIndex getModelIndex (const std::string& id, int column) const = 0; + + /// Return index of column with the given \a id. If no such column exists, -1 is + /// returned. + virtual int searchColumnIndex (Columns::ColumnId id) const = 0; + + /// Return index of column with the given \a id. If no such column exists, an + /// exception is thrown. + virtual int findColumnIndex (Columns::ColumnId id) const = 0; + + /// Return the UniversalId and the hint for viewing \a row. If viewing is not + /// supported by this table, return (UniversalId::Type_None, ""). + virtual std::pair view (int row) const = 0; + + /// Is \a id flagged as deleted? + virtual bool isDeleted (const std::string& id) const = 0; + + unsigned int getFeatures() const; + }; +} + +#endif diff --git a/apps/opencs/model/world/idtableproxymodel.cpp b/apps/opencs/model/world/idtableproxymodel.cpp index f51b7f818..a5e9d354a 100644 --- a/apps/opencs/model/world/idtableproxymodel.cpp +++ b/apps/opencs/model/world/idtableproxymodel.cpp @@ -3,7 +3,7 @@ #include -#include "idtable.hpp" +#include "idtablebase.hpp" void CSMWorld::IdTableProxyModel::updateColumnMap() { @@ -13,7 +13,7 @@ void CSMWorld::IdTableProxyModel::updateColumnMap() { std::vector columns = mFilter->getReferencedColumns(); - const IdTable& table = dynamic_cast (*sourceModel()); + const IdTableBase& table = dynamic_cast (*sourceModel()); for (std::vector::const_iterator iter (columns.begin()); iter!=columns.end(); ++iter) mColumnMap.insert (std::make_pair (*iter, @@ -28,7 +28,7 @@ bool CSMWorld::IdTableProxyModel::filterAcceptsRow (int sourceRow, const QModelI return true; return mFilter->test ( - dynamic_cast (*sourceModel()), sourceRow, mColumnMap); + dynamic_cast (*sourceModel()), sourceRow, mColumnMap); } CSMWorld::IdTableProxyModel::IdTableProxyModel (QObject *parent) @@ -39,7 +39,7 @@ CSMWorld::IdTableProxyModel::IdTableProxyModel (QObject *parent) QModelIndex CSMWorld::IdTableProxyModel::getModelIndex (const std::string& id, int column) const { - return mapFromSource (dynamic_cast (*sourceModel()).getModelIndex (id, column)); + return mapFromSource (dynamic_cast (*sourceModel()).getModelIndex (id, column)); } void CSMWorld::IdTableProxyModel::setFilter (const boost::shared_ptr& filter) diff --git a/apps/opencs/view/world/table.cpp b/apps/opencs/view/world/table.cpp index 6377b0353..bbac2b1ca 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -14,6 +14,7 @@ #include "../../model/world/data.hpp" #include "../../model/world/commands.hpp" #include "../../model/world/idtableproxymodel.hpp" +#include "../../model/world/idtablebase.hpp" #include "../../model/world/idtable.hpp" #include "../../model/world/record.hpp" #include "../../model/world/columns.hpp" @@ -82,7 +83,7 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event) menu.addAction (mExtendedDeleteAction); } - if (mModel->getFeatures() & CSMWorld::IdTable::Feature_ReorderWithinTopic) + if (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_ReorderWithinTopic) { /// \todo allow reordering of multiple rows if (selectedRows.size()==1) @@ -119,7 +120,7 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event) row = mProxyModel->mapToSource (mProxyModel->index (row, 0)).row(); - if (mModel->getFeatures() & CSMWorld::IdTable::Feature_View) + if (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_View) { CSMWorld::UniversalId id = mModel->view (row).first; @@ -131,7 +132,7 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event) menu.addAction (mViewAction); } - if (mModel->getFeatures() & CSMWorld::IdTable::Feature_Preview) + if (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_Preview) { QModelIndex index = mModel->index (row, mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Modification)); @@ -152,7 +153,7 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id, : mCreateAction (0), mCloneAction(0), mRecordStatusDisplay (0), DragRecordTable(document) { - mModel = &dynamic_cast (*mDocument.getData().getTableModel (id)); + mModel = &dynamic_cast (*mDocument.getData().getTableModel (id)); mProxyModel = new CSMWorld::IdTableProxyModel (this); mProxyModel->setSourceModel (mModel); @@ -290,7 +291,7 @@ void CSVWorld::Table::cloneRecord() { QModelIndexList selectedRows = selectionModel()->selectedRows(); const CSMWorld::UniversalId& toClone = getUniversalId(selectedRows.begin()->row()); - if (selectedRows.size()==1 && !mModel->getRecord(toClone.getId()).isDeleted()) + if (selectedRows.size()==1 && !mModel->isDeleted (toClone.getId())) { emit cloneRequest (toClone); } @@ -324,7 +325,8 @@ void CSVWorld::Table::moveUpRecord() for (int i=1; i (*mModel), row, newOrder)); } } } @@ -356,7 +358,8 @@ void CSVWorld::Table::moveDownRecord() for (int i=1; i (*mModel), row, newOrder)); } } } diff --git a/apps/opencs/view/world/table.hpp b/apps/opencs/view/world/table.hpp index 255c430ea..883834b60 100644 --- a/apps/opencs/view/world/table.hpp +++ b/apps/opencs/view/world/table.hpp @@ -23,7 +23,7 @@ namespace CSMWorld class Data; class UniversalId; class IdTableProxyModel; - class IdTable; + class IdTableBase; class CommandDispatcher; } @@ -49,7 +49,7 @@ namespace CSVWorld QAction *mExtendedDeleteAction; QAction *mExtendedRevertAction; CSMWorld::IdTableProxyModel *mProxyModel; - CSMWorld::IdTable *mModel; + CSMWorld::IdTableBase *mModel; int mRecordStatusDisplay; CSMWorld::CommandDispatcher *mDispatcher;