Re-organise the inheritance structure once more in preparation for adding Pathgrid tables.

test
cc9cii 10 years ago
parent 745eae9c10
commit bdf0d8db22

@ -25,7 +25,7 @@ opencs_units (model/world
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 nestedcollection nestablecolumn
pathgrid landtexture land nestedtablewrapper nestedadapters nestedcollection
)
opencs_hdrs_noqt (model/world

@ -148,6 +148,8 @@ namespace CSMWorld
void setRecord (int index, const Record<ESXRecordT>& record);
///< \attention This function must not change the ID.
NestableColumn *getNestableColumn (int column);
};
template<typename ESXRecordT, typename IdAccessorT>
@ -289,6 +291,15 @@ namespace CSMWorld
return *mColumns.at (column);
}
template<typename ESXRecordT, typename IdAccessorT>
NestableColumn *Collection<ESXRecordT, IdAccessorT>::getNestableColumn (int column)
{
if (column < 0 || column >= static_cast<int>(mColumns.size()))
throw std::runtime_error("column index out of range");
return mColumns.at (column);
}
template<typename ESXRecordT, typename IdAccessorT>
void Collection<ESXRecordT, IdAccessorT>::addColumn (Column<ESXRecordT> *column)
{

@ -23,3 +23,36 @@ int CSMWorld::ColumnBase::getId() const
{
return mColumnId;
}
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);
}
CSMWorld::NestableColumn::NestableColumn(int columnId, CSMWorld::ColumnBase::Display displayType,
int flag)
: 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;
}

@ -129,14 +129,32 @@ namespace CSMWorld
virtual std::string getTitle() const;
virtual int getId() const;
virtual int getId() const; // FIXME: why have an accessor for a public member?
};
class NestableColumn : public ColumnBase
{
std::vector<NestableColumn *> mNestedColumns;
bool mHasChildren;
public:
NestableColumn(int columnId, Display displayType, int flag);
~NestableColumn();
void addColumn(CSMWorld::NestableColumn *column);
const ColumnBase& nestedColumn(int subColumn) const;
bool hasChildren() const;
};
template<typename ESXRecordT>
struct Column : public ColumnBase
struct Column : public NestableColumn
{
Column (int columnId, Display displayType, int flags = Flag_Table | Flag_Dialogue)
: ColumnBase (columnId, displayType, flags) {}
: NestableColumn (columnId, displayType, flags) {}
virtual QVariant get (const Record<ESXRecordT>& record) const = 0;

@ -333,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 IdTree (&mReferenceables, IdTable::Feature_Preview),
addModel (new IdTree (&mReferenceables, &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,5 +1,7 @@
#include "idtable.hpp"
#include <stdexcept>
#include "collectionbase.hpp"
#include "columnbase.hpp"
@ -42,6 +44,9 @@ QVariant CSMWorld::IdTable::headerData (int section, Qt::Orientation orientation
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());
@ -231,3 +236,8 @@ int CSMWorld::IdTable::getColumnId(int column) const
{
return mIdCollection->getColumn(column).getId();
}
CSMWorld::CollectionBase *CSMWorld::IdTable::idCollection() const
{
return mIdCollection;
}

@ -83,6 +83,10 @@ namespace CSMWorld
virtual bool isDeleted (const std::string& id) const;
int getColumnId(int column) const;
protected:
virtual CollectionBase *idCollection() const;
};
}

@ -1,34 +1,33 @@
#include "idtree.hpp"
#include "nestedtablewrapper.hpp" // FIXME: is this necessary?
#include "nestedtablewrapper.hpp"
#include "collectionbase.hpp"
#include "nestedcollection.hpp"
#include "nestablecolumn.hpp"
#include "columnbase.hpp"
CSMWorld::IdTree::IdTree (NestedCollection *idCollection, unsigned int features)
: IdTable (idCollection, features), mIdCollection (idCollection)
// NOTE: parent class still needs idCollection
CSMWorld::IdTree::IdTree (NestedCollection *nestedCollection, CollectionBase *idCollection, unsigned int features)
: IdTable (idCollection, features), mNestedCollection (nestedCollection)
{}
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 mNestedCollection->getNestedRowsCount(parent.row(), parent.column());
return mIdCollection->getSize();
return IdTable::rowCount(parent);
}
int CSMWorld::IdTree::columnCount (const QModelIndex & parent) const
{
if (hasChildren(parent))
return mIdCollection->getNestedColumnsCount(parent.row(), parent.column());
return mNestedCollection->getNestedColumnsCount(parent.row(), parent.column());
return mIdCollection->getColumns();
return IdTable::columnCount(parent);
}
QVariant CSMWorld::IdTree::data (const QModelIndex & index, int role) const
@ -39,60 +38,39 @@ QVariant CSMWorld::IdTree::data (const QModelIndex & index, int role) const
if ((role!=Qt::DisplayRole && role!=Qt::EditRole) || index.row() < 0 || index.column() < 0)
return QVariant();
if (role==Qt::EditRole && !mIdCollection->getColumn (index.column()).isEditable())
if (role==Qt::EditRole && !idCollection()->getColumn (index.column()).isEditable())
return QVariant();
if (index.internalId() != 0)
{
std::pair<int, int> parentAdress(unfoldIndexAdress(index.internalId()));
return mIdCollection->getNestedData(parentAdress.first,
return mNestedCollection->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();
return idCollection()->getData (index.row(), index.column());
}
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())
if (section < 0 || !idCollection() || section >= idCollection()->getColumns())
return QVariant();
// FIXME: dynamic cast
const NestableColumn& parentColumn = dynamic_cast<const NestableColumn&>(mIdCollection->getColumn(section));
const NestableColumn *parentColumn = mNestedCollection->getNestableColumn(section);
if (orientation==Qt::Vertical)
return QVariant();
if (role==Qt::DisplayRole)
return tr(parentColumn.nestedColumn(subSection).getTitle().c_str());
return tr(parentColumn->nestedColumn(subSection).getTitle().c_str());
if (role==ColumnBase::Role_Flags)
return mIdCollection->getColumn (section).mFlags;
return idCollection()->getColumn (section).mFlags;
if (role==ColumnBase::Role_Display)
return parentColumn.nestedColumn(subSection).mDisplayType;
return parentColumn->nestedColumn(subSection).mDisplayType;
return QVariant();
}
@ -101,32 +79,21 @@ bool CSMWorld::IdTree::setData (const QModelIndex &index, const QVariant &value,
{
if (index.internalId() != 0)
{
if (mIdCollection->getColumn(parent(index).column()).isEditable() && role==Qt::EditRole)
if (idCollection()->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());
mNestedCollection->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));
CSMWorld::IdTree::index (parentAdress.second, idCollection()->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;
return IdTable::setData(index, value, role);
}
Qt::ItemFlags CSMWorld::IdTree::flags (const QModelIndex & index) const
@ -134,39 +101,29 @@ 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;
return IdTable::flags(index);
}
bool CSMWorld::IdTree::removeRows (int row, int count, const QModelIndex& parent)
{
beginRemoveRows (parent, row, row+count-1);
if (parent.isValid())
{
beginRemoveRows (parent, row, row+count-1);
for (int i = 0; i < count; ++i)
{
mIdCollection->removeNestedRows(parent.row(), parent.column(), row+i);
mNestedCollection->removeNestedRows(parent.row(), parent.column(), row+i);
}
}
else
{
beginRemoveRows (parent, row, row+count-1);
mIdCollection->removeRows (row, count);
}
endRemoveRows();
endRemoveRows();
emit dataChanged (CSMWorld::IdTree::index (parent.row(), 0),
CSMWorld::IdTree::index (parent.row(), mIdCollection->getColumns()-1));
emit dataChanged (CSMWorld::IdTree::index (parent.row(), 0),
CSMWorld::IdTree::index (parent.row(), idCollection()->getColumns()-1));
return true;
return true;
}
else
return IdTable::removeRows(row, count, parent);
}
void CSMWorld::IdTree::addNestedRow(const QModelIndex& parent, int position)
@ -177,11 +134,11 @@ void CSMWorld::IdTree::addNestedRow(const QModelIndex& parent, int position)
int row = parent.row();
beginInsertRows(parent, position, position);
mIdCollection->addNestedRow(row, parent.column(), position);
mNestedCollection->addNestedRow(row, parent.column(), position);
endInsertRows();
emit dataChanged (CSMWorld::IdTree::index (row, 0),
CSMWorld::IdTree::index (row, mIdCollection->getColumns()-1));
CSMWorld::IdTree::index (row, idCollection()->getColumns()-1));
}
QModelIndex CSMWorld::IdTree::index (int row, int column, const QModelIndex& parent) const
@ -192,10 +149,10 @@ QModelIndex CSMWorld::IdTree::index (int row, int column, const QModelIndex& par
encodedId = this->foldIndexAdress(parent);
}
if (row<0 || row>=mIdCollection->getSize())
if (row<0 || row>=idCollection()->getSize())
return QModelIndex();
if (column<0 || column>=mIdCollection->getColumns())
if (column<0 || column>=idCollection()->getColumns())
return QModelIndex();
return createIndex(row, column, encodedId); // store internal id
@ -215,28 +172,6 @@ QModelIndex CSMWorld::IdTree::parent (const QModelIndex& index) const
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();
@ -255,13 +190,16 @@ std::pair< int, int > CSMWorld::IdTree::unfoldIndexAdress (unsigned int id) cons
return std::make_pair (row, column);
}
// index.data().isValid() requires RefIdAdapter::getData() to return a valid QVariant for
// nested columns (refidadapterimp.hpp)
//
// Also see comments in refidadapter.hpp and refidadapterimp.hpp.
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());
mNestedCollection->getNestableColumn(index.column())->hasChildren() &&
index.data().isValid()); // FIXME: not sure why this check is also needed
}
void CSMWorld::IdTree::setNestedTable(const QModelIndex& index, const CSMWorld::NestedTableWrapperBase& nestedTable)
@ -276,10 +214,10 @@ void CSMWorld::IdTree::setNestedTable(const QModelIndex& index, const CSMWorld::
removeRowsMode = true;
}
mIdCollection->setNestedTable(index.row(), index.column(), nestedTable);
mNestedCollection->setNestedTable(index.row(), index.column(), nestedTable);
emit dataChanged (CSMWorld::IdTree::index (index.row(), 0),
CSMWorld::IdTree::index (index.row(), mIdCollection->getColumns()-1));
CSMWorld::IdTree::index (index.row(), idCollection()->getColumns()-1));
if (removeRowsMode)
{
@ -292,5 +230,5 @@ CSMWorld::NestedTableWrapperBase* CSMWorld::IdTree::nestedTable(const QModelInde
if (!hasChildren(index))
throw std::logic_error("Tried to retrive nested table, but index has no children");
return mIdCollection->nestedTable(index.row(), index.column());
return mNestedCollection->nestedTable(index.row(), index.column());
}

@ -22,13 +22,13 @@ namespace CSMWorld
struct RecordBase;
class NestedTableWrapperBase; // FIXME: is this necessary?
class IdTree : public IdTable // IdTable is derived from QAbstractItemModel
class IdTree : public IdTable
{
Q_OBJECT
private:
NestedCollection *mIdCollection;
NestedCollection *mNestedCollection;
// not implemented
IdTree (const IdTree&);
@ -39,8 +39,8 @@ namespace CSMWorld
public:
IdTree (NestedCollection *idCollection, unsigned int features = 0);
///< The ownership of \a idCollection is not transferred.
IdTree (NestedCollection *nestedCollection, CollectionBase *idCollection, unsigned int features = 0);
///< The ownerships of \a nestedCollecton and \a idCollection are not transferred.
virtual ~IdTree();
@ -50,8 +50,6 @@ namespace CSMWorld
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;
@ -63,9 +61,6 @@ namespace CSMWorld
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;

@ -1,44 +0,0 @@
#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;
}

@ -1,33 +0,0 @@
#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,7 +1,17 @@
#include "nestedcollection.hpp"
CSMWorld::NestedCollection::NestedCollection() : mParent(0)
CSMWorld::NestedCollection::NestedCollection()
{}
CSMWorld::NestedCollection::~NestedCollection()
{}
int CSMWorld::NestedCollection::getNestedRowsCount(int row, int column) const
{
return 0;
}
int CSMWorld::NestedCollection::getNestedColumnsCount(int row, int column) const
{
return 0;
}

@ -1,17 +1,14 @@
#ifndef CSM_WOLRD_NESTEDCOLLECTION_H
#define CSM_WOLRD_NESTEDCOLLECTION_H
#include <vector>
#include "collectionbase.hpp"
class QVariant;
namespace CSMWorld
{
class NestableColumn;
class NestedTableWrapperBase;
class NestedCollection : public CollectionBase
class NestedCollection
{
public:
@ -21,25 +18,22 @@ namespace CSMWorld
virtual void addNestedRow(int row, int col, int position) = 0;
virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const = 0;
virtual NestedTableWrapperBase* nestedTable(int row, int column) const = 0;
virtual void removeNestedRows(int row, int column, int subRow) = 0;
virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable) = 0;
virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const = 0;
virtual void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn) = 0;
virtual int getNestedRowsCount(int row, int column) const = 0;
virtual NestedTableWrapperBase* nestedTable(int row, int column) const = 0;
virtual int getNestedColumnsCount(int row, int column) const = 0;
virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable) = 0;
virtual void removeNestedRows(int row, int column, int subRow) = 0;
virtual int getNestedRowsCount(int row, int column) const;
private:
virtual int getNestedColumnsCount(int row, int column) const;
std::vector<NestedCollection *> mChildren;
NestedCollection *mParent; // currently unused
virtual NestableColumn *getNestableColumn(int column) = 0;
};
}
#endif
#endif // CSM_WOLRD_NESTEDCOLLECTION_H

@ -8,7 +8,7 @@
#include "refidadapter.hpp"
#include "refidadapterimp.hpp"
#include "columns.hpp"
#include "nestedtablewrapper.hpp" // FIXME: is this really necessary?
#include "nestedtablewrapper.hpp"
CSMWorld::RefIdColumn::RefIdColumn (int columnId, Display displayType, int flag,
bool editable, bool userEditable)
@ -25,7 +25,6 @@ bool CSMWorld::RefIdColumn::isUserEditable() const
return mUserEditable;
}
// FIXME: const problem
/*const*/ CSMWorld::RefIdAdapter& CSMWorld::RefIdCollection::findAdapter (UniversalId::Type type) const
{
@ -667,6 +666,11 @@ int CSMWorld::RefIdCollection::getNestedColumnsCount(int row, int column) const
return adaptor.getNestedColumnsCount(&mColumns.at(column), mData);
}
CSMWorld::NestableColumn *CSMWorld::RefIdCollection::getNestableColumn(int column)
{
return &mColumns.at(column);
}
void CSMWorld::RefIdCollection::addNestedRow(int row, int col, int position)
{
RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row);

@ -5,7 +5,8 @@
#include <map>
#include <deque>
#include "nestablecolumn.hpp"
#include "columnbase.hpp"
#include "collectionbase.hpp"
#include "nestedcollection.hpp"
#include "refiddata.hpp"
@ -17,7 +18,7 @@ namespace ESM
namespace CSMWorld
{
class RefIdAdapter;
class NestedTableWrapperBase; // FIXME: is this really needed?
class NestedTableWrapperBase;
class RefIdColumn : public NestableColumn
{
@ -35,7 +36,7 @@ namespace CSMWorld
virtual bool isUserEditable() const;
};
class RefIdCollection : public NestedCollection
class RefIdCollection : public CollectionBase, public NestedCollection
{
private:
@ -117,12 +118,12 @@ namespace CSMWorld
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;
NestableColumn *getNestableColumn(int column);
virtual void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn);
virtual void removeNestedRows(int row, int column, int subRow);

Loading…
Cancel
Save