store whole container representing the nested table inside of the

command

Static nature of C++ forced me to use templates. Bit frustraiting.
This commit is contained in:
Marek Kochanowicz 2014-07-18 18:26:22 +02:00
parent 16292bf23e
commit 1ff8abb240
14 changed files with 167 additions and 38 deletions

View file

@ -19,7 +19,7 @@ opencs_hdrs_noqt (model/doc
opencs_units (model/world
idtable idtableproxymodel regionmap data commanddispatcher
idtablebase resourcetable nestedtablemodel
idtablebase resourcetable nestedtablemodel nestedtablewrapper
)

View file

@ -16,6 +16,8 @@
#include "collectionbase.hpp"
#include "nestedtablewrapper.hpp"
namespace CSMWorld
{
/// \brief Access to ID field in records
@ -90,6 +92,10 @@ namespace CSMWorld
virtual void setData (int index, int column, const QVariant& data);
virtual NestedTableWrapperBase nestedTable(int row, int column) const;
virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable);
virtual const ColumnBase& getColumn (int column) const;
virtual void merge();
@ -301,6 +307,18 @@ namespace CSMWorld
return QVariant();
}
template<typename ESXRecordT, typename IdAccessorT>
NestedTableWrapperBase Collection<ESXRecordT, IdAccessorT>::nestedTable(int row, int column) const
{
return NestedTableWrapperBase();
}
template<typename ESXRecordT, typename IdAccessorT>
void Collection<ESXRecordT, IdAccessorT>::setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable)
{
throw std::logic_error("setNestedTable was not overriden");
}
template<typename ESXRecordT, typename IdAccessorT>
void Collection<ESXRecordT, IdAccessorT>::setData (int index, int column, const QVariant& data)
{

View file

@ -13,6 +13,7 @@ namespace CSMWorld
{
struct ColumnBase;
struct RecordBase;
class NestedTableWrapperBase;
/// \brief Base class for record collections
///
@ -34,9 +35,9 @@ namespace CSMWorld
virtual int getSize() const = 0;
virtual int getNestedRowsCount(int row, int column) const;
virtual int getNestedRowsCount(int row, int column) const;
virtual int getNestedColumnsCount(int row, int column) const;
virtual int getNestedColumnsCount(int row, int column) const;
virtual std::string getId (int index) const = 0;
@ -50,6 +51,10 @@ namespace CSMWorld
virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const = 0;
virtual NestedTableWrapperBase nestedTable(int row, int column) const = 0;
virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable) = 0;
virtual void setData (int index, int column, const QVariant& data) = 0;
virtual void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn);

View file

@ -177,26 +177,10 @@ CSMWorld::DeleteNestedCommand::DeleteNestedCommand (IdTable& model, const std::s
mModel(model),
mParentColumn(parentColumn),
QUndoCommand(parent),
mNestedRow(nestedRow)
mNestedRow(nestedRow),
mOld(model.nestedTable(model.getModelIndex(id, parentColumn)))
{
setText (("Delete nested row in " + mId).c_str());
const QModelIndex& parentIndex = mModel.getModelIndex(mId, mParentColumn);
const int columnsCount = mModel.columnCount(parentIndex);
for (int i = 0; i < columnsCount; ++i)
{
const QModelIndex& childIndex = mModel.index(nestedRow, i, parentIndex);
QVariant data = childIndex.data();
if (!data.isValid())
{
data = childIndex.data(Qt::DisplayRole);
}
mOld.push_back(data);
}
}
void CSMWorld::DeleteNestedCommand::redo()
@ -211,14 +195,7 @@ void CSMWorld::DeleteNestedCommand::undo()
{
const QModelIndex& parentIndex = mModel.getModelIndex(mId, mParentColumn);
mModel.addNestedRow(parentIndex, mNestedRow);
for (int i = 0; i < mModel.columnCount(parentIndex); ++i)
{
const QModelIndex& current = mModel.index(mNestedRow, i, parentIndex);
mModel.setData(current, mOld[i]);
}
mModel.setNestedTable(parentIndex, mOld);
}
CSMWorld::AddNestedCommand::AddNestedCommand(IdTable& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent)
@ -226,7 +203,8 @@ CSMWorld::AddNestedCommand::AddNestedCommand(IdTable& model, const std::string&
mId(id),
mNewRow(nestedRow),
mParentColumn(parentColumn),
QUndoCommand(parent)
QUndoCommand(parent),
mOld(model.nestedTable(model.getModelIndex(id, parentColumn)))
{
setText (("Added nested row in " + mId).c_str());
}
@ -242,5 +220,5 @@ void CSMWorld::AddNestedCommand::undo()
{
const QModelIndex& parentIndex = mModel.getModelIndex(mId, mParentColumn);
mModel.removeRows(mNewRow, 1, parentIndex);
mModel.setNestedTable(parentIndex, mOld);
}

View file

@ -13,6 +13,7 @@
#include <QVariant>
#include "universalid.hpp"
#include "nestedtablewrapper.hpp"
class QModelIndex;
class QAbstractItemModel;
@ -22,6 +23,7 @@ namespace CSMWorld
class IdTable;
class IdTable;
class RecordBase;
class NestedTableWrapperBase;
class ModifyCommand : public QUndoCommand
{
@ -143,7 +145,7 @@ namespace CSMWorld
std::string mId;
std::vector<QVariant> mOld;
NestedTableWrapperBase mOld;
int mParentColumn;
@ -164,6 +166,8 @@ namespace CSMWorld
std::string mId;
NestedTableWrapperBase mOld;
int mNewRow;
int mParentColumn;

View file

@ -2,6 +2,7 @@
#include <QDebug>
#include <cassert>
#include "nestedtablewrapper.hpp"
#include "collectionbase.hpp"
#include "columnbase.hpp"
@ -357,3 +358,23 @@ bool CSMWorld::IdTable::hasChildren(const QModelIndex& index) const
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");
}
mIdCollection->setNestedTable(index.row(), index.column(), nestedTable);
}
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 mIdCollection->nestedTable(index.row(), index.column());
}

View file

@ -20,6 +20,7 @@ namespace CSMWorld
{
class CollectionBase;
class RecordBase;
class NestedTableWrapperBase;
class IdTable : public IdTableBase
{
@ -52,6 +53,10 @@ namespace CSMWorld
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;

View file

@ -0,0 +1,7 @@
#include "nestedtablewrapper.hpp"
CSMWorld::NestedTableWrapperBase::NestedTableWrapperBase()
{}
CSMWorld::NestedTableWrapperBase::~NestedTableWrapperBase()
{}

View file

@ -0,0 +1,33 @@
#ifndef CSM_WOLRD_NESTEDTABLEWRAPPER_H
#define CSM_WOLRD_NESTEDTABLEWRAPPER_H
#include <components/esm/loadcont.hpp>
#include <vector>
namespace CSMWorld
{
struct NestedTableWrapperBase
{
virtual ~NestedTableWrapperBase();
NestedTableWrapperBase();
};
template<typename NestedTable>
class NestedTableWrapper : public NestedTableWrapperBase
{
NestedTable mNestedTable;
public:
NestedTableWrapper(const NestedTable& nestedTable) {}
NestedTable getNestedTable() const
{
return mNestedTable;
}
virtual ~NestedTableWrapper() {}
};
}
#endif

View file

@ -10,6 +10,7 @@ namespace CSMWorld
class RefIdColumn;
class RefIdData;
class RecordBase;
class NestedTableWrapperBase;
class RefIdAdapter
{
@ -55,6 +56,10 @@ namespace CSMWorld
virtual void removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, int rowToRemove) const = 0;
virtual void addNestedRow (const RefIdColumn *column, RefIdData& data, int index, int position) const = 0;
virtual void setNestedTable (const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) = 0;
virtual NestedTableWrapperBase nestedTable (const RefIdColumn * column, const RefIdData& data, int index) const = 0;
};
}

View file

@ -1,7 +1,9 @@
#include "refidadapterimp.hpp"
#include "nestedtablewrapper.hpp"
#include <cassert>
#include <stdexcept>
#include <components/esm/loadcont.hpp>
CSMWorld::PotionRefIdAdapter::PotionRefIdAdapter (const InventoryColumns& columns,
const RefIdColumn *autoCalc)
@ -305,6 +307,27 @@ void CSMWorld::ContainerRefIdAdapter::setNestedData(const RefIdColumn *column,
}
}
void CSMWorld::ContainerRefIdAdapter::setNestedTable(const RefIdColumn* column,
RefIdData& data,
int index,
const NestedTableWrapperBase& nestedTable)
{
Record<ESM::Container>& record = dynamic_cast<Record<ESM::Container>&> (
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container)));
record.get().mInventory.mList = dynamic_cast<const NestedTableWrapper<std::vector<ESM::ContItem> >&>(nestedTable).getNestedTable();
}
CSMWorld::NestedTableWrapperBase CSMWorld::ContainerRefIdAdapter::nestedTable (const RefIdColumn* column,
const RefIdData& data,
int index) const
{
const Record<ESM::Container>& record = dynamic_cast<const Record<ESM::Container>&> (
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container)));
return NestedTableWrapper<std::vector<ESM::ContItem> >(record.get().mInventory.mList);
}
QVariant CSMWorld::ContainerRefIdAdapter::getNestedData (const CSMWorld::RefIdColumn* column,
const CSMWorld::RefIdData& data,
int index,

View file

@ -15,6 +15,8 @@
namespace CSMWorld
{
class NestedTableWrapperBase;
struct BaseColumns
{
const RefIdColumn *mId;
@ -637,6 +639,10 @@ namespace CSMWorld
virtual void removeNestedRow (const RefIdColumn *column, RefIdData& data, int index, int rowToRemove) const;
virtual void addNestedRow (const RefIdColumn *column, RefIdData& data, int index, int position) const;
virtual NestedTableWrapperBase nestedTable (const RefIdColumn * column, const RefIdData& data, int index) const;
virtual void setNestedTable (const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable);
};
struct CreatureColumns : public ActorColumns

View file

@ -10,6 +10,7 @@
#include "refidadapter.hpp"
#include "refidadapterimp.hpp"
#include "columns.hpp"
#include "nestedtablewrapper.hpp"
CSMWorld::RefIdColumn::RefIdColumn (int columnId, Display displayType, int flag,
bool editable, bool userEditable, bool canNest)
@ -27,7 +28,7 @@ bool CSMWorld::RefIdColumn::isUserEditable() const
}
const CSMWorld::RefIdAdapter& CSMWorld::RefIdCollection::findAdaptor (UniversalId::Type type) const
CSMWorld::RefIdAdapter& CSMWorld::RefIdCollection::findAdaptor (UniversalId::Type type) const
{
std::map<UniversalId::Type, RefIdAdapter *>::const_iterator iter = mAdapters.find (type);
@ -641,3 +642,21 @@ void CSMWorld::RefIdCollection::addNestedRow(int row, int col, int position)
adaptor.addNestedRow(&mColumns.at(col), mData, localIndex.first, position);
}
void CSMWorld::RefIdCollection::setNestedTable(int row, int column, const CSMWorld::NestedTableWrapperBase& nestedTable)
{
RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row);
CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast<CSMWorld::NestedRefIdAdapter&>(findAdaptor (localIndex.second));
adaptor.setNestedTable(&mColumns.at(column), mData, localIndex.first, nestedTable);
}
CSMWorld::NestedTableWrapperBase CSMWorld::RefIdCollection::nestedTable(int row, int column) const
{
RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row);
const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast<const CSMWorld::NestedRefIdAdapter&>(findAdaptor (localIndex.second));
return adaptor.nestedTable(&mColumns.at(column), mData, localIndex.first);
}

View file

@ -17,6 +17,7 @@ namespace ESM
namespace CSMWorld
{
class RefIdAdapter;
class NestedTableWrapperBase;
class RefIdColumn : public NestColumn
{
@ -44,7 +45,7 @@ namespace CSMWorld
private:
const RefIdAdapter& findAdaptor (UniversalId::Type) const;
RefIdAdapter& findAdaptor (UniversalId::Type) const;
///< Throws an exception if no adaptor for \a Type can be found.
public:
@ -71,6 +72,10 @@ namespace CSMWorld
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);