basic (non-editable) subview for global variables
parent
1dd63e9fb6
commit
ef9575498f
@ -0,0 +1,21 @@
|
||||
#ifndef CSM_WOLRD_COLUMNS_H
|
||||
#define CSM_WOLRD_COLUMNS_H
|
||||
|
||||
#include "idcollection.hpp"
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
template<typename ESXRecordT>
|
||||
struct FloatValueColumn : public Column<ESXRecordT>
|
||||
{
|
||||
FloatValueColumn() : Column<ESXRecordT> ("Value") {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
return record.get().mValue;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,47 @@
|
||||
|
||||
#include "data.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
|
||||
#include <components/esm/loadglob.hpp>
|
||||
|
||||
#include "idtable.hpp"
|
||||
#include "columns.hpp"
|
||||
|
||||
CSMWorld::Data::Data()
|
||||
{
|
||||
mGlobals.addColumn (new FloatValueColumn<ESM::Global>);
|
||||
|
||||
mModels.insert (std::make_pair (
|
||||
UniversalId (UniversalId::Type_Globals),
|
||||
new IdTable (&mGlobals)
|
||||
));
|
||||
}
|
||||
|
||||
CSMWorld::Data::~Data()
|
||||
{
|
||||
for (std::map<UniversalId, QAbstractTableModel *>::iterator iter (mModels.begin()); iter!=mModels.end(); ++iter)
|
||||
delete iter->second;
|
||||
}
|
||||
|
||||
const CSMWorld::IdCollection<ESM::Global>& CSMWorld::Data::getGlobals() const
|
||||
{
|
||||
return mGlobals;
|
||||
}
|
||||
|
||||
CSMWorld::IdCollection<ESM::Global>& CSMWorld::Data::getGlobals()
|
||||
{
|
||||
return mGlobals;
|
||||
}
|
||||
|
||||
QAbstractTableModel *CSMWorld::Data::getTableModel (const UniversalId& id)
|
||||
{
|
||||
std::map<UniversalId, QAbstractTableModel *>::iterator iter = mModels.find (id);
|
||||
|
||||
if (iter==mModels.end())
|
||||
throw std::logic_error ("No table model available for " + id.toString());
|
||||
|
||||
return iter->second;
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
#ifndef CSM_WOLRD_IDLIST_H
|
||||
#define CSM_WOLRD_IDLIST_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <components/esm/loadglob.hpp>
|
||||
|
||||
#include "idcollection.hpp"
|
||||
#include "universalid.hpp"
|
||||
|
||||
class QAbstractTableModel;
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class Data
|
||||
{
|
||||
IdCollection<ESM::Global> mGlobals;
|
||||
std::map<UniversalId, QAbstractTableModel *> mModels;
|
||||
|
||||
// not implemented
|
||||
Data (const Data&);
|
||||
Data& operator= (const Data&);
|
||||
|
||||
public:
|
||||
|
||||
Data();
|
||||
|
||||
~Data();
|
||||
|
||||
const IdCollection<ESM::Global>& getGlobals() const;
|
||||
|
||||
IdCollection<ESM::Global>& getGlobals();
|
||||
|
||||
QAbstractTableModel *getTableModel (const UniversalId& id);
|
||||
///< If no table model is available for \æ id, an exception is thrown.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,6 @@
|
||||
|
||||
#include "idcollection.hpp"
|
||||
|
||||
CSMWorld::IdCollectionBase::IdCollectionBase() {}
|
||||
|
||||
CSMWorld::IdCollectionBase::~IdCollectionBase() {}
|
@ -0,0 +1,158 @@
|
||||
#ifndef CSM_WOLRD_IDCOLLECTION_H
|
||||
#define CSM_WOLRD_IDCOLLECTION_H
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
#include "record.hpp"
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
template<typename ESXRecordT>
|
||||
struct Column
|
||||
{
|
||||
std::string mTitle;
|
||||
|
||||
Column (const std::string& title) : mTitle (title) {}
|
||||
|
||||
virtual ~Column() {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const = 0;
|
||||
};
|
||||
|
||||
class IdCollectionBase
|
||||
{
|
||||
// not implemented
|
||||
IdCollectionBase (const IdCollectionBase&);
|
||||
IdCollectionBase& operator= (const IdCollectionBase&);
|
||||
|
||||
public:
|
||||
|
||||
IdCollectionBase();
|
||||
|
||||
virtual ~IdCollectionBase();
|
||||
|
||||
virtual int getSize() const = 0;
|
||||
|
||||
virtual std::string getId (int index) const = 0;
|
||||
|
||||
virtual int getColumns() const = 0;
|
||||
|
||||
virtual std::string getTitle (int column) const = 0;
|
||||
|
||||
virtual QVariant getData (int index, int column) const = 0;
|
||||
};
|
||||
|
||||
///< \brief Collection of ID-based records
|
||||
template<typename ESXRecordT>
|
||||
class IdCollection : public IdCollectionBase
|
||||
{
|
||||
std::vector<Record<ESXRecordT> > mRecords;
|
||||
std::map<std::string, int> mIndex;
|
||||
std::vector<Column<ESXRecordT> *> mColumns;
|
||||
|
||||
// not implemented
|
||||
IdCollection (const IdCollection&);
|
||||
IdCollection& operator= (const IdCollection&);
|
||||
|
||||
public:
|
||||
|
||||
IdCollection();
|
||||
|
||||
virtual ~IdCollection();
|
||||
|
||||
void add (const ESXRecordT& record);
|
||||
///< Add a new record (modified)
|
||||
|
||||
virtual int getSize() const;
|
||||
|
||||
virtual std::string getId (int index) const;
|
||||
|
||||
virtual int getColumns() const;
|
||||
|
||||
virtual QVariant getData (int index, int column) const;
|
||||
|
||||
virtual std::string getTitle (int column) const;
|
||||
|
||||
virtual void addColumn (Column<ESXRecordT> *column);
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
IdCollection<ESXRecordT>::IdCollection()
|
||||
{}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
IdCollection<ESXRecordT>::~IdCollection()
|
||||
{
|
||||
for (typename std::vector<Column<ESXRecordT> *>::iterator iter (mColumns.begin()); iter!=mColumns.end(); ++iter)
|
||||
delete *iter;
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
void IdCollection<ESXRecordT>::add (const ESXRecordT& record)
|
||||
{
|
||||
std::string id;
|
||||
|
||||
std::transform (record.mId.begin(), record.mId.end(), std::back_inserter (id),
|
||||
(int(*)(int)) std::tolower);
|
||||
|
||||
std::map<std::string, int>::iterator iter = mIndex.find (id);
|
||||
|
||||
if (iter==mIndex.end())
|
||||
{
|
||||
Record<ESXRecordT> record2;
|
||||
record2.mState = Record<ESXRecordT>::State_ModifiedOnly;
|
||||
record2.mModified = record;
|
||||
|
||||
mRecords.push_back (record2);
|
||||
mIndex.insert (std::make_pair (id, mRecords.size()-1));
|
||||
}
|
||||
else
|
||||
{
|
||||
mRecords[iter->second].setModified (record);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
int IdCollection<ESXRecordT>::getSize() const
|
||||
{
|
||||
return mRecords.size();
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
std::string IdCollection<ESXRecordT>::getId (int index) const
|
||||
{
|
||||
return mRecords.at (index).get().mId;
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
int IdCollection<ESXRecordT>::getColumns() const
|
||||
{
|
||||
return mColumns.size();
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
QVariant IdCollection<ESXRecordT>::getData (int index, int column) const
|
||||
{
|
||||
return mColumns.at (column)->get (mRecords.at (index));
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
std::string IdCollection<ESXRecordT>::getTitle (int column) const
|
||||
{
|
||||
return mColumns.at (column)->mTitle;
|
||||
}
|
||||
|
||||
template<typename ESXRecordT>
|
||||
void IdCollection<ESXRecordT>::addColumn (Column<ESXRecordT> *column)
|
||||
{
|
||||
mColumns.push_back (column);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,55 @@
|
||||
|
||||
#include "idtable.hpp"
|
||||
|
||||
#include "idcollection.hpp"
|
||||
|
||||
CSMWorld::IdTable::IdTable (IdCollectionBase *idCollection) : mIdCollection (idCollection)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CSMWorld::IdTable::~IdTable()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int CSMWorld::IdTable::rowCount (const QModelIndex & parent) const
|
||||
{
|
||||
if (parent.isValid())
|
||||
return 0;
|
||||
|
||||
return mIdCollection->getSize();
|
||||
}
|
||||
|
||||
int CSMWorld::IdTable::columnCount (const QModelIndex & parent) const
|
||||
{
|
||||
if (parent.isValid())
|
||||
return 0;
|
||||
|
||||
return 1+mIdCollection->getColumns();
|
||||
}
|
||||
|
||||
QVariant CSMWorld::IdTable::data (const QModelIndex & index, int role) const
|
||||
{
|
||||
if (role!=Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
if (index.column()==0)
|
||||
return QVariant (tr (mIdCollection->getId (index.row()).c_str()));
|
||||
|
||||
return mIdCollection->getData (index.row(), index.column()-1);
|
||||
}
|
||||
|
||||
QVariant CSMWorld::IdTable::headerData (int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (role!=Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
if (orientation==Qt::Vertical)
|
||||
return QVariant();
|
||||
|
||||
if (section==0)
|
||||
return QVariant (tr ("ID"));
|
||||
|
||||
return tr (mIdCollection->getTitle (section-1).c_str());
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
#ifndef CSM_WOLRD_IDTABLE_H
|
||||
#define CSM_WOLRD_IDTABLE_H
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class IdCollectionBase;
|
||||
|
||||
class IdTable : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
IdCollectionBase *mIdCollection;
|
||||
|
||||
// not implemented
|
||||
IdTable (const IdTable&);
|
||||
IdTable& operator= (const IdTable&);
|
||||
|
||||
public:
|
||||
|
||||
IdTable (IdCollectionBase *idCollection);
|
||||
///< The ownership of \a idCollection is not transferred.
|
||||
|
||||
virtual ~IdTable();
|
||||
|
||||
int rowCount (const QModelIndex & parent = QModelIndex()) const;
|
||||
|
||||
int columnCount (const QModelIndex & parent = QModelIndex()) const;
|
||||
|
||||
QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const;
|
||||
|
||||
QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,76 @@
|
||||
#ifndef CSM_WOLRD_RECORD_H
|
||||
#define CSM_WOLRD_RECORD_H
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
template <typename ESXRecordT>
|
||||
struct Record
|
||||
{
|
||||
enum state
|
||||
{
|
||||
State_BaseOnly, // defined in base only
|
||||
State_Modified, // exists in base, but has been modified
|
||||
State_ModifiedOnly, // newly created in modified
|
||||
State_Deleted // exists in base, but has been deleted
|
||||
};
|
||||
|
||||
ESXRecordT mBase;
|
||||
ESXRecordT mModified;
|
||||
state mState;
|
||||
|
||||
bool isDeleted() const;
|
||||
|
||||
bool isModified() const;
|
||||
|
||||
const ESXRecordT& get() const;
|
||||
///< Throws an exception, if the record is deleted.
|
||||
|
||||
ESXRecordT& get();
|
||||
///< Throws an exception, if the record is deleted.
|
||||
|
||||
void setModified (const ESXRecordT& modified);
|
||||
};
|
||||
|
||||
template <typename ESXRecordT>
|
||||
bool Record<ESXRecordT>::isDeleted() const
|
||||
{
|
||||
return mState==State_Deleted;
|
||||
}
|
||||
|
||||
template <typename ESXRecordT>
|
||||
bool Record<ESXRecordT>::isModified() const
|
||||
{
|
||||
return mState==State_Modified || mState==State_ModifiedOnly;
|
||||
}
|
||||
|
||||
template <typename ESXRecordT>
|
||||
const ESXRecordT& Record<ESXRecordT>::get() const
|
||||
{
|
||||
if (isDeleted())
|
||||
throw std::logic_error ("attempt to access a deleted record");
|
||||
|
||||
return mState==State_BaseOnly ? mBase : mModified;
|
||||
}
|
||||
|
||||
template <typename ESXRecordT>
|
||||
ESXRecordT& Record<ESXRecordT>::get()
|
||||
{
|
||||
if (isDeleted())
|
||||
throw std::logic_error ("attempt to access a deleted record");
|
||||
|
||||
return mState==State_BaseOnly ? mBase : mModified;
|
||||
}
|
||||
|
||||
template <typename ESXRecordT>
|
||||
void Record<ESXRecordT>::setModified (const ESXRecordT& modified)
|
||||
{
|
||||
mModified = modified;
|
||||
|
||||
if (mState!=State_ModifiedOnly)
|
||||
mState = State_Modified;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,26 @@
|
||||
|
||||
#include "globals.hpp"
|
||||
|
||||
#include <QTableView>
|
||||
#include <QHeaderView>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
#include "../../model/world/data.hpp"
|
||||
|
||||
CSVWorld::Globals::Globals (const CSMWorld::UniversalId& id, CSMWorld::Data& data)
|
||||
: SubView (id)
|
||||
{
|
||||
QTableView *table = new QTableView();
|
||||
|
||||
setWidget (table);
|
||||
|
||||
QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel (this);
|
||||
proxyModel->setSourceModel (data.getTableModel (id));
|
||||
|
||||
table->setModel (proxyModel);
|
||||
table->horizontalHeader()->setResizeMode (QHeaderView::Interactive);
|
||||
table->verticalHeader()->hide();
|
||||
table->setSortingEnabled (true);
|
||||
|
||||
/// \todo make initial layout fill the whole width of the table
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
#ifndef CSV_WORLD_GLOBALS_H
|
||||
#define CSV_WORLD_GLOBALS_H
|
||||
|
||||
#include "subview.hpp"
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class Globals : public SubView
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
Globals (const CSMWorld::UniversalId& id, CSMWorld::Data& data);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue