mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-25 06:35:30 +00:00
Reorganised class inheritance structure of collections, columns and idtable model.
This commit is contained in:
parent
ece34a1baa
commit
83bcc8d451
@ -18,15 +18,14 @@ opencs_hdrs_noqt (model/doc
|
||||
|
||||
|
||||
opencs_units (model/world
|
||||
idtable idtableproxymodel regionmap data commanddispatcher
|
||||
idtablebase resourcetable nestedtableproxymodel
|
||||
idtable idtableproxymodel regionmap data commanddispatcher idtablebase resourcetable nestedtableproxymodel idtree
|
||||
)
|
||||
|
||||
|
||||
opencs_units_noqt (model/world
|
||||
universalid record commands columnbase scriptcontext cell refidcollection
|
||||
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
|
||||
|
@ -1,9 +1,10 @@
|
||||
|
||||
#include "columnbase.hpp"
|
||||
|
||||
#include "columns.hpp"
|
||||
|
||||
CSMWorld::ColumnBase::ColumnBase (int columnId, Display displayType, int flags, bool canNest)
|
||||
: mColumnId (columnId), mDisplayType (displayType), mFlags (flags), mCanNest(canNest)
|
||||
CSMWorld::ColumnBase::ColumnBase (int columnId, Display displayType, int flags)
|
||||
: mColumnId (columnId), mDisplayType (displayType), mFlags (flags)
|
||||
{}
|
||||
|
||||
CSMWorld::ColumnBase::~ColumnBase() {}
|
||||
@ -22,43 +23,3 @@ int CSMWorld::ColumnBase::getId() const
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <Qt>
|
||||
#include <QVariant>
|
||||
@ -117,9 +117,8 @@ namespace CSMWorld
|
||||
int mColumnId;
|
||||
int mFlags;
|
||||
Display mDisplayType;
|
||||
bool mCanNest;
|
||||
|
||||
ColumnBase (int columnId, Display displayType, int flag, bool canNest = false);
|
||||
ColumnBase (int columnId, Display displayType, int flag);
|
||||
|
||||
virtual ~ColumnBase();
|
||||
|
||||
@ -133,39 +132,11 @@ namespace CSMWorld
|
||||
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>
|
||||
struct Column : public NestColumn
|
||||
struct Column : public ColumnBase
|
||||
{
|
||||
Column (int columnId, Display displayType, int flags = Flag_Table | Flag_Dialogue, bool canNest = false)
|
||||
: NestColumn (columnId, displayType, flags, canNest) {}
|
||||
Column (int columnId, Display displayType, int flags = Flag_Table | Flag_Dialogue)
|
||||
: ColumnBase (columnId, displayType, flags) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const = 0;
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
#include "idtable.hpp"
|
||||
#include "idtree.hpp"
|
||||
#include <components/misc/stringops.hpp>
|
||||
#include "nestedtablewrapper.hpp"
|
||||
|
||||
@ -172,10 +173,10 @@ void CSMWorld::CloneCommand::undo()
|
||||
mModel.removeRow (mModel.getModelIndex (mId, 0).row());
|
||||
}
|
||||
|
||||
CSMWorld::DeleteNestedCommand::DeleteNestedCommand (IdTable& model,
|
||||
CSMWorld::DeleteNestedCommand::DeleteNestedCommand (IdTree& model,
|
||||
const std::string& id,
|
||||
int nestedRow,
|
||||
int parentColumn,
|
||||
int nestedRow,
|
||||
int parentColumn,
|
||||
QUndoCommand* parent) :
|
||||
mId(id),
|
||||
mModel(model),
|
||||
@ -192,7 +193,7 @@ void CSMWorld::DeleteNestedCommand::redo()
|
||||
const QModelIndex& parentIndex = mModel.getModelIndex(mId, mParentColumn);
|
||||
|
||||
mModel.removeRows (mNestedRow, 1, parentIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CSMWorld::DeleteNestedCommand::undo()
|
||||
@ -202,7 +203,7 @@ void CSMWorld::DeleteNestedCommand::undo()
|
||||
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),
|
||||
mId(id),
|
||||
mNewRow(nestedRow),
|
||||
@ -227,7 +228,7 @@ void CSMWorld::AddNestedCommand::undo()
|
||||
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))) {}
|
||||
|
||||
CSMWorld::NestedTableStoring::~NestedTableStoring()
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include <QVariant>
|
||||
#include <QUndoCommand>
|
||||
#include <QModelIndex>
|
||||
#include <QVariant>
|
||||
|
||||
#include "universalid.hpp"
|
||||
#include "nestedtablewrapper.hpp"
|
||||
@ -21,7 +20,7 @@ class QAbstractItemModel;
|
||||
namespace CSMWorld
|
||||
{
|
||||
class IdTable;
|
||||
class IdTable;
|
||||
class IdTree;
|
||||
struct RecordBase;
|
||||
class NestedTableWrapperBase;
|
||||
|
||||
@ -148,18 +147,18 @@ namespace CSMWorld
|
||||
NestedTableWrapperBase* mOld;
|
||||
|
||||
public:
|
||||
NestedTableStoring(const IdTable& model, const std::string& id, int parentColumn);
|
||||
|
||||
NestedTableStoring(const IdTree& model, const std::string& id, int parentColumn);
|
||||
|
||||
~NestedTableStoring();
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
const NestedTableWrapperBase& getOld() const;
|
||||
};
|
||||
|
||||
|
||||
class DeleteNestedCommand : public QUndoCommand, private NestedTableStoring
|
||||
{
|
||||
IdTable& mModel;
|
||||
IdTree& mModel;
|
||||
|
||||
std::string mId;
|
||||
|
||||
@ -169,16 +168,16 @@ namespace CSMWorld
|
||||
|
||||
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 undo();
|
||||
};
|
||||
|
||||
|
||||
class AddNestedCommand : public QUndoCommand, private NestedTableStoring
|
||||
{
|
||||
IdTable& mModel;
|
||||
IdTree& mModel;
|
||||
|
||||
std::string mId;
|
||||
|
||||
@ -188,7 +187,7 @@ namespace CSMWorld
|
||||
|
||||
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();
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <components/esm/cellref.hpp>
|
||||
|
||||
#include "idtable.hpp"
|
||||
#include "idtree.hpp"
|
||||
#include "columnimp.hpp"
|
||||
#include "regionmap.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 (&mPathgrids), UniversalId::Type_Pathgrid);
|
||||
addModel (new IdTable (&mStartScripts), UniversalId::Type_StartScript);
|
||||
addModel (new IdTable (&mReferenceables, IdTable::Feature_Preview),
|
||||
addModel (new IdTree (&mReferenceables, IdTable::Feature_Preview),
|
||||
UniversalId::Type_Referenceable);
|
||||
addModel (new IdTable (&mRefs, IdTable::Feature_ViewCell | IdTable::Feature_Preview), UniversalId::Type_Reference);
|
||||
addModel (new IdTable (&mFilters), UniversalId::Type_Filter);
|
||||
|
@ -1,12 +1,6 @@
|
||||
#include "idtable.hpp"
|
||||
#include <QDebug>
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include "nestedtablewrapper.hpp"
|
||||
|
||||
#include "collectionbase.hpp"
|
||||
#include "nestedcollection.hpp"
|
||||
#include "columnbase.hpp"
|
||||
|
||||
CSMWorld::IdTable::IdTable (CollectionBase *idCollection, unsigned int features)
|
||||
@ -14,26 +8,20 @@ CSMWorld::IdTable::IdTable (CollectionBase *idCollection, unsigned int features)
|
||||
{}
|
||||
|
||||
CSMWorld::IdTable::~IdTable()
|
||||
{
|
||||
mIdCollection = 0; // FIXME: workaround only, should stop QHideEvent calling after destruction
|
||||
}
|
||||
{}
|
||||
|
||||
int CSMWorld::IdTable::rowCount (const QModelIndex & parent) const
|
||||
{
|
||||
if (hasChildren(parent))
|
||||
{
|
||||
return dynamic_cast<NestedCollection*>(mIdCollection)->getNestedRowsCount(parent.row(), parent.column());
|
||||
}
|
||||
if (parent.isValid())
|
||||
return 0;
|
||||
|
||||
return mIdCollection->getSize();
|
||||
}
|
||||
|
||||
int CSMWorld::IdTable::columnCount (const QModelIndex & parent) const
|
||||
{
|
||||
if (hasChildren(parent))
|
||||
{
|
||||
return dynamic_cast<NestedCollection*>(mIdCollection)->getNestedColumnsCount(parent.row(), parent.column());
|
||||
}
|
||||
if (parent.isValid())
|
||||
return 0;
|
||||
|
||||
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())
|
||||
return QVariant();
|
||||
|
||||
if (index.internalId() != 0)
|
||||
{
|
||||
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());
|
||||
}
|
||||
return mIdCollection->getData (index.row(), index.column());
|
||||
}
|
||||
|
||||
QVariant CSMWorld::IdTable::headerData (int section,
|
||||
Qt::Orientation orientation,
|
||||
int role) const
|
||||
QVariant CSMWorld::IdTable::headerData (int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (orientation==Qt::Vertical)
|
||||
return QVariant();
|
||||
@ -74,63 +49,19 @@ QVariant CSMWorld::IdTable::headerData (int section,
|
||||
return mIdCollection->getColumn (section).mFlags;
|
||||
|
||||
if (role==ColumnBase::Role_Display)
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
mIdCollection->setData (index.row(), index.column(), value);
|
||||
|
||||
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;
|
||||
}
|
||||
@ -150,56 +81,22 @@ Qt::ItemFlags CSMWorld::IdTable::flags (const QModelIndex & index) const
|
||||
|
||||
bool CSMWorld::IdTable::removeRows (int row, int count, const QModelIndex& parent)
|
||||
{
|
||||
if (parent.isValid())
|
||||
return false;
|
||||
|
||||
beginRemoveRows (parent, row, row+count-1);
|
||||
|
||||
if (parent.isValid())
|
||||
{
|
||||
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);
|
||||
}
|
||||
mIdCollection->removeRows (row, count);
|
||||
|
||||
endRemoveRows();
|
||||
|
||||
emit dataChanged (CSMWorld::IdTable::index (parent.row(), 0),
|
||||
CSMWorld::IdTable::index (parent.row(), mIdCollection->getColumns()-1));
|
||||
|
||||
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
|
||||
{
|
||||
unsigned int encodedId = 0;
|
||||
if (parent.isValid())
|
||||
{
|
||||
encodedId = this->foldIndexAdress(parent);
|
||||
}
|
||||
return QModelIndex();
|
||||
|
||||
if (row<0 || row>=mIdCollection->getSize())
|
||||
return QModelIndex();
|
||||
@ -207,24 +104,12 @@ QModelIndex CSMWorld::IdTable::index (int row, int column, const QModelIndex& pa
|
||||
if (column<0 || column>=mIdCollection->getColumns())
|
||||
return QModelIndex();
|
||||
|
||||
return createIndex(row, column, encodedId);
|
||||
return createIndex (row, column);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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);
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
@ -7,20 +7,10 @@
|
||||
#include "universalid.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
|
||||
{
|
||||
class CollectionBase;
|
||||
struct RecordBase;
|
||||
class NestedTableWrapperBase;
|
||||
|
||||
class IdTable : public IdTableBase
|
||||
{
|
||||
@ -33,8 +23,6 @@ namespace CSMWorld
|
||||
// not implemented
|
||||
IdTable (const IdTable&);
|
||||
IdTable& operator= (const IdTable&);
|
||||
unsigned int foldIndexAdress(const QModelIndex& index) const;
|
||||
std::pair<int, int> unfoldIndexAdress(unsigned int id) const;
|
||||
|
||||
public:
|
||||
|
||||
@ -51,27 +39,17 @@ namespace CSMWorld
|
||||
|
||||
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 Qt::ItemFlags flags (const QModelIndex & index) const;
|
||||
|
||||
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())
|
||||
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);
|
||||
///< \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;
|
||||
|
||||
int getColumnId(int column) const;
|
||||
|
||||
signals:
|
||||
void resetStart(const QString& id);
|
||||
|
||||
void resetEnd(const QString& id);
|
||||
};
|
||||
}
|
||||
|
||||
|
296
apps/opencs/model/world/idtree.cpp
Normal file
296
apps/opencs/model/world/idtree.cpp
Normal 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());
|
||||
}
|
88
apps/opencs/model/world/idtree.hpp
Normal file
88
apps/opencs/model/world/idtree.hpp
Normal 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
|
44
apps/opencs/model/world/nestablecolumn.cpp
Normal file
44
apps/opencs/model/world/nestablecolumn.cpp
Normal 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;
|
||||
}
|
33
apps/opencs/model/world/nestablecolumn.hpp
Normal file
33
apps/opencs/model/world/nestablecolumn.hpp
Normal 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
|
@ -1,6 +1,8 @@
|
||||
#ifndef CSM_WOLRD_NESTEDCOLLECTION_H
|
||||
#define CSM_WOLRD_NESTEDCOLLECTION_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "collectionbase.hpp"
|
||||
|
||||
class QVariant;
|
||||
@ -11,7 +13,12 @@ namespace CSMWorld
|
||||
|
||||
class NestedCollection : public CollectionBase
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
NestedCollection();
|
||||
virtual ~NestedCollection();
|
||||
|
||||
virtual void addNestedRow(int row, int col, int position) = 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;
|
||||
|
||||
private:
|
||||
|
||||
std::vector<NestedCollection *> mChildren;
|
||||
NestedCollection *mParent; // currently unused
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
#include "nestedtableproxymodel.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include "idtable.hpp"
|
||||
#include "idtree.hpp"
|
||||
|
||||
CSMWorld::NestedTableProxyModel::NestedTableProxyModel(const QModelIndex& parent,
|
||||
ColumnBase::Display columnId,
|
||||
CSMWorld::IdTable* parentModel)
|
||||
CSMWorld::IdTree* parentModel)
|
||||
: mParentColumn(parent.column()),
|
||||
mMainModel(parentModel)
|
||||
{
|
||||
@ -119,7 +119,7 @@ int CSMWorld::NestedTableProxyModel::getParentColumn() const
|
||||
return mParentColumn;
|
||||
}
|
||||
|
||||
CSMWorld::IdTable* CSMWorld::NestedTableProxyModel::model() const
|
||||
CSMWorld::IdTree* CSMWorld::NestedTableProxyModel::model() const
|
||||
{
|
||||
return mMainModel;
|
||||
}
|
||||
|
@ -17,27 +17,27 @@ namespace CSMWorld
|
||||
{
|
||||
class CollectionBase;
|
||||
class RecordBase;
|
||||
class IdTable;
|
||||
class IdTree;
|
||||
|
||||
class NestedTableProxyModel : public QAbstractProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
const int mParentColumn;
|
||||
IdTable* mMainModel;
|
||||
IdTree* mMainModel;
|
||||
std::string mId;
|
||||
|
||||
public:
|
||||
NestedTableProxyModel(const QModelIndex& parent,
|
||||
ColumnBase::Display displayType,
|
||||
IdTable* parentModel);
|
||||
IdTree* parentModel);
|
||||
//parent is the parent of columns to work with. Columnid provides information about the column
|
||||
|
||||
std::string getParentId() const;
|
||||
|
||||
int getParentColumn() const;
|
||||
|
||||
CSMWorld::IdTable* model() const;
|
||||
CSMWorld::IdTree* model() const;
|
||||
|
||||
virtual QModelIndex mapFromSource(const QModelIndex& sourceIndex) const;
|
||||
|
||||
|
@ -2,18 +2,17 @@
|
||||
|
||||
#include <stdexcept>
|
||||
#include <memory>
|
||||
#include <QDebug>
|
||||
|
||||
#include <components/esm/esmreader.hpp>
|
||||
|
||||
#include "refidadapter.hpp"
|
||||
#include "refidadapterimp.hpp"
|
||||
#include "columns.hpp"
|
||||
#include "nestedtablewrapper.hpp"
|
||||
#include "nestedtablewrapper.hpp" // FIXME: is this really necessary?
|
||||
|
||||
CSMWorld::RefIdColumn::RefIdColumn (int columnId, Display displayType, int flag,
|
||||
bool editable, bool userEditable, bool canNest)
|
||||
: NestColumn (columnId, displayType, flag, canNest), mEditable (editable), mUserEditable (userEditable)
|
||||
bool editable, bool userEditable)
|
||||
: NestableColumn (columnId, displayType, flag), mEditable (editable), mUserEditable (userEditable)
|
||||
{}
|
||||
|
||||
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);
|
||||
|
||||
@ -99,14 +99,19 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_AiAlarm, ColumnBase::Display_Integer));
|
||||
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();
|
||||
mColumns.back().addNestedColumn(Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String);
|
||||
mColumns.back().addNestedColumn(Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer);
|
||||
mColumns.back().addColumn(
|
||||
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();
|
||||
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
|
||||
{
|
||||
@ -175,10 +180,13 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
||||
mColumns.push_back (RefIdColumn (Columns::ColumnId_Respawn, ColumnBase::Display_Boolean));
|
||||
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();
|
||||
mColumns.back().addNestedColumn(Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String);
|
||||
mColumns.back().addNestedColumn(Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer);
|
||||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_String));
|
||||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer));
|
||||
|
||||
CreatureColumns creatureColumns (actorsColumns);
|
||||
|
||||
@ -315,16 +323,24 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
||||
|
||||
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();
|
||||
mColumns.back().addNestedColumn(Columns::ColumnId_DestinationCell, CSMWorld::ColumnBase::Display_String);
|
||||
mColumns.back().addNestedColumn(Columns::ColumnId_PosX, CSMWorld::ColumnBase::Display_Float);
|
||||
mColumns.back().addNestedColumn(Columns::ColumnId_PosY, CSMWorld::ColumnBase::Display_Float);
|
||||
mColumns.back().addNestedColumn(Columns::ColumnId_PosZ, CSMWorld::ColumnBase::Display_Float);
|
||||
mColumns.back().addNestedColumn(Columns::ColumnId_RotX, CSMWorld::ColumnBase::Display_Float);
|
||||
mColumns.back().addNestedColumn(Columns::ColumnId_RotY, CSMWorld::ColumnBase::Display_Float);
|
||||
mColumns.back().addNestedColumn(Columns::ColumnId_RotZ, CSMWorld::ColumnBase::Display_Float);
|
||||
|
||||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_DestinationCell, CSMWorld::ColumnBase::Display_String));
|
||||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_PosX, CSMWorld::ColumnBase::Display_Float));
|
||||
mColumns.back().addColumn(
|
||||
new RefIdColumn (Columns::ColumnId_PosY, 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);
|
||||
|
||||
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);
|
||||
|
||||
// FIXME: const problem
|
||||
CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast<CSMWorld::NestedRefIdAdapter&>(findAdapter (localIndex.second));
|
||||
|
||||
// FIXME: const problem
|
||||
adaptor.setNestedTable(&mColumns.at(column), mData, localIndex.first, nestedTable);
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,7 @@
|
||||
#include <map>
|
||||
#include <deque>
|
||||
|
||||
#include "columnbase.hpp"
|
||||
#include "collectionbase.hpp"
|
||||
#include "nestablecolumn.hpp"
|
||||
#include "nestedcollection.hpp"
|
||||
#include "refiddata.hpp"
|
||||
|
||||
@ -18,9 +17,9 @@ namespace ESM
|
||||
namespace CSMWorld
|
||||
{
|
||||
class RefIdAdapter;
|
||||
class NestedTableWrapperBase;
|
||||
class NestedTableWrapperBase; // FIXME: is this really needed?
|
||||
|
||||
class RefIdColumn : public NestColumn
|
||||
class RefIdColumn : public NestableColumn
|
||||
{
|
||||
bool mEditable;
|
||||
bool mUserEditable;
|
||||
@ -29,7 +28,7 @@ namespace CSMWorld
|
||||
|
||||
RefIdColumn (int columnId, Display displayType,
|
||||
int flag = Flag_Table | Flag_Dialogue, bool editable = true,
|
||||
bool userEditable = true, bool canNest = false);
|
||||
bool userEditable = true);
|
||||
|
||||
virtual bool isEditable() const;
|
||||
|
||||
@ -46,7 +45,7 @@ namespace CSMWorld
|
||||
|
||||
private:
|
||||
|
||||
RefIdAdapter& findAdapter (UniversalId::Type) const;
|
||||
/*const*/ RefIdAdapter& findAdapter (UniversalId::Type) const;
|
||||
///< Throws an exception if no adaptor for \a Type can be found.
|
||||
|
||||
public:
|
||||
@ -57,10 +56,6 @@ namespace CSMWorld
|
||||
|
||||
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 int getIndex (const std::string& id) const;
|
||||
@ -71,22 +66,10 @@ namespace CSMWorld
|
||||
|
||||
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 setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn);
|
||||
|
||||
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,
|
||||
const std::string& destination,
|
||||
const UniversalId::Type type);
|
||||
@ -128,6 +111,24 @@ namespace CSMWorld
|
||||
///
|
||||
/// \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;
|
||||
|
||||
const RefIdData& getDataSet() const; //I can't figure out a better name for this one :(
|
||||
|
@ -52,7 +52,7 @@ namespace CSMWorld
|
||||
virtual void load (int index, ESM::ESMReader& reader, bool base) = 0;
|
||||
|
||||
virtual void erase (int index, int count) = 0;
|
||||
|
||||
|
||||
virtual std::string getId (int index) 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");
|
||||
|
||||
mContainer.erase (mContainer.begin()+index, mContainer.begin()+index+count);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename RecordT>
|
||||
std::string RefIdDataContainer<RecordT>::getId (int index) const
|
||||
@ -231,7 +231,7 @@ namespace CSMWorld
|
||||
|
||||
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::Activator>& getActivators() const;
|
||||
const RefIdDataContainer<ESM::Potion>& getPotions() const;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "../../model/world/nestedtableproxymodel.hpp"
|
||||
#include "../../model/world/columnbase.hpp"
|
||||
#include "../../model/world/idtable.hpp"
|
||||
#include "../../model/world/idtree.hpp"
|
||||
#include "../../model/world/columns.hpp"
|
||||
#include "../../model/world/record.hpp"
|
||||
#include "../../model/world/tablemimedata.hpp"
|
||||
@ -422,7 +423,7 @@ void CSVWorld::EditWidget::remake(int row)
|
||||
|
||||
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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user