injected new class IdTableBase between QAbstractItemModel and IdTable

This commit is contained in:
Marc Zinnschlag 2014-07-04 13:24:35 +02:00
parent 63d0fdee7f
commit 1b1f1bade3
22 changed files with 124 additions and 68 deletions

View file

@ -18,7 +18,7 @@ opencs_hdrs_noqt (model/doc
opencs_units (model/world opencs_units (model/world
idtable idtableproxymodel regionmap data commanddispatcher idtable idtableproxymodel regionmap data commanddispatcher idtablebase
) )

View file

@ -7,7 +7,7 @@ CSMFilter::AndNode::AndNode (const std::vector<boost::shared_ptr<Node> >& nodes)
: NAryNode (nodes, "and") : 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<int, int>& columns) const const std::map<int, int>& columns) const
{ {
int size = getSize(); int size = getSize();

View file

@ -11,7 +11,7 @@ namespace CSMFilter
AndNode (const std::vector<boost::shared_ptr<Node> >& nodes); AndNode (const std::vector<boost::shared_ptr<Node> >& nodes);
virtual bool test (const CSMWorld::IdTable& table, int row, virtual bool test (const CSMWorld::IdTableBase& table, int row,
const std::map<int, int>& columns) const; const std::map<int, int>& columns) const;
///< \return Can the specified table row pass through to filter? ///< \return Can the specified table row pass through to filter?
/// \param columns column ID to column index mapping /// \param columns column ID to column index mapping

View file

@ -3,7 +3,7 @@
CSMFilter::BooleanNode::BooleanNode (bool true_) : mTrue (true_) {} 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<int, int>& columns) const const std::map<int, int>& columns) const
{ {
return mTrue; return mTrue;

View file

@ -13,7 +13,7 @@ namespace CSMFilter
BooleanNode (bool true_); BooleanNode (bool true_);
virtual bool test (const CSMWorld::IdTable& table, int row, virtual bool test (const CSMWorld::IdTableBase& table, int row,
const std::map<int, int>& columns) const; const std::map<int, int>& columns) const;
///< \return Can the specified table row pass through to filter? ///< \return Can the specified table row pass through to filter?
/// \param columns column ID to column index mapping /// \param columns column ID to column index mapping

View file

@ -11,7 +11,7 @@
namespace CSMWorld namespace CSMWorld
{ {
class IdTable; class IdTableBase;
} }
namespace CSMFilter namespace CSMFilter
@ -32,7 +32,7 @@ namespace CSMFilter
virtual ~Node(); virtual ~Node();
virtual bool test (const CSMWorld::IdTable& table, int row, virtual bool test (const CSMWorld::IdTableBase& table, int row,
const std::map<int, int>& columns) const = 0; const std::map<int, int>& columns) const = 0;
///< \return Can the specified table row pass through to filter? ///< \return Can the specified table row pass through to filter?
/// \param columns column ID to column index mapping /// \param columns column ID to column index mapping

View file

@ -3,7 +3,7 @@
CSMFilter::NotNode::NotNode (boost::shared_ptr<Node> child) : UnaryNode (child, "not") {} CSMFilter::NotNode::NotNode (boost::shared_ptr<Node> 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<int, int>& columns) const const std::map<int, int>& columns) const
{ {
return !getChild().test (table, row, columns); return !getChild().test (table, row, columns);

View file

@ -11,7 +11,7 @@ namespace CSMFilter
NotNode (boost::shared_ptr<Node> child); NotNode (boost::shared_ptr<Node> child);
virtual bool test (const CSMWorld::IdTable& table, int row, virtual bool test (const CSMWorld::IdTableBase& table, int row,
const std::map<int, int>& columns) const; const std::map<int, int>& columns) const;
///< \return Can the specified table row pass through to filter? ///< \return Can the specified table row pass through to filter?
/// \param columns column ID to column index mapping /// \param columns column ID to column index mapping

View file

@ -7,7 +7,7 @@ CSMFilter::OrNode::OrNode (const std::vector<boost::shared_ptr<Node> >& nodes)
: NAryNode (nodes, "or") : 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<int, int>& columns) const const std::map<int, int>& columns) const
{ {
int size = getSize(); int size = getSize();

View file

@ -11,7 +11,7 @@ namespace CSMFilter
OrNode (const std::vector<boost::shared_ptr<Node> >& nodes); OrNode (const std::vector<boost::shared_ptr<Node> >& nodes);
virtual bool test (const CSMWorld::IdTable& table, int row, virtual bool test (const CSMWorld::IdTableBase& table, int row,
const std::map<int, int>& columns) const; const std::map<int, int>& columns) const;
///< \return Can the specified table row pass through to filter? ///< \return Can the specified table row pass through to filter?
/// \param columns column ID to column index mapping /// \param columns column ID to column index mapping

View file

@ -7,13 +7,13 @@
#include <QRegExp> #include <QRegExp>
#include "../world/columns.hpp" #include "../world/columns.hpp"
#include "../world/idtable.hpp" #include "../world/idtablebase.hpp"
CSMFilter::TextNode::TextNode (int columnId, const std::string& text) CSMFilter::TextNode::TextNode (int columnId, const std::string& text)
: mColumnId (columnId), mText (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<int, int>& columns) const const std::map<int, int>& columns) const
{ {
const std::map<int, int>::const_iterator iter = columns.find (mColumnId); const std::map<int, int>::const_iterator iter = columns.find (mColumnId);

View file

@ -14,7 +14,7 @@ namespace CSMFilter
TextNode (int columnId, const std::string& text); 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<int, int>& columns) const; const std::map<int, int>& columns) const;
///< \return Can the specified table row pass through to filter? ///< \return Can the specified table row pass through to filter?
/// \param columns column ID to column index mapping /// \param columns column ID to column index mapping

View file

@ -5,13 +5,13 @@
#include <stdexcept> #include <stdexcept>
#include "../world/columns.hpp" #include "../world/columns.hpp"
#include "../world/idtable.hpp" #include "../world/idtablebase.hpp"
CSMFilter::ValueNode::ValueNode (int columnId, Type lowerType, Type upperType, CSMFilter::ValueNode::ValueNode (int columnId, Type lowerType, Type upperType,
double lower, double upper) double lower, double upper)
: mColumnId (columnId), mLowerType (lowerType), mUpperType (upperType), mLower (lower), mUpper (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<int, int>& columns) const const std::map<int, int>& columns) const
{ {
const std::map<int, int>::const_iterator iter = columns.find (mColumnId); const std::map<int, int>::const_iterator iter = columns.find (mColumnId);

View file

@ -27,7 +27,7 @@ namespace CSMFilter
ValueNode (int columnId, Type lowerType, Type upperType, double lower, double upper); 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<int, int>& columns) const; const std::map<int, int>& columns) const;
///< \return Can the specified table row pass through to filter? ///< \return Can the specified table row pass through to filter?
/// \param columns column ID to column index mapping /// \param columns column ID to column index mapping

View file

@ -5,7 +5,7 @@
#include "columnbase.hpp" #include "columnbase.hpp"
CSMWorld::IdTable::IdTable (CollectionBase *idCollection, unsigned int features) CSMWorld::IdTable::IdTable (CollectionBase *idCollection, unsigned int features)
: mIdCollection (idCollection), mFeatures (features) : IdTableBase (features), mIdCollection (idCollection)
{} {}
CSMWorld::IdTable::~IdTable() CSMWorld::IdTable::~IdTable()
@ -185,17 +185,12 @@ void CSMWorld::IdTable::reorderRows (int baseIndex, const std::vector<int>& newO
index (baseIndex+newOrder.size()-1, mIdCollection->getColumns()-1)); index (baseIndex+newOrder.size()-1, mIdCollection->getColumns()-1));
} }
unsigned int CSMWorld::IdTable::getFeatures() const
{
return mFeatures;
}
std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view (int row) const std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view (int row) const
{ {
std::string id; std::string id;
std::string hint; std::string hint;
if (mFeatures & Feature_ViewCell) if (getFeatures() & Feature_ViewCell)
{ {
int cellColumn = mIdCollection->searchColumnIndex (Columns::ColumnId_Cell); int cellColumn = mIdCollection->searchColumnIndex (Columns::ColumnId_Cell);
int idColumn = mIdCollection->searchColumnIndex (Columns::ColumnId_Id); int idColumn = mIdCollection->searchColumnIndex (Columns::ColumnId_Id);
@ -206,7 +201,7 @@ std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view (int row)
hint = "r:" + std::string (mIdCollection->getData (row, idColumn).toString().toUtf8().constData()); 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); int column = mIdCollection->searchColumnIndex (Columns::ColumnId_Id);
@ -226,6 +221,11 @@ std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view (int row)
return std::make_pair (UniversalId (UniversalId::Type_Scene, id), hint); 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 int CSMWorld::IdTable::getColumnId(int column) const
{ {
return mIdCollection->getColumn(column).getId(); return mIdCollection->getColumn(column).getId();

View file

@ -3,8 +3,7 @@
#include <vector> #include <vector>
#include <QAbstractItemModel> #include "idtablebase.hpp"
#include "universalid.hpp" #include "universalid.hpp"
#include "columns.hpp" #include "columns.hpp"
@ -13,33 +12,13 @@ namespace CSMWorld
class CollectionBase; class CollectionBase;
class RecordBase; class RecordBase;
class IdTable : public QAbstractItemModel class IdTable : public IdTableBase
{ {
Q_OBJECT 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: private:
CollectionBase *mIdCollection; CollectionBase *mIdCollection;
unsigned int mFeatures;
// not implemented // not implemented
IdTable (const IdTable&); IdTable (const IdTable&);
@ -78,17 +57,17 @@ namespace CSMWorld
const std::string& destination, const std::string& destination,
UniversalId::Type type = UniversalId::Type_None); 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); void setRecord (const std::string& id, const RecordBase& record);
///< Add record or overwrite existing recrod. ///< Add record or overwrite existing recrod.
const RecordBase& getRecord (const std::string& id) const; 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. ///< 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 ///< Return index of column with the given \a id. If no such column exists, an exception is
/// thrown. /// thrown.
@ -96,12 +75,13 @@ namespace CSMWorld
///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices ///< 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). /// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex).
unsigned int getFeatures() const; virtual std::pair<UniversalId, std::string> view (int row) const;
std::pair<UniversalId, std::string> view (int row) const;
///< Return the UniversalId and the hint for viewing \a row. If viewing is not ///< Return the UniversalId and the hint for viewing \a row. If viewing is not
/// supported by this table, return (UniversalId::Type_None, ""). /// 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; int getColumnId(int column) const;
}; };
} }

View file

@ -0,0 +1,9 @@
#include "idtablebase.hpp"
CSMWorld::IdTableBase::IdTableBase (unsigned int features) : mFeatures (features) {}
unsigned int CSMWorld::IdTableBase::getFeatures() const
{
return mFeatures;
}

View file

@ -0,0 +1,64 @@
#ifndef CSM_WOLRD_IDTABLEBASE_H
#define CSM_WOLRD_IDTABLEBASE_H
#include <QAbstractItemModel>
#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<UniversalId, std::string> 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

View file

@ -3,7 +3,7 @@
#include <vector> #include <vector>
#include "idtable.hpp" #include "idtablebase.hpp"
void CSMWorld::IdTableProxyModel::updateColumnMap() void CSMWorld::IdTableProxyModel::updateColumnMap()
{ {
@ -13,7 +13,7 @@ void CSMWorld::IdTableProxyModel::updateColumnMap()
{ {
std::vector<int> columns = mFilter->getReferencedColumns(); std::vector<int> columns = mFilter->getReferencedColumns();
const IdTable& table = dynamic_cast<const IdTable&> (*sourceModel()); const IdTableBase& table = dynamic_cast<const IdTableBase&> (*sourceModel());
for (std::vector<int>::const_iterator iter (columns.begin()); iter!=columns.end(); ++iter) for (std::vector<int>::const_iterator iter (columns.begin()); iter!=columns.end(); ++iter)
mColumnMap.insert (std::make_pair (*iter, mColumnMap.insert (std::make_pair (*iter,
@ -28,7 +28,7 @@ bool CSMWorld::IdTableProxyModel::filterAcceptsRow (int sourceRow, const QModelI
return true; return true;
return mFilter->test ( return mFilter->test (
dynamic_cast<IdTable&> (*sourceModel()), sourceRow, mColumnMap); dynamic_cast<IdTableBase&> (*sourceModel()), sourceRow, mColumnMap);
} }
CSMWorld::IdTableProxyModel::IdTableProxyModel (QObject *parent) 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 QModelIndex CSMWorld::IdTableProxyModel::getModelIndex (const std::string& id, int column) const
{ {
return mapFromSource (dynamic_cast<IdTable&> (*sourceModel()).getModelIndex (id, column)); return mapFromSource (dynamic_cast<IdTableBase&> (*sourceModel()).getModelIndex (id, column));
} }
void CSMWorld::IdTableProxyModel::setFilter (const boost::shared_ptr<CSMFilter::Node>& filter) void CSMWorld::IdTableProxyModel::setFilter (const boost::shared_ptr<CSMFilter::Node>& filter)

View file

@ -14,6 +14,7 @@
#include "../../model/world/data.hpp" #include "../../model/world/data.hpp"
#include "../../model/world/commands.hpp" #include "../../model/world/commands.hpp"
#include "../../model/world/idtableproxymodel.hpp" #include "../../model/world/idtableproxymodel.hpp"
#include "../../model/world/idtablebase.hpp"
#include "../../model/world/idtable.hpp" #include "../../model/world/idtable.hpp"
#include "../../model/world/record.hpp" #include "../../model/world/record.hpp"
#include "../../model/world/columns.hpp" #include "../../model/world/columns.hpp"
@ -82,7 +83,7 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
menu.addAction (mExtendedDeleteAction); menu.addAction (mExtendedDeleteAction);
} }
if (mModel->getFeatures() & CSMWorld::IdTable::Feature_ReorderWithinTopic) if (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_ReorderWithinTopic)
{ {
/// \todo allow reordering of multiple rows /// \todo allow reordering of multiple rows
if (selectedRows.size()==1) if (selectedRows.size()==1)
@ -119,7 +120,7 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
row = mProxyModel->mapToSource (mProxyModel->index (row, 0)).row(); 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; CSMWorld::UniversalId id = mModel->view (row).first;
@ -131,7 +132,7 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
menu.addAction (mViewAction); menu.addAction (mViewAction);
} }
if (mModel->getFeatures() & CSMWorld::IdTable::Feature_Preview) if (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_Preview)
{ {
QModelIndex index = mModel->index (row, QModelIndex index = mModel->index (row,
mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Modification)); mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Modification));
@ -152,7 +153,7 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
: mCreateAction (0), mCloneAction(0), mRecordStatusDisplay (0), : mCreateAction (0), mCloneAction(0), mRecordStatusDisplay (0),
DragRecordTable(document) DragRecordTable(document)
{ {
mModel = &dynamic_cast<CSMWorld::IdTable&> (*mDocument.getData().getTableModel (id)); mModel = &dynamic_cast<CSMWorld::IdTableBase&> (*mDocument.getData().getTableModel (id));
mProxyModel = new CSMWorld::IdTableProxyModel (this); mProxyModel = new CSMWorld::IdTableProxyModel (this);
mProxyModel->setSourceModel (mModel); mProxyModel->setSourceModel (mModel);
@ -290,7 +291,7 @@ void CSVWorld::Table::cloneRecord()
{ {
QModelIndexList selectedRows = selectionModel()->selectedRows(); QModelIndexList selectedRows = selectionModel()->selectedRows();
const CSMWorld::UniversalId& toClone = getUniversalId(selectedRows.begin()->row()); 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); emit cloneRequest (toClone);
} }
@ -324,7 +325,8 @@ void CSVWorld::Table::moveUpRecord()
for (int i=1; i<row2-row; ++i) for (int i=1; i<row2-row; ++i)
newOrder[i] = i; newOrder[i] = i;
mDocument.getUndoStack().push (new CSMWorld::ReorderRowsCommand (*mModel, row, newOrder)); mDocument.getUndoStack().push (new CSMWorld::ReorderRowsCommand (
dynamic_cast<CSMWorld::IdTable&> (*mModel), row, newOrder));
} }
} }
} }
@ -356,7 +358,8 @@ void CSVWorld::Table::moveDownRecord()
for (int i=1; i<row2-row; ++i) for (int i=1; i<row2-row; ++i)
newOrder[i] = i; newOrder[i] = i;
mDocument.getUndoStack().push (new CSMWorld::ReorderRowsCommand (*mModel, row, newOrder)); mDocument.getUndoStack().push (new CSMWorld::ReorderRowsCommand (
dynamic_cast<CSMWorld::IdTable&> (*mModel), row, newOrder));
} }
} }
} }

View file

@ -23,7 +23,7 @@ namespace CSMWorld
class Data; class Data;
class UniversalId; class UniversalId;
class IdTableProxyModel; class IdTableProxyModel;
class IdTable; class IdTableBase;
class CommandDispatcher; class CommandDispatcher;
} }
@ -49,7 +49,7 @@ namespace CSVWorld
QAction *mExtendedDeleteAction; QAction *mExtendedDeleteAction;
QAction *mExtendedRevertAction; QAction *mExtendedRevertAction;
CSMWorld::IdTableProxyModel *mProxyModel; CSMWorld::IdTableProxyModel *mProxyModel;
CSMWorld::IdTable *mModel; CSMWorld::IdTableBase *mModel;
int mRecordStatusDisplay; int mRecordStatusDisplay;
CSMWorld::CommandDispatcher *mDispatcher; CSMWorld::CommandDispatcher *mDispatcher;