#ifndef CSM_WOLRD_NESTEDIDCOLLECTION_H #define CSM_WOLRD_NESTEDIDCOLLECTION_H #include <map> #include <stdexcept> #include "nestedcollection.hpp" #include "nestedcoladapterimp.hpp" namespace ESM { class ESMReader; } namespace CSMWorld { struct NestedTableWrapperBase; struct Cell; template<typename T, typename AT> class IdCollection; template<typename ESXRecordT, typename IdAccessorT = IdAccessor<ESXRecordT> > class NestedIdCollection : public IdCollection<ESXRecordT, IdAccessorT>, public NestedCollection { std::map<const ColumnBase*, NestedColumnAdapter<ESXRecordT>* > mAdapters; const NestedColumnAdapter<ESXRecordT>& getAdapter(const ColumnBase &column) const; public: NestedIdCollection (); ~NestedIdCollection(); virtual void addNestedRow(int row, int column, int position); virtual void removeNestedRows(int row, int column, int subRow); virtual QVariant getNestedData(int row, int column, int subRow, int subColumn) const; virtual void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn); virtual NestedTableWrapperBase* nestedTable(int row, int column) const; virtual void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable); virtual int getNestedRowsCount(int row, int column) const; virtual int getNestedColumnsCount(int row, int column) const; // this method is inherited from NestedCollection, not from Collection<ESXRecordT> virtual NestableColumn *getNestableColumn(int column); void addAdapter(std::pair<const ColumnBase*, NestedColumnAdapter<ESXRecordT>* > adapter); }; template<typename ESXRecordT, typename IdAccessorT> NestedIdCollection<ESXRecordT, IdAccessorT>::NestedIdCollection () {} template<typename ESXRecordT, typename IdAccessorT> NestedIdCollection<ESXRecordT, IdAccessorT>::~NestedIdCollection() { for (typename std::map<const ColumnBase *, NestedColumnAdapter<ESXRecordT>* >::iterator iter (mAdapters.begin()); iter!=mAdapters.end(); ++iter) { delete (*iter).second; } } template<typename ESXRecordT, typename IdAccessorT> void NestedIdCollection<ESXRecordT, IdAccessorT>::addAdapter(std::pair<const ColumnBase*, NestedColumnAdapter<ESXRecordT>* > adapter) { mAdapters.insert(adapter); } template<typename ESXRecordT, typename IdAccessorT> const NestedColumnAdapter<ESXRecordT>& NestedIdCollection<ESXRecordT, IdAccessorT>::getAdapter(const ColumnBase &column) const { typename std::map<const ColumnBase *, NestedColumnAdapter<ESXRecordT>* >::const_iterator iter = mAdapters.find (&column); if (iter==mAdapters.end()) throw std::logic_error("No such column in the nestedidadapter"); return *iter->second; } template<typename ESXRecordT, typename IdAccessorT> void NestedIdCollection<ESXRecordT, IdAccessorT>::addNestedRow(int row, int column, int position) { Record<ESXRecordT> record; record.assign(Collection<ESXRecordT, IdAccessorT>::getRecord(row)); getAdapter(Collection<ESXRecordT, IdAccessorT>::getColumn(column)).addRow(record, position); Collection<ESXRecordT, IdAccessorT>::setRecord(row, record); } template<typename ESXRecordT, typename IdAccessorT> void NestedIdCollection<ESXRecordT, IdAccessorT>::removeNestedRows(int row, int column, int subRow) { Record<ESXRecordT> record; record.assign(Collection<ESXRecordT, IdAccessorT>::getRecord(row)); getAdapter(Collection<ESXRecordT, IdAccessorT>::getColumn(column)).removeRow(record, subRow); Collection<ESXRecordT, IdAccessorT>::setRecord(row, record); } template<typename ESXRecordT, typename IdAccessorT> QVariant NestedIdCollection<ESXRecordT, IdAccessorT>::getNestedData (int row, int column, int subRow, int subColumn) const { return getAdapter(Collection<ESXRecordT, IdAccessorT>::getColumn(column)).getData( Collection<ESXRecordT, IdAccessorT>::getRecord(row), subRow, subColumn); } template<typename ESXRecordT, typename IdAccessorT> void NestedIdCollection<ESXRecordT, IdAccessorT>::setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn) { Record<ESXRecordT> record; record.assign(Collection<ESXRecordT, IdAccessorT>::getRecord(row)); getAdapter(Collection<ESXRecordT, IdAccessorT>::getColumn(column)).setData( record, data, subRow, subColumn); Collection<ESXRecordT, IdAccessorT>::setRecord(row, record); } template<typename ESXRecordT, typename IdAccessorT> CSMWorld::NestedTableWrapperBase* NestedIdCollection<ESXRecordT, IdAccessorT>::nestedTable(int row, int column) const { return getAdapter(Collection<ESXRecordT, IdAccessorT>::getColumn(column)).table( Collection<ESXRecordT, IdAccessorT>::getRecord(row)); } template<typename ESXRecordT, typename IdAccessorT> void NestedIdCollection<ESXRecordT, IdAccessorT>::setNestedTable(int row, int column, const CSMWorld::NestedTableWrapperBase& nestedTable) { Record<ESXRecordT> record; record.assign(Collection<ESXRecordT, IdAccessorT>::getRecord(row)); getAdapter(Collection<ESXRecordT, IdAccessorT>::getColumn(column)).setTable( record, nestedTable); Collection<ESXRecordT, IdAccessorT>::setRecord(row, record); } template<typename ESXRecordT, typename IdAccessorT> int NestedIdCollection<ESXRecordT, IdAccessorT>::getNestedRowsCount(int row, int column) const { return getAdapter(Collection<ESXRecordT, IdAccessorT>::getColumn(column)).getRowsCount( Collection<ESXRecordT, IdAccessorT>::getRecord(row)); } template<typename ESXRecordT, typename IdAccessorT> int NestedIdCollection<ESXRecordT, IdAccessorT>::getNestedColumnsCount(int row, int column) const { const ColumnBase &nestedColumn = Collection<ESXRecordT, IdAccessorT>::getColumn(column); int numRecords = Collection<ESXRecordT, IdAccessorT>::getSize(); if (row >= 0 && row < numRecords) { const Record<ESXRecordT>& record = Collection<ESXRecordT, IdAccessorT>::getRecord(row); return getAdapter(nestedColumn).getColumnsCount(record); } else { // If the row is invalid (or there no records), retrieve the column count using a blank record const Record<ESXRecordT> record; return getAdapter(nestedColumn).getColumnsCount(record); } } template<typename ESXRecordT, typename IdAccessorT> CSMWorld::NestableColumn *NestedIdCollection<ESXRecordT, IdAccessorT>::getNestableColumn(int column) { return Collection<ESXRecordT, IdAccessorT>::getNestableColumn(column); } } #endif // CSM_WOLRD_NESTEDIDCOLLECTION_H