diff --git a/apps/opencs/model/world/idtableproxymodel.cpp b/apps/opencs/model/world/idtableproxymodel.cpp index 516644713..ce9d44ed6 100644 --- a/apps/opencs/model/world/idtableproxymodel.cpp +++ b/apps/opencs/model/world/idtableproxymodel.cpp @@ -50,6 +50,24 @@ QModelIndex CSMWorld::IdTableProxyModel::getModelIndex (const std::string& id, i return mapFromSource (dynamic_cast (*sourceModel()).getModelIndex (id, column)); } +void CSMWorld::IdTableProxyModel::setSourceModel(QAbstractItemModel *model) +{ + QSortFilterProxyModel::setSourceModel(model); + + connect(sourceModel(), + SIGNAL(rowsRemoved(const QModelIndex &, int, int)), + this, + SLOT(sourceRowsChanged(const QModelIndex &, int, int))); + connect(sourceModel(), + SIGNAL(rowsInserted(const QModelIndex &, int, int)), + this, + SLOT(sourceRowsChanged(const QModelIndex &, int, int))); + connect(sourceModel(), + SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), + this, + SLOT(sourceDataChanged(const QModelIndex &, const QModelIndex &))); +} + void CSMWorld::IdTableProxyModel::setFilter (const boost::shared_ptr& filter) { beginResetModel(); @@ -60,6 +78,20 @@ void CSMWorld::IdTableProxyModel::setFilter (const boost::shared_ptr(left.data(ColumnBase::Role_ColumnId).toInt()); + EnumColumnCache::const_iterator valuesIt = mEnumColumnCache.find(id); + if (valuesIt == mEnumColumnCache.end()) + { + if (Columns::hasEnums(id)) + { + valuesIt = mEnumColumnCache.insert(std::make_pair(id, Columns::getEnums(id))).first; + } + } + + if (valuesIt != mEnumColumnCache.end()) + { + return valuesIt->second[left.data().toInt()] < valuesIt->second[right.data().toInt()]; + } return QSortFilterProxyModel::lessThan(left, right); } @@ -68,3 +100,13 @@ void CSMWorld::IdTableProxyModel::refreshFilter() updateColumnMap(); invalidateFilter(); } + +void CSMWorld::IdTableProxyModel::sourceRowsChanged(const QModelIndex &/*parent*/, int /*start*/, int /*end*/) +{ + refreshFilter(); +} + +void CSMWorld::IdTableProxyModel::sourceDataChanged(const QModelIndex &/*topLeft*/, const QModelIndex &/*bottomRight*/) +{ + refreshFilter(); +} diff --git a/apps/opencs/model/world/idtableproxymodel.hpp b/apps/opencs/model/world/idtableproxymodel.hpp index d2a240529..17c30361a 100644 --- a/apps/opencs/model/world/idtableproxymodel.hpp +++ b/apps/opencs/model/world/idtableproxymodel.hpp @@ -11,6 +11,8 @@ #include "../filter/node.hpp" +#include "columns.hpp" + namespace CSMWorld { class IdTableProxyModel : public QSortFilterProxyModel @@ -20,6 +22,11 @@ namespace CSMWorld boost::shared_ptr mFilter; std::map mColumnMap; // column ID, column index in this model (or -1) + // Cache of enum values for enum columns (e.g. Modified, Record Type). + // Used to speed up comparisons during the sort by such columns. + typedef std::map > EnumColumnCache; + mutable EnumColumnCache mEnumColumnCache; + private: void updateColumnMap(); @@ -30,6 +37,8 @@ namespace CSMWorld virtual QModelIndex getModelIndex (const std::string& id, int column) const; + virtual void setSourceModel(QAbstractItemModel *model); + void setFilter (const boost::shared_ptr& filter); void refreshFilter(); @@ -39,6 +48,12 @@ namespace CSMWorld bool lessThan(const QModelIndex &left, const QModelIndex &right) const; virtual bool filterAcceptsRow (int sourceRow, const QModelIndex& sourceParent) const; + + private slots: + + void sourceRowsChanged(const QModelIndex &parent, int start, int end); + + void sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); }; } diff --git a/apps/opencs/view/world/table.cpp b/apps/opencs/view/world/table.cpp index 74343a5f6..5a2a572e2 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -653,10 +653,6 @@ void CSVWorld::Table::tableSizeUpdate() } emit tableSizeChanged (size, deleted, modified); - - // not really related to tableSizeUpdate() but placed here for convenience rather than - // creating a bunch of extra connections & slot - mProxyModel->refreshFilter(); } void CSVWorld::Table::selectionSizeUpdate()