forked from mirror/openmw-tes3mp
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:
parent
16292bf23e
commit
1ff8abb240
14 changed files with 167 additions and 38 deletions
|
@ -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
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
@ -300,6 +306,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)
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace CSMWorld
|
|||
{
|
||||
struct ColumnBase;
|
||||
struct RecordBase;
|
||||
class NestedTableWrapperBase;
|
||||
|
||||
/// \brief Base class for record collections
|
||||
///
|
||||
|
@ -33,10 +34,10 @@ namespace CSMWorld
|
|||
virtual ~CollectionBase();
|
||||
|
||||
virtual int getSize() const = 0;
|
||||
|
||||
virtual int getNestedRowsCount(int row, int column) const;
|
||||
|
||||
virtual int getNestedColumnsCount(int row, int column) const;
|
||||
virtual int getNestedRowsCount(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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
@ -241,6 +219,6 @@ void CSMWorld::AddNestedCommand::redo()
|
|||
void CSMWorld::AddNestedCommand::undo()
|
||||
{
|
||||
const QModelIndex& parentIndex = mModel.getModelIndex(mId, mParentColumn);
|
||||
|
||||
mModel.removeRows(mNewRow, 1, parentIndex);
|
||||
|
||||
mModel.setNestedTable(parentIndex, mOld);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ namespace CSMWorld
|
|||
{
|
||||
class CollectionBase;
|
||||
class RecordBase;
|
||||
class NestedTableWrapperBase;
|
||||
|
||||
class IdTable : public IdTableBase
|
||||
{
|
||||
|
@ -51,6 +52,10 @@ 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);
|
||||
|
||||
|
|
7
apps/opencs/model/world/nestedtablewrapper.cpp
Normal file
7
apps/opencs/model/world/nestedtablewrapper.cpp
Normal file
|
@ -0,0 +1,7 @@
|
|||
#include "nestedtablewrapper.hpp"
|
||||
|
||||
CSMWorld::NestedTableWrapperBase::NestedTableWrapperBase()
|
||||
{}
|
||||
|
||||
CSMWorld::NestedTableWrapperBase::~NestedTableWrapperBase()
|
||||
{}
|
33
apps/opencs/model/world/nestedtablewrapper.hpp
Normal file
33
apps/opencs/model/world/nestedtablewrapper.hpp
Normal 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
|
|
@ -10,6 +10,7 @@ namespace CSMWorld
|
|||
class RefIdColumn;
|
||||
class RefIdData;
|
||||
class RecordBase;
|
||||
class NestedTableWrapperBase;
|
||||
|
||||
class RefIdAdapter
|
||||
{
|
||||
|
@ -41,7 +42,7 @@ namespace CSMWorld
|
|||
NestedRefIdAdapter();
|
||||
|
||||
virtual ~NestedRefIdAdapter();
|
||||
|
||||
|
||||
virtual void setNestedData (const RefIdColumn *column, RefIdData& data, int row,
|
||||
const QVariant& value, int subRowIndex, int subColIndex) const = 0;
|
||||
|
||||
|
@ -53,8 +54,12 @@ namespace CSMWorld
|
|||
virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const = 0;
|
||||
|
||||
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;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
@ -70,6 +71,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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue