1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-26 18:35:20 +00:00

Reorganised class inheritance structure of collections, columns and idtable model.

This commit is contained in:
cc9cii 2015-04-02 20:19:15 +11:00
parent ece34a1baa
commit 83bcc8d451
19 changed files with 590 additions and 372 deletions

View File

@ -18,15 +18,14 @@ opencs_hdrs_noqt (model/doc
opencs_units (model/world opencs_units (model/world
idtable idtableproxymodel regionmap data commanddispatcher idtable idtableproxymodel regionmap data commanddispatcher idtablebase resourcetable nestedtableproxymodel idtree
idtablebase resourcetable nestedtableproxymodel
) )
opencs_units_noqt (model/world opencs_units_noqt (model/world
universalid record commands columnbase scriptcontext cell refidcollection universalid record commands columnbase scriptcontext cell refidcollection
refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope
pathgrid landtexture land nestedtablewrapper nestedadapters pathgrid landtexture land nestedtablewrapper nestedadapters nestedcollection nestablecolumn
) )
opencs_hdrs_noqt (model/world opencs_hdrs_noqt (model/world

View File

@ -1,9 +1,10 @@
#include "columnbase.hpp" #include "columnbase.hpp"
#include "columns.hpp" #include "columns.hpp"
CSMWorld::ColumnBase::ColumnBase (int columnId, Display displayType, int flags, bool canNest) CSMWorld::ColumnBase::ColumnBase (int columnId, Display displayType, int flags)
: mColumnId (columnId), mDisplayType (displayType), mFlags (flags), mCanNest(canNest) : mColumnId (columnId), mDisplayType (displayType), mFlags (flags)
{} {}
CSMWorld::ColumnBase::~ColumnBase() {} CSMWorld::ColumnBase::~ColumnBase() {}
@ -22,43 +23,3 @@ int CSMWorld::ColumnBase::getId() const
{ {
return mColumnId; return mColumnId;
} }
bool CSMWorld::NestColumn::canHaveNestedColumns() const
{
return mCanNest;
}
void CSMWorld::NestColumn::addNestedColumn(int columnId, Display displayType)
{
if (!mCanNest)
throw std::logic_error("Tried to nest inside of the non-nest column");
mNestedColumns.push_back(CSMWorld::NestedColumn(columnId, displayType, mFlags, this));
}
const CSMWorld::ColumnBase& CSMWorld::NestColumn::nestedColumn(int subColumn) const
{
if (!mCanNest)
throw std::logic_error("Tried to access nested column of the non-nest column");
return mNestedColumns.at(subColumn);
}
int CSMWorld::NestColumn::nestedColumnCount() const
{
if (!mCanNest)
throw std::logic_error("Tried to access number of the subcolumns in the non-nest column");
return mNestedColumns.size();
}
CSMWorld::NestColumn::NestColumn(int columnId, Display displayType, int flags, bool canNest)
: CSMWorld::ColumnBase(columnId, displayType, flags, canNest) {}
CSMWorld::NestedColumn::NestedColumn(int columnId, Display displayType, int flag, const CSMWorld::NestColumn* parent)
: mParent(parent), CSMWorld::ColumnBase(columnId, displayType, flag) {}
bool CSMWorld::NestedColumn::isEditable() const
{
return mParent->isEditable();
}

View File

@ -3,7 +3,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <exception> #include <stdexcept>
#include <Qt> #include <Qt>
#include <QVariant> #include <QVariant>
@ -117,9 +117,8 @@ namespace CSMWorld
int mColumnId; int mColumnId;
int mFlags; int mFlags;
Display mDisplayType; Display mDisplayType;
bool mCanNest;
ColumnBase (int columnId, Display displayType, int flag, bool canNest = false); ColumnBase (int columnId, Display displayType, int flag);
virtual ~ColumnBase(); virtual ~ColumnBase();
@ -133,39 +132,11 @@ namespace CSMWorld
virtual int getId() const; virtual int getId() const;
}; };
class NestedColumn;
class NestColumn : public ColumnBase
{
std::vector<NestedColumn> mNestedColumns;
public:
NestColumn(int columnId, Display displayType, int flags, bool canNest);
void addNestedColumn(int columnId, Display displayType);
bool canHaveNestedColumns() const;
const ColumnBase& nestedColumn(int subColumn) const;
int nestedColumnCount() const;
};
class NestedColumn : public ColumnBase
{
const ColumnBase* mParent;
public:
NestedColumn(int columnId, Display displayType, int flag, const NestColumn* parent);
virtual bool isEditable() const;
};
template<typename ESXRecordT> template<typename ESXRecordT>
struct Column : public NestColumn struct Column : public ColumnBase
{ {
Column (int columnId, Display displayType, int flags = Flag_Table | Flag_Dialogue, bool canNest = false) Column (int columnId, Display displayType, int flags = Flag_Table | Flag_Dialogue)
: NestColumn (columnId, displayType, flags, canNest) {} : ColumnBase (columnId, displayType, flags) {}
virtual QVariant get (const Record<ESXRecordT>& record) const = 0; virtual QVariant get (const Record<ESXRecordT>& record) const = 0;

View File

@ -3,6 +3,7 @@
#include <QAbstractItemModel> #include <QAbstractItemModel>
#include "idtable.hpp" #include "idtable.hpp"
#include "idtree.hpp"
#include <components/misc/stringops.hpp> #include <components/misc/stringops.hpp>
#include "nestedtablewrapper.hpp" #include "nestedtablewrapper.hpp"
@ -172,10 +173,10 @@ void CSMWorld::CloneCommand::undo()
mModel.removeRow (mModel.getModelIndex (mId, 0).row()); mModel.removeRow (mModel.getModelIndex (mId, 0).row());
} }
CSMWorld::DeleteNestedCommand::DeleteNestedCommand (IdTable& model, CSMWorld::DeleteNestedCommand::DeleteNestedCommand (IdTree& model,
const std::string& id, const std::string& id,
int nestedRow, int nestedRow,
int parentColumn, int parentColumn,
QUndoCommand* parent) : QUndoCommand* parent) :
mId(id), mId(id),
mModel(model), mModel(model),
@ -192,7 +193,7 @@ void CSMWorld::DeleteNestedCommand::redo()
const QModelIndex& parentIndex = mModel.getModelIndex(mId, mParentColumn); const QModelIndex& parentIndex = mModel.getModelIndex(mId, mParentColumn);
mModel.removeRows (mNestedRow, 1, parentIndex); mModel.removeRows (mNestedRow, 1, parentIndex);
} }
void CSMWorld::DeleteNestedCommand::undo() void CSMWorld::DeleteNestedCommand::undo()
@ -202,7 +203,7 @@ void CSMWorld::DeleteNestedCommand::undo()
mModel.setNestedTable(parentIndex, getOld()); mModel.setNestedTable(parentIndex, getOld());
} }
CSMWorld::AddNestedCommand::AddNestedCommand(IdTable& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent) CSMWorld::AddNestedCommand::AddNestedCommand(IdTree& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent)
: mModel(model), : mModel(model),
mId(id), mId(id),
mNewRow(nestedRow), mNewRow(nestedRow),
@ -227,7 +228,7 @@ void CSMWorld::AddNestedCommand::undo()
mModel.setNestedTable(parentIndex, getOld()); mModel.setNestedTable(parentIndex, getOld());
} }
CSMWorld::NestedTableStoring::NestedTableStoring(const IdTable& model, const std::string& id, int parentColumn) CSMWorld::NestedTableStoring::NestedTableStoring(const IdTree& model, const std::string& id, int parentColumn)
: mOld(model.nestedTable(model.getModelIndex(id, parentColumn))) {} : mOld(model.nestedTable(model.getModelIndex(id, parentColumn))) {}
CSMWorld::NestedTableStoring::~NestedTableStoring() CSMWorld::NestedTableStoring::~NestedTableStoring()

View File

@ -10,7 +10,6 @@
#include <QVariant> #include <QVariant>
#include <QUndoCommand> #include <QUndoCommand>
#include <QModelIndex> #include <QModelIndex>
#include <QVariant>
#include "universalid.hpp" #include "universalid.hpp"
#include "nestedtablewrapper.hpp" #include "nestedtablewrapper.hpp"
@ -21,7 +20,7 @@ class QAbstractItemModel;
namespace CSMWorld namespace CSMWorld
{ {
class IdTable; class IdTable;
class IdTable; class IdTree;
struct RecordBase; struct RecordBase;
class NestedTableWrapperBase; class NestedTableWrapperBase;
@ -148,18 +147,18 @@ namespace CSMWorld
NestedTableWrapperBase* mOld; NestedTableWrapperBase* mOld;
public: public:
NestedTableStoring(const IdTable& model, const std::string& id, int parentColumn); NestedTableStoring(const IdTree& model, const std::string& id, int parentColumn);
~NestedTableStoring(); ~NestedTableStoring();
protected: protected:
const NestedTableWrapperBase& getOld() const; const NestedTableWrapperBase& getOld() const;
}; };
class DeleteNestedCommand : public QUndoCommand, private NestedTableStoring class DeleteNestedCommand : public QUndoCommand, private NestedTableStoring
{ {
IdTable& mModel; IdTree& mModel;
std::string mId; std::string mId;
@ -169,16 +168,16 @@ namespace CSMWorld
public: public:
DeleteNestedCommand (IdTable& 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();
virtual void undo(); virtual void undo();
}; };
class AddNestedCommand : public QUndoCommand, private NestedTableStoring class AddNestedCommand : public QUndoCommand, private NestedTableStoring
{ {
IdTable& mModel; IdTree& mModel;
std::string mId; std::string mId;
@ -188,7 +187,7 @@ namespace CSMWorld
public: public:
AddNestedCommand(IdTable& 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 redo();

View File

@ -12,6 +12,7 @@
#include <components/esm/cellref.hpp> #include <components/esm/cellref.hpp>
#include "idtable.hpp" #include "idtable.hpp"
#include "idtree.hpp"
#include "columnimp.hpp" #include "columnimp.hpp"
#include "regionmap.hpp" #include "regionmap.hpp"
#include "columns.hpp" #include "columns.hpp"
@ -332,7 +333,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
addModel (new IdTable (&mMagicEffects), UniversalId::Type_MagicEffect); addModel (new IdTable (&mMagicEffects), UniversalId::Type_MagicEffect);
addModel (new IdTable (&mPathgrids), UniversalId::Type_Pathgrid); addModel (new IdTable (&mPathgrids), UniversalId::Type_Pathgrid);
addModel (new IdTable (&mStartScripts), UniversalId::Type_StartScript); addModel (new IdTable (&mStartScripts), UniversalId::Type_StartScript);
addModel (new IdTable (&mReferenceables, IdTable::Feature_Preview), addModel (new IdTree (&mReferenceables, IdTable::Feature_Preview),
UniversalId::Type_Referenceable); UniversalId::Type_Referenceable);
addModel (new IdTable (&mRefs, IdTable::Feature_ViewCell | IdTable::Feature_Preview), UniversalId::Type_Reference); addModel (new IdTable (&mRefs, IdTable::Feature_ViewCell | IdTable::Feature_Preview), UniversalId::Type_Reference);
addModel (new IdTable (&mFilters), UniversalId::Type_Filter); addModel (new IdTable (&mFilters), UniversalId::Type_Filter);

View File

@ -1,12 +1,6 @@
#include "idtable.hpp" #include "idtable.hpp"
#include <QDebug>
#include <cassert>
#include <iostream>
#include "nestedtablewrapper.hpp"
#include "collectionbase.hpp" #include "collectionbase.hpp"
#include "nestedcollection.hpp"
#include "columnbase.hpp" #include "columnbase.hpp"
CSMWorld::IdTable::IdTable (CollectionBase *idCollection, unsigned int features) CSMWorld::IdTable::IdTable (CollectionBase *idCollection, unsigned int features)
@ -14,26 +8,20 @@ CSMWorld::IdTable::IdTable (CollectionBase *idCollection, unsigned int features)
{} {}
CSMWorld::IdTable::~IdTable() CSMWorld::IdTable::~IdTable()
{ {}
mIdCollection = 0; // FIXME: workaround only, should stop QHideEvent calling after destruction
}
int CSMWorld::IdTable::rowCount (const QModelIndex & parent) const int CSMWorld::IdTable::rowCount (const QModelIndex & parent) const
{ {
if (hasChildren(parent)) if (parent.isValid())
{ return 0;
return dynamic_cast<NestedCollection*>(mIdCollection)->getNestedRowsCount(parent.row(), parent.column());
}
return mIdCollection->getSize(); return mIdCollection->getSize();
} }
int CSMWorld::IdTable::columnCount (const QModelIndex & parent) const int CSMWorld::IdTable::columnCount (const QModelIndex & parent) const
{ {
if (hasChildren(parent)) if (parent.isValid())
{ return 0;
return dynamic_cast<NestedCollection*>(mIdCollection)->getNestedColumnsCount(parent.row(), parent.column());
}
return mIdCollection->getColumns(); return mIdCollection->getColumns();
} }
@ -46,23 +34,10 @@ QVariant CSMWorld::IdTable::data (const QModelIndex & index, int role) const
if (role==Qt::EditRole && !mIdCollection->getColumn (index.column()).isEditable()) if (role==Qt::EditRole && !mIdCollection->getColumn (index.column()).isEditable())
return QVariant(); return QVariant();
if (index.internalId() != 0) return mIdCollection->getData (index.row(), index.column());
{
std::pair<int, int> parentAdress(unfoldIndexAdress(index.internalId()));
return dynamic_cast<NestedCollection*>(mIdCollection)->getNestedData(parentAdress.first,
parentAdress.second,
index.row(),
index.column());
}
else
{
return mIdCollection->getData (index.row(), index.column());
}
} }
QVariant CSMWorld::IdTable::headerData (int section, QVariant CSMWorld::IdTable::headerData (int section, Qt::Orientation orientation, int role) const
Qt::Orientation orientation,
int role) const
{ {
if (orientation==Qt::Vertical) if (orientation==Qt::Vertical)
return QVariant(); return QVariant();
@ -74,63 +49,19 @@ QVariant CSMWorld::IdTable::headerData (int section,
return mIdCollection->getColumn (section).mFlags; return mIdCollection->getColumn (section).mFlags;
if (role==ColumnBase::Role_Display) if (role==ColumnBase::Role_Display)
{
return mIdCollection->getColumn (section).mDisplayType; return mIdCollection->getColumn (section).mDisplayType;
}
return QVariant();
}
QVariant CSMWorld::IdTable::nestedHeaderData(int section, int subSection, Qt::Orientation orientation, int role) const
{
// FIXME: workaround only, should stop QHideEvent calling after destruction
if (section < 0 || !mIdCollection || section >= mIdCollection->getColumns())
return QVariant();
const NestColumn& parentColumn = dynamic_cast<const NestColumn&>(mIdCollection->getColumn(section));
if (orientation==Qt::Vertical)
return QVariant();
if (role==Qt::DisplayRole)
return tr(parentColumn.nestedColumn(subSection).getTitle().c_str());
if (role==ColumnBase::Role_Flags)
return mIdCollection->getColumn (section).mFlags;
if (role==ColumnBase::Role_Display)
return parentColumn.nestedColumn(subSection).mDisplayType;
return QVariant(); return QVariant();
} }
bool CSMWorld::IdTable::setData (const QModelIndex &index, const QVariant &value, int role) bool CSMWorld::IdTable::setData (const QModelIndex &index, const QVariant &value, int role)
{ {
if (index.internalId() != 0)
{
if (mIdCollection->getColumn(parent(index).column()).isEditable() && role==Qt::EditRole)
{
const std::pair<int, int>& parentAdress(unfoldIndexAdress(index.internalId()));
dynamic_cast<NestedCollection*>(mIdCollection)->setNestedData(parentAdress.first, parentAdress.second, value, index.row(), index.column());
emit dataChanged (CSMWorld::IdTable::index (parentAdress.first, 0),
CSMWorld::IdTable::index (parentAdress.second, mIdCollection->getColumns()-1));
return true;
}
else
{
return false;
}
}
if (mIdCollection->getColumn (index.column()).isEditable() && role==Qt::EditRole) if (mIdCollection->getColumn (index.column()).isEditable() && role==Qt::EditRole)
{ {
mIdCollection->setData (index.row(), index.column(), value); mIdCollection->setData (index.row(), index.column(), value);
emit dataChanged (CSMWorld::IdTable::index (index.row(), 0), emit dataChanged (CSMWorld::IdTable::index (index.row(), 0),
CSMWorld::IdTable::index (index.row(), mIdCollection->getColumns()-1)); CSMWorld::IdTable::index (index.row(), mIdCollection->getColumns()-1));
return true; return true;
} }
@ -150,56 +81,22 @@ Qt::ItemFlags CSMWorld::IdTable::flags (const QModelIndex & index) const
bool CSMWorld::IdTable::removeRows (int row, int count, const QModelIndex& parent) bool CSMWorld::IdTable::removeRows (int row, int count, const QModelIndex& parent)
{ {
if (parent.isValid())
return false;
beginRemoveRows (parent, row, row+count-1); beginRemoveRows (parent, row, row+count-1);
if (parent.isValid()) mIdCollection->removeRows (row, count);
{
for (int i = 0; i < count; ++i)
{
dynamic_cast<NestedCollection*>(mIdCollection)->removeNestedRows(parent.row(), parent.column(), row+i);
}
}
else
{
beginRemoveRows (parent, row, row+count-1);
mIdCollection->removeRows (row, count);
}
endRemoveRows(); endRemoveRows();
emit dataChanged (CSMWorld::IdTable::index (parent.row(), 0),
CSMWorld::IdTable::index (parent.row(), mIdCollection->getColumns()-1));
return true; return true;
} }
void CSMWorld::IdTable::addNestedRow(const QModelIndex& parent, int position)
{
if (!hasChildren(parent))
{
throw std::logic_error("Tried to set nested table, but index has no children");
}
int row = parent.row();
beginInsertRows(parent, position, position);
dynamic_cast<NestedCollection*>(mIdCollection)->addNestedRow(row, parent.column(), position);
endInsertRows();
emit dataChanged (CSMWorld::IdTable::index (row, 0),
CSMWorld::IdTable::index (row, mIdCollection->getColumns()-1));
}
QModelIndex CSMWorld::IdTable::index (int row, int column, const QModelIndex& parent) const QModelIndex CSMWorld::IdTable::index (int row, int column, const QModelIndex& parent) const
{ {
unsigned int encodedId = 0;
if (parent.isValid()) if (parent.isValid())
{ return QModelIndex();
encodedId = this->foldIndexAdress(parent);
}
if (row<0 || row>=mIdCollection->getSize()) if (row<0 || row>=mIdCollection->getSize())
return QModelIndex(); return QModelIndex();
@ -207,24 +104,12 @@ QModelIndex CSMWorld::IdTable::index (int row, int column, const QModelIndex& pa
if (column<0 || column>=mIdCollection->getColumns()) if (column<0 || column>=mIdCollection->getColumns())
return QModelIndex(); return QModelIndex();
return createIndex(row, column, encodedId); return createIndex (row, column);
} }
QModelIndex CSMWorld::IdTable::parent (const QModelIndex& index) const QModelIndex CSMWorld::IdTable::parent (const QModelIndex& index) const
{ {
if (index.internalId() == 0) //0 is used for indexs with invalid parent (top level data) return QModelIndex();
{
return QModelIndex();
}
unsigned int id = index.internalId();
const std::pair<int, int>& adress(unfoldIndexAdress(id));
if (adress.first >= this->rowCount() || adress.second >= this->columnCount())
{
throw "Parent index is not present in the model";
}
return createIndex(adress.first, adress.second);
} }
void CSMWorld::IdTable::addRecord (const std::string& id, UniversalId::Type type) void CSMWorld::IdTable::addRecord (const std::string& id, UniversalId::Type type)
@ -346,66 +231,3 @@ int CSMWorld::IdTable::getColumnId(int column) const
{ {
return mIdCollection->getColumn(column).getId(); return mIdCollection->getColumn(column).getId();
} }
unsigned int CSMWorld::IdTable::foldIndexAdress (const QModelIndex& index) const
{
unsigned int out = index.row() * this->columnCount();
out += index.column();
return ++out;
}
std::pair< int, int > CSMWorld::IdTable::unfoldIndexAdress (unsigned int id) const
{
if (id == 0)
{
throw "Attempt to unfold index id of the top level data cell";
}
--id;
int row = id / this->columnCount();
int column = id - row * this->columnCount();
return std::make_pair (row, column);
}
bool CSMWorld::IdTable::hasChildren(const QModelIndex& index) const
{
return (index.isValid() &&
index.internalId() == 0 &&
mIdCollection->getColumn(index.column()).mCanNest &&
index.data().isValid());
}
void CSMWorld::IdTable::setNestedTable(const QModelIndex& index, const CSMWorld::NestedTableWrapperBase& nestedTable)
{
if (!hasChildren(index))
{
throw std::logic_error("Tried to set nested table, but index has no children");
}
bool removeRowsMode = false;
if (nestedTable.size() != this->nestedTable(index)->size())
{
emit resetStart(this->index(index.row(), 0).data().toString());
removeRowsMode = true;
}
dynamic_cast<NestedCollection*>(mIdCollection)->setNestedTable(index.row(), index.column(), nestedTable);
emit dataChanged (CSMWorld::IdTable::index (index.row(), 0),
CSMWorld::IdTable::index (index.row(), mIdCollection->getColumns()-1));
if (removeRowsMode)
{
emit resetEnd(this->index(index.row(), 0).data().toString());
}
}
CSMWorld::NestedTableWrapperBase* CSMWorld::IdTable::nestedTable(const QModelIndex& index) const
{
if (!hasChildren(index))
{
throw std::logic_error("Tried to retrive nested table, but index has no children");
}
return dynamic_cast<NestedCollection*>(mIdCollection)->nestedTable(index.row(), index.column());
}

View File

@ -7,20 +7,10 @@
#include "universalid.hpp" #include "universalid.hpp"
#include "columns.hpp" #include "columns.hpp"
/*! \brief
* Clas for holding the model. Uses typical qt table abstraction/interface for granting access to the individiual fields of the records,
* Some records are holding nested data (for instance inventory list of the npc). In casses like this, table model offers interface
* to access nested data in the qt way that is specify parent. Since some of those nested data require multiple columns to
* represent informations, single int (default way to index model in the qmodelindex) is not sufficiant. Therefore tablemodelindex class
* can hold two ints for the sake of indexing two dimensions of the table. This model does not support multiple levels of the nested
* data. Vast majority of methods makes sense only for the top level data.
*/
namespace CSMWorld namespace CSMWorld
{ {
class CollectionBase; class CollectionBase;
struct RecordBase; struct RecordBase;
class NestedTableWrapperBase;
class IdTable : public IdTableBase class IdTable : public IdTableBase
{ {
@ -33,8 +23,6 @@ namespace CSMWorld
// not implemented // not implemented
IdTable (const IdTable&); IdTable (const IdTable&);
IdTable& operator= (const IdTable&); IdTable& operator= (const IdTable&);
unsigned int foldIndexAdress(const QModelIndex& index) const;
std::pair<int, int> unfoldIndexAdress(unsigned int id) const;
public: public:
@ -51,27 +39,17 @@ namespace CSMWorld
virtual QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; virtual QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
QVariant nestedHeaderData(int section, int subSection, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
NestedTableWrapperBase* nestedTable(const QModelIndex &index) const;
void setNestedTable(const QModelIndex &index, const NestedTableWrapperBase& nestedTable);
virtual bool setData ( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); virtual bool setData ( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
virtual Qt::ItemFlags flags (const QModelIndex & index) const; virtual Qt::ItemFlags flags (const QModelIndex & index) const;
virtual bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex()); virtual bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex());
void addNestedRow (const QModelIndex& parent, int position);
virtual QModelIndex index (int row, int column, const QModelIndex& parent = QModelIndex()) virtual QModelIndex index (int row, int column, const QModelIndex& parent = QModelIndex())
const; const;
virtual QModelIndex parent (const QModelIndex& index) const; virtual QModelIndex parent (const QModelIndex& index) const;
virtual bool hasChildren (const QModelIndex& index) const;
void addRecord (const std::string& id, UniversalId::Type type = UniversalId::Type_None); void addRecord (const std::string& id, UniversalId::Type type = UniversalId::Type_None);
///< \param type Will be ignored, unless the collection supports multiple record types ///< \param type Will be ignored, unless the collection supports multiple record types
@ -105,11 +83,6 @@ namespace CSMWorld
virtual bool isDeleted (const std::string& id) const; virtual bool isDeleted (const std::string& id) const;
int getColumnId(int column) const; int getColumnId(int column) const;
signals:
void resetStart(const QString& id);
void resetEnd(const QString& id);
}; };
} }

View File

@ -0,0 +1,296 @@
#include "idtree.hpp"
#include "nestedtablewrapper.hpp" // FIXME: is this necessary?
#include "nestedcollection.hpp"
#include "nestablecolumn.hpp"
CSMWorld::IdTree::IdTree (NestedCollection *idCollection, unsigned int features)
: IdTable (idCollection, features), mIdCollection (idCollection)
{}
CSMWorld::IdTree::~IdTree()
{
// FIXME: workaround only, a proper fix should stop QHideEvent calls after destruction
mIdCollection = 0;
}
int CSMWorld::IdTree::rowCount (const QModelIndex & parent) const
{
if (hasChildren(parent))
return mIdCollection->getNestedRowsCount(parent.row(), parent.column());
return mIdCollection->getSize();
}
int CSMWorld::IdTree::columnCount (const QModelIndex & parent) const
{
if (hasChildren(parent))
return mIdCollection->getNestedColumnsCount(parent.row(), parent.column());
return mIdCollection->getColumns();
}
QVariant CSMWorld::IdTree::data (const QModelIndex & index, int role) const
{
if (!index.isValid())
return QVariant();
if ((role!=Qt::DisplayRole && role!=Qt::EditRole) || index.row() < 0 || index.column() < 0)
return QVariant();
if (role==Qt::EditRole && !mIdCollection->getColumn (index.column()).isEditable())
return QVariant();
if (index.internalId() != 0)
{
std::pair<int, int> parentAdress(unfoldIndexAdress(index.internalId()));
return mIdCollection->getNestedData(parentAdress.first,
parentAdress.second, index.row(), index.column());
}
else
return mIdCollection->getData (index.row(), index.column());
}
QVariant CSMWorld::IdTree::headerData (int section, Qt::Orientation orientation, int role) const
{
if (orientation==Qt::Vertical)
return QVariant();
if (orientation != Qt::Horizontal)
throw std::logic_error("Unknown header orientation specified");
if (role == Qt::DisplayRole)
return tr (mIdCollection->getColumn (section).getTitle().c_str());
if (role == ColumnBase::Role_Flags)
return mIdCollection->getColumn (section).mFlags;
if (role == ColumnBase::Role_Display)
return mIdCollection->getColumn (section).mDisplayType;
return QVariant();
}
QVariant CSMWorld::IdTree::nestedHeaderData(int section, int subSection, Qt::Orientation orientation, int role) const
{
// FIXME: workaround only, a proper fix should stop QHideEvent calls after destruction
if (section < 0 || !mIdCollection || section >= mIdCollection->getColumns())
return QVariant();
// FIXME: dynamic cast
const NestableColumn& parentColumn = dynamic_cast<const NestableColumn&>(mIdCollection->getColumn(section));
if (orientation==Qt::Vertical)
return QVariant();
if (role==Qt::DisplayRole)
return tr(parentColumn.nestedColumn(subSection).getTitle().c_str());
if (role==ColumnBase::Role_Flags)
return mIdCollection->getColumn (section).mFlags;
if (role==ColumnBase::Role_Display)
return parentColumn.nestedColumn(subSection).mDisplayType;
return QVariant();
}
bool CSMWorld::IdTree::setData (const QModelIndex &index, const QVariant &value, int role)
{
if (index.internalId() != 0)
{
if (mIdCollection->getColumn(parent(index).column()).isEditable() && role==Qt::EditRole)
{
const std::pair<int, int>& parentAdress(unfoldIndexAdress(index.internalId()));
mIdCollection->setNestedData(parentAdress.first, parentAdress.second, value, index.row(), index.column());
emit dataChanged (CSMWorld::IdTree::index (parentAdress.first, 0),
CSMWorld::IdTree::index (parentAdress.second, mIdCollection->getColumns()-1));
return true;
}
else
return false;
}
if (mIdCollection->getColumn (index.column()).isEditable() && role==Qt::EditRole)
{
mIdCollection->setData (index.row(), index.column(), value);
emit dataChanged (CSMWorld::IdTree::index (index.row(), 0),
CSMWorld::IdTree::index (index.row(), mIdCollection->getColumns()-1));
return true;
}
return false;
}
Qt::ItemFlags CSMWorld::IdTree::flags (const QModelIndex & index) const
{
if (!index.isValid())
return 0;
Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
if (mIdCollection->getColumn (index.column()).isUserEditable())
flags |= Qt::ItemIsEditable;
return flags;
}
bool CSMWorld::IdTree::removeRows (int row, int count, const QModelIndex& parent)
{
beginRemoveRows (parent, row, row+count-1);
if (parent.isValid())
{
for (int i = 0; i < count; ++i)
{
mIdCollection->removeNestedRows(parent.row(), parent.column(), row+i);
}
}
else
{
beginRemoveRows (parent, row, row+count-1);
mIdCollection->removeRows (row, count);
}
endRemoveRows();
emit dataChanged (CSMWorld::IdTree::index (parent.row(), 0),
CSMWorld::IdTree::index (parent.row(), mIdCollection->getColumns()-1));
return true;
}
void CSMWorld::IdTree::addNestedRow(const QModelIndex& parent, int position)
{
if (!hasChildren(parent))
throw std::logic_error("Tried to set nested table, but index has no children");
int row = parent.row();
beginInsertRows(parent, position, position);
mIdCollection->addNestedRow(row, parent.column(), position);
endInsertRows();
emit dataChanged (CSMWorld::IdTree::index (row, 0),
CSMWorld::IdTree::index (row, mIdCollection->getColumns()-1));
}
QModelIndex CSMWorld::IdTree::index (int row, int column, const QModelIndex& parent) const
{
unsigned int encodedId = 0;
if (parent.isValid())
{
encodedId = this->foldIndexAdress(parent);
}
if (row<0 || row>=mIdCollection->getSize())
return QModelIndex();
if (column<0 || column>=mIdCollection->getColumns())
return QModelIndex();
return createIndex(row, column, encodedId); // store internal id
}
QModelIndex CSMWorld::IdTree::parent (const QModelIndex& index) const
{
if (index.internalId() == 0) // 0 is used for indexs with invalid parent (top level data)
return QModelIndex();
unsigned int id = index.internalId();
const std::pair<int, int>& adress(unfoldIndexAdress(id));
if (adress.first >= this->rowCount() || adress.second >= this->columnCount())
throw "Parent index is not present in the model";
return createIndex(adress.first, adress.second);
}
void CSMWorld::IdTree::setRecord (const std::string& id, const RecordBase& record)
{
int index = mIdCollection->searchId (id);
if (index==-1)
{
int index = mIdCollection->getAppendIndex (id);
beginInsertRows (QModelIndex(), index, index);
mIdCollection->appendRecord (record);
endInsertRows();
}
else
{
mIdCollection->replace (index, record);
emit dataChanged (CSMWorld::IdTree::index (index, 0),
CSMWorld::IdTree::index (index, mIdCollection->getColumns()-1));
}
}
unsigned int CSMWorld::IdTree::foldIndexAdress (const QModelIndex& index) const
{
unsigned int out = index.row() * this->columnCount();
out += index.column();
return ++out;
}
std::pair< int, int > CSMWorld::IdTree::unfoldIndexAdress (unsigned int id) const
{
if (id == 0)
throw "Attempt to unfold index id of the top level data cell";
--id;
int row = id / this->columnCount();
int column = id - row * this->columnCount();
return std::make_pair (row, column);
}
bool CSMWorld::IdTree::hasChildren(const QModelIndex& index) const
{
// FIXME: dynamic cast
return (index.isValid() &&
index.internalId() == 0 &&
dynamic_cast<const CSMWorld::NestableColumn &>(mIdCollection->getColumn(index.column())).hasChildren() &&
index.data().isValid());
}
void CSMWorld::IdTree::setNestedTable(const QModelIndex& index, const CSMWorld::NestedTableWrapperBase& nestedTable)
{
if (!hasChildren(index))
throw std::logic_error("Tried to set nested table, but index has no children");
bool removeRowsMode = false;
if (nestedTable.size() != this->nestedTable(index)->size())
{
emit resetStart(this->index(index.row(), 0).data().toString());
removeRowsMode = true;
}
mIdCollection->setNestedTable(index.row(), index.column(), nestedTable);
emit dataChanged (CSMWorld::IdTree::index (index.row(), 0),
CSMWorld::IdTree::index (index.row(), mIdCollection->getColumns()-1));
if (removeRowsMode)
{
emit resetEnd(this->index(index.row(), 0).data().toString());
}
}
CSMWorld::NestedTableWrapperBase* CSMWorld::IdTree::nestedTable(const QModelIndex& index) const
{
if (!hasChildren(index))
throw std::logic_error("Tried to retrive nested table, but index has no children");
return mIdCollection->nestedTable(index.row(), index.column());
}

View File

@ -0,0 +1,88 @@
#ifndef CSM_WOLRD_IDTREE_H
#define CSM_WOLRD_IDTREE_H
#include "idtable.hpp"
#include "universalid.hpp"
#include "columns.hpp"
/*! \brief
* Class for holding the model. Uses typical qt table abstraction/interface for granting access
* to the individiual fields of the records, Some records are holding nested data (for instance
* inventory list of the npc). In casses like this, table model offers interface to access
* nested data in the qt way - that is specify parent. Since some of those nested data require
* multiple columns to represent informations, single int (default way to index model in the
* qmodelindex) is not sufficiant. Therefore tablemodelindex class can hold two ints for the
* sake of indexing two dimensions of the table. This model does not support multiple levels of
* the nested data. Vast majority of methods makes sense only for the top level data.
*/
namespace CSMWorld
{
class NestedCollection;
struct RecordBase;
class NestedTableWrapperBase; // FIXME: is this necessary?
class IdTree : public IdTable // IdTable is derived from QAbstractItemModel
{
Q_OBJECT
private:
NestedCollection *mIdCollection;
// not implemented
IdTree (const IdTree&);
IdTree& operator= (const IdTree&);
unsigned int foldIndexAdress(const QModelIndex& index) const;
std::pair<int, int> unfoldIndexAdress(unsigned int id) const;
public:
IdTree (NestedCollection *idCollection, unsigned int features = 0);
///< The ownership of \a idCollection is not transferred.
virtual ~IdTree();
virtual int rowCount (const QModelIndex & parent = QModelIndex()) const;
virtual int columnCount (const QModelIndex & parent = QModelIndex()) const;
virtual QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const;
virtual QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
virtual bool setData ( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
virtual Qt::ItemFlags flags (const QModelIndex & index) const;
virtual bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex());
virtual QModelIndex index (int row, int column, const QModelIndex& parent = QModelIndex())
const;
virtual QModelIndex parent (const QModelIndex& index) const;
void setRecord (const std::string& id, const RecordBase& record);
///< Add record or overwrite existing recrod.
// TODO: check if below methods are really needed
QVariant nestedHeaderData(int section, int subSection, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
NestedTableWrapperBase* nestedTable(const QModelIndex &index) const;
void setNestedTable(const QModelIndex &index, const NestedTableWrapperBase& nestedTable);
void addNestedRow (const QModelIndex& parent, int position);
virtual bool hasChildren (const QModelIndex& index) const;
signals:
void resetStart(const QString& id);
void resetEnd(const QString& id);
};
}
#endif

View File

@ -0,0 +1,44 @@
#include "nestablecolumn.hpp"
#include <stdexcept>
void CSMWorld::NestableColumn::addColumn(CSMWorld::NestableColumn *column)
{
mNestedColumns.push_back(column);
mHasChildren = true;
}
const CSMWorld::ColumnBase& CSMWorld::NestableColumn::nestedColumn(int subColumn) const
{
if (!mHasChildren)
throw std::logic_error("Tried to access nested column of the non-nest column");
return *mNestedColumns.at(subColumn);
}
int CSMWorld::NestableColumn::nestedColumnCount() const
{
if (!mHasChildren)
throw std::logic_error("Tried to access number of the subcolumns in the non-nest column");
return mNestedColumns.size();
}
CSMWorld::NestableColumn::NestableColumn(int columnId, CSMWorld::ColumnBase::Display displayType,
int flag, const CSMWorld::NestableColumn* parent)
: mParent(parent), mHasChildren(false), CSMWorld::ColumnBase(columnId, displayType, flag)
{
}
CSMWorld::NestableColumn::~NestableColumn()
{
for (unsigned int i = 0; i < mNestedColumns.size(); ++i)
{
delete mNestedColumns[i];
}
}
bool CSMWorld::NestableColumn::hasChildren() const
{
return mHasChildren;
}

View File

@ -0,0 +1,33 @@
#ifndef CSM_WOLRD_NESTABLECOLUMN_H
#define CSM_WOLRD_NESTABLECOLUMN_H
#include <vector>
#include "columnbase.hpp"
namespace CSMWorld
{
class NestableColumn : public ColumnBase
{
std::vector<NestableColumn *> mNestedColumns;
const NestableColumn* mParent;
bool mHasChildren; // cached
public:
NestableColumn(int columnId,
Display displayType, int flag, const NestableColumn* parent = 0);
~NestableColumn();
void addColumn(CSMWorld::NestableColumn *column);
const ColumnBase& nestedColumn(int subColumn) const;
int nestedColumnCount() const;
bool hasChildren() const;
};
}
#endif

View File

@ -1,6 +1,8 @@
#ifndef CSM_WOLRD_NESTEDCOLLECTION_H #ifndef CSM_WOLRD_NESTEDCOLLECTION_H
#define CSM_WOLRD_NESTEDCOLLECTION_H #define CSM_WOLRD_NESTEDCOLLECTION_H
#include <vector>
#include "collectionbase.hpp" #include "collectionbase.hpp"
class QVariant; class QVariant;
@ -11,7 +13,12 @@ namespace CSMWorld
class NestedCollection : public CollectionBase class NestedCollection : public CollectionBase
{ {
public: public:
NestedCollection();
virtual ~NestedCollection();
virtual void addNestedRow(int row, int col, int position) = 0; virtual void addNestedRow(int row, int col, int position) = 0;
virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const = 0; virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const = 0;
@ -28,7 +35,10 @@ namespace CSMWorld
virtual void removeNestedRows(int row, int column, int subRow) = 0; virtual void removeNestedRows(int row, int column, int subRow) = 0;
private:
std::vector<NestedCollection *> mChildren;
NestedCollection *mParent; // currently unused
}; };
} }

View File

@ -1,11 +1,11 @@
#include "nestedtableproxymodel.hpp" #include "nestedtableproxymodel.hpp"
#include <cassert> #include <cassert>
#include "idtable.hpp" #include "idtree.hpp"
CSMWorld::NestedTableProxyModel::NestedTableProxyModel(const QModelIndex& parent, CSMWorld::NestedTableProxyModel::NestedTableProxyModel(const QModelIndex& parent,
ColumnBase::Display columnId, ColumnBase::Display columnId,
CSMWorld::IdTable* parentModel) CSMWorld::IdTree* parentModel)
: mParentColumn(parent.column()), : mParentColumn(parent.column()),
mMainModel(parentModel) mMainModel(parentModel)
{ {
@ -119,7 +119,7 @@ int CSMWorld::NestedTableProxyModel::getParentColumn() const
return mParentColumn; return mParentColumn;
} }
CSMWorld::IdTable* CSMWorld::NestedTableProxyModel::model() const CSMWorld::IdTree* CSMWorld::NestedTableProxyModel::model() const
{ {
return mMainModel; return mMainModel;
} }

View File

@ -17,27 +17,27 @@ namespace CSMWorld
{ {
class CollectionBase; class CollectionBase;
class RecordBase; class RecordBase;
class IdTable; class IdTree;
class NestedTableProxyModel : public QAbstractProxyModel class NestedTableProxyModel : public QAbstractProxyModel
{ {
Q_OBJECT Q_OBJECT
const int mParentColumn; const int mParentColumn;
IdTable* mMainModel; IdTree* mMainModel;
std::string mId; std::string mId;
public: public:
NestedTableProxyModel(const QModelIndex& parent, NestedTableProxyModel(const QModelIndex& parent,
ColumnBase::Display displayType, ColumnBase::Display displayType,
IdTable* parentModel); IdTree* parentModel);
//parent is the parent of columns to work with. Columnid provides information about the column //parent is the parent of columns to work with. Columnid provides information about the column
std::string getParentId() const; std::string getParentId() const;
int getParentColumn() const; int getParentColumn() const;
CSMWorld::IdTable* model() const; CSMWorld::IdTree* model() const;
virtual QModelIndex mapFromSource(const QModelIndex& sourceIndex) const; virtual QModelIndex mapFromSource(const QModelIndex& sourceIndex) const;

View File

@ -2,18 +2,17 @@
#include <stdexcept> #include <stdexcept>
#include <memory> #include <memory>
#include <QDebug>
#include <components/esm/esmreader.hpp> #include <components/esm/esmreader.hpp>
#include "refidadapter.hpp" #include "refidadapter.hpp"
#include "refidadapterimp.hpp" #include "refidadapterimp.hpp"
#include "columns.hpp" #include "columns.hpp"
#include "nestedtablewrapper.hpp" #include "nestedtablewrapper.hpp" // FIXME: is this really necessary?
CSMWorld::RefIdColumn::RefIdColumn (int columnId, Display displayType, int flag, CSMWorld::RefIdColumn::RefIdColumn (int columnId, Display displayType, int flag,
bool editable, bool userEditable, bool canNest) bool editable, bool userEditable)
: NestColumn (columnId, displayType, flag, canNest), mEditable (editable), mUserEditable (userEditable) : NestableColumn (columnId, displayType, flag), mEditable (editable), mUserEditable (userEditable)
{} {}
bool CSMWorld::RefIdColumn::isEditable() const bool CSMWorld::RefIdColumn::isEditable() const
@ -27,7 +26,8 @@ bool CSMWorld::RefIdColumn::isUserEditable() const
} }
CSMWorld::RefIdAdapter& CSMWorld::RefIdCollection::findAdapter (UniversalId::Type type) const // FIXME: const problem
/*const*/ CSMWorld::RefIdAdapter& CSMWorld::RefIdCollection::findAdapter (UniversalId::Type type) const
{ {
std::map<UniversalId::Type, RefIdAdapter *>::const_iterator iter = mAdapters.find (type); std::map<UniversalId::Type, RefIdAdapter *>::const_iterator iter = mAdapters.find (type);
@ -99,14 +99,19 @@ CSMWorld::RefIdCollection::RefIdCollection()
mColumns.push_back (RefIdColumn (Columns::ColumnId_AiAlarm, ColumnBase::Display_Integer)); mColumns.push_back (RefIdColumn (Columns::ColumnId_AiAlarm, ColumnBase::Display_Integer));
actorsColumns.mAlarm = &mColumns.back(); actorsColumns.mAlarm = &mColumns.back();
mColumns.push_back(RefIdColumn (Columns::ColumnId_ActorInventory, ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue, true, true, true)); // Nested table
mColumns.push_back(RefIdColumn (Columns::ColumnId_ActorInventory, ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue));
actorsColumns.mInventory = &mColumns.back(); actorsColumns.mInventory = &mColumns.back();
mColumns.back().addNestedColumn(Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String); mColumns.back().addColumn(
mColumns.back().addNestedColumn(Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer); new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer));
mColumns.push_back(RefIdColumn (Columns::ColumnId_ActorSpells, ColumnBase::Display_NestedSpellList, ColumnBase::Flag_Dialogue, true, true, true)); // Nested table
mColumns.push_back(RefIdColumn (Columns::ColumnId_ActorSpells, ColumnBase::Display_NestedSpellList, ColumnBase::Flag_Dialogue));
actorsColumns.mSpells = &mColumns.back(); actorsColumns.mSpells = &mColumns.back();
mColumns.back().addNestedColumn(Columns::ColumnId_SpellId, CSMWorld::ColumnBase::Display_String); mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_SpellId, CSMWorld::ColumnBase::Display_String));
static const struct static const struct
{ {
@ -175,10 +180,13 @@ CSMWorld::RefIdCollection::RefIdCollection()
mColumns.push_back (RefIdColumn (Columns::ColumnId_Respawn, ColumnBase::Display_Boolean)); mColumns.push_back (RefIdColumn (Columns::ColumnId_Respawn, ColumnBase::Display_Boolean));
const RefIdColumn *respawn = &mColumns.back(); const RefIdColumn *respawn = &mColumns.back();
mColumns.push_back(RefIdColumn (Columns::ColumnId_ContainerContent, ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue, true, true, true)); // Nested table
mColumns.push_back(RefIdColumn (Columns::ColumnId_ContainerContent, ColumnBase::Display_NestedItemList, ColumnBase::Flag_Dialogue));
const RefIdColumn *content = &mColumns.back(); const RefIdColumn *content = &mColumns.back();
mColumns.back().addNestedColumn(Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String); mColumns.back().addColumn(
mColumns.back().addNestedColumn(Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer); new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer));
CreatureColumns creatureColumns (actorsColumns); CreatureColumns creatureColumns (actorsColumns);
@ -315,16 +323,24 @@ CSMWorld::RefIdCollection::RefIdCollection()
npcColumns.mFlags.insert (std::make_pair (metalBlood, ESM::NPC::Metal)); npcColumns.mFlags.insert (std::make_pair (metalBlood, ESM::NPC::Metal));
mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcDestinations, ColumnBase::Display_NestedDestinationsList, ColumnBase::Flag_Dialogue, true, true, true)); // Nested table
mColumns.push_back(RefIdColumn (Columns::ColumnId_NpcDestinations, ColumnBase::Display_NestedDestinationsList, ColumnBase::Flag_Dialogue));
npcColumns.mDestinations = &mColumns.back(); npcColumns.mDestinations = &mColumns.back();
mColumns.back().addNestedColumn(Columns::ColumnId_DestinationCell, CSMWorld::ColumnBase::Display_String); mColumns.back().addColumn(
mColumns.back().addNestedColumn(Columns::ColumnId_PosX, CSMWorld::ColumnBase::Display_Float); new RefIdColumn (Columns::ColumnId_DestinationCell, CSMWorld::ColumnBase::Display_String));
mColumns.back().addNestedColumn(Columns::ColumnId_PosY, CSMWorld::ColumnBase::Display_Float); mColumns.back().addColumn(
mColumns.back().addNestedColumn(Columns::ColumnId_PosZ, CSMWorld::ColumnBase::Display_Float); new RefIdColumn (Columns::ColumnId_PosX, CSMWorld::ColumnBase::Display_Float));
mColumns.back().addNestedColumn(Columns::ColumnId_RotX, CSMWorld::ColumnBase::Display_Float); mColumns.back().addColumn(
mColumns.back().addNestedColumn(Columns::ColumnId_RotY, CSMWorld::ColumnBase::Display_Float); new RefIdColumn (Columns::ColumnId_PosY, CSMWorld::ColumnBase::Display_Float));
mColumns.back().addNestedColumn(Columns::ColumnId_RotZ, CSMWorld::ColumnBase::Display_Float); mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_PosZ, CSMWorld::ColumnBase::Display_Float));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_RotX, CSMWorld::ColumnBase::Display_Float));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_RotY, CSMWorld::ColumnBase::Display_Float));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_RotZ, CSMWorld::ColumnBase::Display_Float));
WeaponColumns weaponColumns (enchantableColumns); WeaponColumns weaponColumns (enchantableColumns);
mColumns.push_back (RefIdColumn (Columns::ColumnId_WeaponType, ColumnBase::Display_WeaponType)); mColumns.push_back (RefIdColumn (Columns::ColumnId_WeaponType, ColumnBase::Display_WeaponType));
@ -664,8 +680,10 @@ void CSMWorld::RefIdCollection::setNestedTable(int row, int column, const CSMWor
{ {
RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row);
// FIXME: const problem
CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast<CSMWorld::NestedRefIdAdapter&>(findAdapter (localIndex.second)); CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast<CSMWorld::NestedRefIdAdapter&>(findAdapter (localIndex.second));
// FIXME: const problem
adaptor.setNestedTable(&mColumns.at(column), mData, localIndex.first, nestedTable); adaptor.setNestedTable(&mColumns.at(column), mData, localIndex.first, nestedTable);
} }

View File

@ -5,8 +5,7 @@
#include <map> #include <map>
#include <deque> #include <deque>
#include "columnbase.hpp" #include "nestablecolumn.hpp"
#include "collectionbase.hpp"
#include "nestedcollection.hpp" #include "nestedcollection.hpp"
#include "refiddata.hpp" #include "refiddata.hpp"
@ -18,9 +17,9 @@ namespace ESM
namespace CSMWorld namespace CSMWorld
{ {
class RefIdAdapter; class RefIdAdapter;
class NestedTableWrapperBase; class NestedTableWrapperBase; // FIXME: is this really needed?
class RefIdColumn : public NestColumn class RefIdColumn : public NestableColumn
{ {
bool mEditable; bool mEditable;
bool mUserEditable; bool mUserEditable;
@ -29,7 +28,7 @@ namespace CSMWorld
RefIdColumn (int columnId, Display displayType, RefIdColumn (int columnId, Display displayType,
int flag = Flag_Table | Flag_Dialogue, bool editable = true, int flag = Flag_Table | Flag_Dialogue, bool editable = true,
bool userEditable = true, bool canNest = false); bool userEditable = true);
virtual bool isEditable() const; virtual bool isEditable() const;
@ -46,7 +45,7 @@ namespace CSMWorld
private: private:
RefIdAdapter& findAdapter (UniversalId::Type) const; /*const*/ RefIdAdapter& findAdapter (UniversalId::Type) const;
///< Throws an exception if no adaptor for \a Type can be found. ///< Throws an exception if no adaptor for \a Type can be found.
public: public:
@ -57,10 +56,6 @@ namespace CSMWorld
virtual int getSize() const; virtual int getSize() const;
virtual int getNestedRowsCount(int row, int column) const;
virtual int getNestedColumnsCount(int row, int column) const;
virtual std::string getId (int index) const; virtual std::string getId (int index) const;
virtual int getIndex (const std::string& id) const; virtual int getIndex (const std::string& id) const;
@ -71,22 +66,10 @@ namespace CSMWorld
virtual QVariant getData (int index, int column) const; virtual QVariant getData (int index, int column) const;
virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const;
virtual NestedTableWrapperBase* nestedTable(int row, int column) const;
virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable);
virtual void setData (int index, int column, const QVariant& data); virtual void setData (int index, int column, const QVariant& data);
virtual void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn);
virtual void removeRows (int index, int count); virtual void removeRows (int index, int count);
virtual void removeNestedRows(int row, int column, int subRow);
virtual void addNestedRow(int row, int col, int position);
virtual void cloneRecord(const std::string& origin, virtual void cloneRecord(const std::string& origin,
const std::string& destination, const std::string& destination,
const UniversalId::Type type); const UniversalId::Type type);
@ -128,6 +111,24 @@ namespace CSMWorld
/// ///
/// \return Success? /// \return Success?
virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const;
virtual NestedTableWrapperBase* nestedTable(int row, int column) const;
virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable);
// FIXME
virtual int getNestedRowsCount(int row, int column) const;
// FIXME
virtual int getNestedColumnsCount(int row, int column) const;
virtual void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn);
virtual void removeNestedRows(int row, int column, int subRow);
virtual void addNestedRow(int row, int col, int position);
void save (int index, ESM::ESMWriter& writer) const; void save (int index, ESM::ESMWriter& writer) const;
const RefIdData& getDataSet() const; //I can't figure out a better name for this one :( const RefIdData& getDataSet() const; //I can't figure out a better name for this one :(

View File

@ -52,7 +52,7 @@ namespace CSMWorld
virtual void load (int index, ESM::ESMReader& reader, bool base) = 0; virtual void load (int index, ESM::ESMReader& reader, bool base) = 0;
virtual void erase (int index, int count) = 0; virtual void erase (int index, int count) = 0;
virtual std::string getId (int index) const = 0; virtual std::string getId (int index) const = 0;
virtual void save (int index, ESM::ESMWriter& writer) const = 0; virtual void save (int index, ESM::ESMWriter& writer) const = 0;
@ -134,7 +134,7 @@ namespace CSMWorld
throw std::runtime_error ("invalid RefIdDataContainer index"); throw std::runtime_error ("invalid RefIdDataContainer index");
mContainer.erase (mContainer.begin()+index, mContainer.begin()+index+count); mContainer.erase (mContainer.begin()+index, mContainer.begin()+index+count);
} }
template<typename RecordT> template<typename RecordT>
std::string RefIdDataContainer<RecordT>::getId (int index) const std::string RefIdDataContainer<RecordT>::getId (int index) const
@ -231,7 +231,7 @@ namespace CSMWorld
void save (int index, ESM::ESMWriter& writer) const; void save (int index, ESM::ESMWriter& writer) const;
//RECORD CONTAINERS ACCESS METHODS //RECORD CONTAINERS ACCESS METHODS
const RefIdDataContainer<ESM::Book>& getBooks() const; const RefIdDataContainer<ESM::Book>& getBooks() const;
const RefIdDataContainer<ESM::Activator>& getActivators() const; const RefIdDataContainer<ESM::Activator>& getActivators() const;
const RefIdDataContainer<ESM::Potion>& getPotions() const; const RefIdDataContainer<ESM::Potion>& getPotions() const;

View File

@ -26,6 +26,7 @@
#include "../../model/world/nestedtableproxymodel.hpp" #include "../../model/world/nestedtableproxymodel.hpp"
#include "../../model/world/columnbase.hpp" #include "../../model/world/columnbase.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/record.hpp" #include "../../model/world/record.hpp"
#include "../../model/world/tablemimedata.hpp" #include "../../model/world/tablemimedata.hpp"
@ -422,7 +423,7 @@ void CSVWorld::EditWidget::remake(int row)
if (mTable->hasChildren(mTable->index(row, i))) if (mTable->hasChildren(mTable->index(row, i)))
{ {
mNestedModels.push_back(new CSMWorld::NestedTableProxyModel (mTable->index(row, i), display, mTable)); mNestedModels.push_back(new CSMWorld::NestedTableProxyModel (mTable->index(row, i), display, dynamic_cast<CSMWorld::IdTree*>(mTable)));
NestedTable* table = new NestedTable(mDocument, mNestedModels.back(), this); NestedTable* table = new NestedTable(mDocument, mNestedModels.back(), this);