You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openmw/apps/opencs/model/world/nestedtableproxymodel.cpp

188 lines
5.8 KiB
C++

#include "nestedtableproxymodel.hpp"
#include "idtree.hpp"
#include <cassert>
#include <apps/opencs/model/world/columnbase.hpp>
CSMWorld::NestedTableProxyModel::NestedTableProxyModel(
const QModelIndex& parent, ColumnBase::Display columnId, CSMWorld::IdTree* parentModel)
: mParentColumn(parent.column())
, mMainModel(parentModel)
{
const int parentRow = parent.row();
mId = std::string(parentModel->index(parentRow, 0).data().toString().toUtf8());
QAbstractProxyModel::setSourceModel(parentModel);
connect(mMainModel, &IdTree::rowsAboutToBeInserted, this, &NestedTableProxyModel::forwardRowsAboutToInserted);
connect(mMainModel, &IdTree::rowsInserted, this, &NestedTableProxyModel::forwardRowsInserted);
connect(mMainModel, &IdTree::rowsAboutToBeRemoved, this, &NestedTableProxyModel::forwardRowsAboutToRemoved);
connect(mMainModel, &IdTree::rowsRemoved, this, &NestedTableProxyModel::forwardRowsRemoved);
connect(mMainModel, &IdTree::resetStart, this, &NestedTableProxyModel::forwardResetStart);
connect(mMainModel, &IdTree::resetEnd, this, &NestedTableProxyModel::forwardResetEnd);
connect(mMainModel, &IdTree::dataChanged, this, &NestedTableProxyModel::forwardDataChanged);
}
QModelIndex CSMWorld::NestedTableProxyModel::mapFromSource(const QModelIndex& sourceIndex) const
{
const QModelIndex& testedParent = mMainModel->parent(sourceIndex);
const QModelIndex& parent = mMainModel->getNestedModelIndex(mId, mParentColumn);
if (testedParent == parent)
{
return createIndex(sourceIndex.row(), sourceIndex.column());
}
else
{
return QModelIndex();
}
}
QModelIndex CSMWorld::NestedTableProxyModel::mapToSource(const QModelIndex& proxyIndex) const
{
const QModelIndex& parent = mMainModel->getNestedModelIndex(mId, mParentColumn);
return mMainModel->index(proxyIndex.row(), proxyIndex.column(), parent);
}
int CSMWorld::NestedTableProxyModel::rowCount(const QModelIndex& index) const
{
assert(!index.isValid());
return mMainModel->rowCount(mMainModel->getModelIndex(mId, mParentColumn));
}
int CSMWorld::NestedTableProxyModel::columnCount(const QModelIndex& parent) const
{
assert(!parent.isValid());
return mMainModel->columnCount(mMainModel->getModelIndex(mId, mParentColumn));
}
QModelIndex CSMWorld::NestedTableProxyModel::index(int row, int column, const QModelIndex& parent) const
{
assert(!parent.isValid());
int numRows = rowCount(parent);
int numColumns = columnCount(parent);
if (row < 0 || row >= numRows || column < 0 || column >= numColumns)
return QModelIndex();
return createIndex(row, column);
}
QModelIndex CSMWorld::NestedTableProxyModel::parent(const QModelIndex& index) const
{
return QModelIndex();
}
QVariant CSMWorld::NestedTableProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
{
return mMainModel->nestedHeaderData(mParentColumn, section, orientation, role);
}
QVariant CSMWorld::NestedTableProxyModel::data(const QModelIndex& index, int role) const
{
return mMainModel->data(mapToSource(index), role);
}
// NOTE: Due to mapToSouce(index) the dataChanged() signal resulting from setData() will have the
// source model's index values. The indicies need to be converted to the proxy space values.
// See forwardDataChanged()
bool CSMWorld::NestedTableProxyModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
return mMainModel->setData(mapToSource(index), value, role);
}
Qt::ItemFlags CSMWorld::NestedTableProxyModel::flags(const QModelIndex& index) const
{
return mMainModel->flags(mapToSource(index));
}
std::string CSMWorld::NestedTableProxyModel::getParentId() const
{
return mId;
}
int CSMWorld::NestedTableProxyModel::getParentColumn() const
{
return mParentColumn;
}
CSMWorld::IdTree* CSMWorld::NestedTableProxyModel::model() const
{
return mMainModel;
}
void CSMWorld::NestedTableProxyModel::forwardRowsAboutToInserted(const QModelIndex& parent, int first, int last)
{
if (indexIsParent(parent))
{
beginInsertRows(QModelIndex(), first, last);
}
}
void CSMWorld::NestedTableProxyModel::forwardRowsInserted(const QModelIndex& parent, int first, int last)
{
if (indexIsParent(parent))
{
endInsertRows();
}
}
bool CSMWorld::NestedTableProxyModel::indexIsParent(const QModelIndex& index)
{
return (index.isValid() && index.column() == mParentColumn
&& mMainModel->data(mMainModel->index(index.row(), 0)).toString().toUtf8().constData() == mId);
}
void CSMWorld::NestedTableProxyModel::forwardRowsAboutToRemoved(const QModelIndex& parent, int first, int last)
{
if (indexIsParent(parent))
{
beginRemoveRows(QModelIndex(), first, last);
}
}
void CSMWorld::NestedTableProxyModel::forwardRowsRemoved(const QModelIndex& parent, int first, int last)
{
if (indexIsParent(parent))
{
endRemoveRows();
}
}
void CSMWorld::NestedTableProxyModel::forwardResetStart(const QString& id)
{
if (id.toUtf8() == mId.c_str())
beginResetModel();
}
void CSMWorld::NestedTableProxyModel::forwardResetEnd(const QString& id)
{
if (id.toUtf8() == mId.c_str())
endResetModel();
}
void CSMWorld::NestedTableProxyModel::forwardDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight)
{
const QModelIndex& parent = mMainModel->getNestedModelIndex(mId, mParentColumn);
if (topLeft.column() <= parent.column() && bottomRight.column() >= parent.column())
{
emit dataChanged(index(0, 0), index(mMainModel->rowCount(parent) - 1, mMainModel->columnCount(parent) - 1));
}
else if (topLeft.parent() == parent && bottomRight.parent() == parent)
{
emit dataChanged(index(topLeft.row(), topLeft.column()), index(bottomRight.row(), bottomRight.column()));
}
}