1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-20 05:23:53 +00:00

working on the issue

This commit is contained in:
Marek Kochanowicz 2014-06-09 10:35:39 +02:00
parent 6929e541dd
commit 21a1f6f4ae
11 changed files with 342 additions and 18 deletions

View file

@ -73,6 +73,10 @@ namespace CSMWorld
///< Add a new record (modified)
virtual int getSize() const;
virtual int getNestedColumnsCount(int column) const;
virtual int getNestedRowsCount(int row, int column) const;
virtual std::string getId (int index) const;
@ -92,7 +96,7 @@ namespace CSMWorld
virtual void purge();
///< Remove records that are flagged as erased.
virtual void removeRows (int index, int count) ;
virtual void removeRows (int index, int count);
virtual void appendBlankRecord (const std::string& id,
UniversalId::Type type = UniversalId::Type_None);
@ -247,6 +251,20 @@ namespace CSMWorld
{
return mRecords.size();
}
template<typename ESXRecordT, typename IdAccessorT>
int Collection<ESXRecordT, IdAccessorT>::getNestedRowsCount(int row, int column) const
{
//TODO
return 0;
}
template<typename ESXRecordT, typename IdAccessorT>
int Collection<ESXRecordT, IdAccessorT>::getNestedColumnsCount(int column) const
{
//TODO
return 0;
}
template<typename ESXRecordT, typename IdAccessorT>
std::string Collection<ESXRecordT, IdAccessorT>::getId (int index) const

View file

@ -28,4 +28,21 @@ int CSMWorld::CollectionBase::findColumnIndex (Columns::ColumnId id) const
throw std::logic_error ("invalid column index");
return index;
}
}
void CSMWorld::CollectionBase::setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn)
{
assert(false); //TODO remove and make pure abstract
}
int CSMWorld::CollectionBase::getNestedColumnsCount(int row, int column) const
{
assert(false); //TODO remove and make pure abstract
return 0;
}
int CSMWorld::CollectionBase::getNestedRowsCount(int row, int column) const
{
assert(false); //TODO, make pure abstract
return 0;
}

View file

@ -33,6 +33,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 std::string getId (int index) const = 0;
@ -46,6 +50,8 @@ namespace CSMWorld
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);
// Not in use. Temporarily removed so that the implementation of RefIdCollection can continue without
// these functions for now.
// virtual void merge() = 0;
@ -106,4 +112,4 @@ namespace CSMWorld
};
}
#endif
#endif

View file

@ -1,6 +1,8 @@
#include "idtable.hpp"
#include <QDebug>
#include "collectionbase.hpp"
#include "columnbase.hpp"
@ -14,16 +16,21 @@ CSMWorld::IdTable::~IdTable()
int CSMWorld::IdTable::rowCount (const QModelIndex & parent) const
{
if (parent.isValid())
return 0;
if (hasChildren(parent))
{
int nestedRows = mIdCollection->getNestedRowsCount(parent.row(), parent.column());
return nestedRows;
}
return mIdCollection->getSize();
}
int CSMWorld::IdTable::columnCount (const QModelIndex & parent) const
{
if (parent.isValid())
return 0;
{
return mIdCollection->getNestedColumnsCount(parent.row(), parent.column());
}
return mIdCollection->getColumns();
}
@ -36,7 +43,17 @@ QVariant CSMWorld::IdTable::data (const QModelIndex & index, int role) const
if (role==Qt::EditRole && !mIdCollection->getColumn (index.column()).isEditable())
return QVariant();
<<<<<<< Updated upstream
return mIdCollection->getData (index.row(), index.column());
=======
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());
}
>>>>>>> Stashed changes
}
QVariant CSMWorld::IdTable::headerData (int section, Qt::Orientation orientation, int role) const
@ -60,11 +77,18 @@ bool CSMWorld::IdTable::setData ( const QModelIndex &index, const QVariant &valu
{
if (mIdCollection->getColumn (index.column()).isEditable() && role==Qt::EditRole)
{
mIdCollection->setData (index.row(), index.column(), value);
if (index.internalId() == 0)
{
mIdCollection->setData (index.row(), index.column(), value);
emit dataChanged (CSMWorld::IdTable::index (index.row(), 0),
CSMWorld::IdTable::index (index.row(), mIdCollection->getColumns()-1));
emit dataChanged (CSMWorld::IdTable::index (index.row(), 0),
CSMWorld::IdTable::index (index.row(), mIdCollection->getColumns()-1));
} else
{
const std::pair<int, int>& parentAdress(unfoldIndexAdress(index.internalId()));
mIdCollection->setNestedData(parentAdress.first, parentAdress.second, value, index.row(), index.column());
}
return true;
}
@ -111,7 +135,23 @@ QModelIndex CSMWorld::IdTable::index (int row, int column, const QModelIndex& pa
QModelIndex CSMWorld::IdTable::parent (const QModelIndex& index) const
{
<<<<<<< Updated upstream
return QModelIndex();
=======
if (index.internalId() == 0) //0 is used for indexs with invalid parent (top level data)
{
return QModelIndex();
}
const std::pair<int, int>& adress(unfoldIndexAdress(index.internalId()));
if (adress.first >= this->rowCount() || adress.second >= this->columnCount())
{
qDebug()<<"Parent index is not present in the model";
throw "Parent index is not present in the model";
}
return createIndex(adress.first, adress.second, 0);
>>>>>>> Stashed changes
}
void CSMWorld::IdTable::addRecord (const std::string& id, UniversalId::Type type)
@ -240,4 +280,37 @@ std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view (int row)
int CSMWorld::IdTable::getColumnId(int column) const
{
return mIdCollection->getColumn(column).getId();
}
<<<<<<< Updated upstream
}
=======
}
bool CSMWorld::IdTable::hasChildren(const QModelIndex& index) const
{
return (index.isValid() &&
mIdCollection->getColumn (index.column()).mDisplayType == ColumnBase::Display_Nested &&
index.data().isValid());
}
unsigned int CSMWorld::IdTable::foldIndexAdress (const QModelIndex& index) const
{
unsigned int out = index.row() * this->columnCount();
out += index.column();
++out;
return out;
}
std::pair< int, int > CSMWorld::IdTable::unfoldIndexAdress (unsigned int id) const
{
if (id == 0)
{
qDebug()<<"Attempt to unfold index id of the top level data cell";
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<int, int>(row, column);
}
>>>>>>> Stashed changes

View file

@ -8,6 +8,19 @@
#include "universalid.hpp"
#include "columns.hpp"
<<<<<<< Updated upstream
=======
/*! \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. The parent is encoded in the internalid of the index model
* See methods fold and unfold adress to see why. This approach has some serious limitations: it allows only
* a single level of the nesting. At the point of creating this code this seemed to be a good enough solution.
* If for some reason it turned out that in fact multiple levels of nesting are needed, change in the addressing of the
* index is most likely the very first to be considered.
*/
>>>>>>> Stashed changes
namespace CSMWorld
{
class CollectionBase;
@ -44,6 +57,13 @@ namespace CSMWorld
// not implemented
IdTable (const IdTable&);
IdTable& operator= (const IdTable&);
<<<<<<< Updated upstream
=======
unsigned int foldIndexAdress(const QModelIndex& index) const;
std::pair<int, int> unfoldIndexAdress(unsigned int id) const;
>>>>>>> Stashed changes
public:
@ -71,6 +91,8 @@ namespace CSMWorld
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

View file

@ -3,4 +3,12 @@
CSMWorld::RefIdAdapter::RefIdAdapter() {}
CSMWorld::RefIdAdapter::~RefIdAdapter() {}
<<<<<<< Updated upstream
CSMWorld::RefIdAdapter::~RefIdAdapter() {}
=======
CSMWorld::RefIdAdapter::~RefIdAdapter() {}
CSMWorld::NestedRefIdAdapter::NestedRefIdAdapter() {}
CSMWorld::NestedRefIdAdapter::~NestedRefIdAdapter() {}
>>>>>>> Stashed changes

View file

@ -31,8 +31,28 @@ namespace CSMWorld
///< If the data type does not match an exception is thrown.
virtual std::string getId (const RecordBase& record) const = 0;
virtual void setId(RecordBase& record, const std::string& id) = 0;
};
class NestedRefIdAdapter
{
public:
NestedRefIdAdapter();
virtual ~NestedRefIdAdapter();
virtual void setNestedData (const RefIdColumn *column, RefIdData& data, int row,
const QVariant& value, int subRowIndex, int subColIndex) const = 0;
virtual QVariant getNestedData (const RefIdColumn *column, const RefIdData& data,
int index, int subRowIndex, int subColIndex) const = 0;
virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const = 0;
virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const = 0;
};
}
#endif
#endif

View file

@ -1,6 +1,8 @@
#include "refidadapterimp.hpp"
#include <QDebug>
CSMWorld::PotionRefIdAdapter::PotionRefIdAdapter (const InventoryColumns& columns,
const RefIdColumn *autoCalc)
: InventoryRefIdAdapter<ESM::Potion> (UniversalId::Type_Potion, columns),
@ -178,6 +180,32 @@ CSMWorld::ContainerRefIdAdapter::ContainerRefIdAdapter (const NameColumns& colum
mOrganic (organic), mRespawn (respawn)
{}
int CSMWorld::ContainerRefIdAdapter::getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const
{
qDebug()<<"getting nested columns count";
if (column==mContent)
{
return 2;
} else {
throw "Trying to obtain nested columns count, but column does not have nested columns!";
}
}
int CSMWorld::ContainerRefIdAdapter::getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const
{
qDebug()<<"getting nested rows count";
const Record<ESM::Container>& record = static_cast<const Record<ESM::Container>&> (
data.getRecord(RefIdData::LocalIndex (index, UniversalId::Type_Container)));
qDebug() << "exception above";
if (column==mContent)
{
qDebug() << record.get().mInventory.mList.size();
return record.get().mInventory.mList.size();
} else {
throw "Trying to obtain nested rows count, but column does not have nested columns!";
}
}
QVariant CSMWorld::ContainerRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data,
int index) const
{
@ -192,6 +220,9 @@ QVariant CSMWorld::ContainerRefIdAdapter::getData (const RefIdColumn *column, co
if (column==mRespawn)
return (record.get().mFlags & ESM::Container::Respawn)!=0;
if (column==mContent)
return true;
return NameRefIdAdapter<ESM::Container>::getData (column, data, index);
}
@ -222,6 +253,71 @@ void CSMWorld::ContainerRefIdAdapter::setData (const RefIdColumn *column, RefIdD
NameRefIdAdapter<ESM::Container>::setData (column, data, index, value);
}
<<<<<<< Updated upstream
=======
void CSMWorld::ContainerRefIdAdapter::setNestedData(const RefIdColumn *column, RefIdData& data,
int row,
const QVariant& value,
int subRowIndex,
int subColIndex) const
{
Record<ESM::Container>& record = static_cast<Record<ESM::Container>&> (
data.getRecord (RefIdData::LocalIndex (row, UniversalId::Type_Container)));
if (column==mContent)
{
switch (subColIndex)
{
case 0:
record.get().mInventory.mList.at(subRowIndex).mItem.assign(std::string(value.toString().toUtf8().constData()));
break;
case 1:
record.get().mInventory.mList.at(subRowIndex).mCount = value.toInt();
break;
default:
throw "Trying to access non-existing column in the nested table!";
}
} else
{
throw "This column does not hold multiple values.";
}
}
QVariant CSMWorld::ContainerRefIdAdapter::getNestedData (const CSMWorld::RefIdColumn* column,
const CSMWorld::RefIdData& data,
int index,
int subRowIndex,
int subColIndex) const
{
qDebug()<<"Accessing content column";
const Record<ESM::Container>& record = static_cast<const Record<ESM::Container>&> (
data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container)));
if (column==mContent)
{
const ESM::ContItem& content = record.get().mInventory.mList.at(subRowIndex);
switch (subColIndex)
{
case 0:
return QString::fromUtf8(content.mItem.toString().c_str());
case 1:
return content.mCount;
default:
throw "Trying to access non-existing column in the nested table!";
}
} else
{
throw "This column does not hold multiple values.";
}
}
>>>>>>> Stashed changes
CSMWorld::CreatureColumns::CreatureColumns (const ActorColumns& actorColumns)
: ActorColumns (actorColumns)
{}
@ -572,4 +668,4 @@ void CSMWorld::WeaponRefIdAdapter::setData (const RefIdColumn *column, RefIdData
else
EnchantableRefIdAdapter<ESM::Weapon>::setData (column, data, index, value);
}
}
}

View file

@ -23,6 +23,7 @@ namespace CSMWorld
};
/// \brief Base adapter for all refereceable record types
/// Adapters that can handle nested tables, needs to return valid qvariant for parent columns
template<typename RecordT>
class BaseRefIdAdapter : public RefIdAdapter
{
@ -605,7 +606,7 @@ namespace CSMWorld
///< If the data type does not match an exception is thrown.
};
class ContainerRefIdAdapter : public NameRefIdAdapter<ESM::Container>
class ContainerRefIdAdapter : public NameRefIdAdapter<ESM::Container>, public NestedRefIdAdapter
{
const RefIdColumn *mWeight;
const RefIdColumn *mOrganic;
@ -614,14 +615,30 @@ namespace CSMWorld
public:
ContainerRefIdAdapter (const NameColumns& columns, const RefIdColumn *weight,
<<<<<<< Updated upstream
const RefIdColumn *organic, const RefIdColumn *respawn);
=======
const RefIdColumn *organic, const RefIdColumn *respawn, const RefIdColumn *content);
virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index)
const;
virtual QVariant getNestedData (const RefIdColumn *column, const RefIdData& data,
int index, int subRowIndex, int subColIndex) const;
>>>>>>> Stashed changes
virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) const;
<<<<<<< Updated upstream
=======
virtual void setNestedData (const RefIdColumn *column, RefIdData& data, int index,
const QVariant& value, int subRowIndex, int subColIndex) const;
>>>>>>> Stashed changes
virtual void setData (const RefIdColumn *column, RefIdData& data, int index,
const QVariant& value) const;
const QVariant& value) const;
///< If the data type does not match an exception is thrown.
virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const;
virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const;
};
struct CreatureColumns : public ActorColumns

View file

@ -3,6 +3,7 @@
#include <stdexcept>
#include <memory>
#include <QDebug>
#include <components/esm/esmreader.hpp>
@ -416,6 +417,19 @@ QVariant CSMWorld::RefIdCollection::getData (int index, int column) const
return adaptor.getData (&mColumns.at (column), mData, localIndex.first);
}
<<<<<<< Updated upstream
=======
QVariant CSMWorld::RefIdCollection::getNestedData (int row, int column, int subRow, int subColumn) const
{
RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(row);
const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast<const CSMWorld::NestedRefIdAdapter&>(findAdaptor (localIndex.second));
//if this overloaded, base class method was not overriden, crash will happen (assert(false)) Don't try to use this method for non-nested columns!
return adaptor.getNestedData (&mColumns.at (column), mData, localIndex.first, subRow, subColumn);
}
>>>>>>> Stashed changes
void CSMWorld::RefIdCollection::setData (int index, int column, const QVariant& data)
{
RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (index);
@ -425,6 +439,15 @@ void CSMWorld::RefIdCollection::setData (int index, int column, const QVariant&
adaptor.setData (&mColumns.at (column), mData, localIndex.first, data);
}
void CSMWorld::RefIdCollection::setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn)
{
RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row);
const RefIdAdapter& adaptor = findAdaptor (localIndex.second);
dynamic_cast<const CSMWorld::NestedRefIdAdapter&>(adaptor).setNestedData (&mColumns.at (column), mData, localIndex.first, data, subRow, subColumn);
}
void CSMWorld::RefIdCollection::removeRows (int index, int count)
{
mData.erase (index, count);
@ -566,3 +589,21 @@ const CSMWorld::RefIdData& CSMWorld::RefIdCollection::getDataSet() const
return mData;
}
int CSMWorld::RefIdCollection::getNestedRowsCount(int row, int column) const
{
RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row);
const CSMWorld::NestedRefIdAdapter& adaptor = dynamic_cast<const CSMWorld::NestedRefIdAdapter&>(findAdaptor (localIndex.second));
const int count = adaptor.getNestedRowsCount(&mColumns.at(column), mData, localIndex.first);
return count;
}
int CSMWorld::RefIdCollection::getNestedColumnsCount(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.getNestedColumnsCount(&mColumns.at(column), mData);
}

View file

@ -55,6 +55,10 @@ 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;
@ -67,6 +71,8 @@ namespace CSMWorld
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 cloneRecord(const std::string& origin,