123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #include "EditorDefs.h"
- #include "ColumnSortProxyModel.h"
- // Editor
- #include "Util/AbstractSortModel.h"
- class ColumnSortProxyModelLessThan
- {
- public:
- inline ColumnSortProxyModelLessThan(int column, const AbstractSortModel* source)
- : sort_column(column)
- , source_model(source) {}
- inline bool operator()(int r1, int r2) const
- {
- QModelIndex i1 = source_model->index(r1, sort_column);
- QModelIndex i2 = source_model->index(r2, sort_column);
- return source_model->LessThan(i1, i2);
- }
- private:
- int sort_column;
- const AbstractSortModel* source_model;
- };
- class ColumnSortProxyModelGreaterThan
- {
- public:
- inline ColumnSortProxyModelGreaterThan(int column, const AbstractSortModel* source)
- : sort_column(column)
- , source_model(source) {}
- inline bool operator()(int r1, int r2) const
- {
- QModelIndex i1 = source_model->index(r1, sort_column);
- QModelIndex i2 = source_model->index(r2, sort_column);
- return source_model->LessThan(i2, i1);
- }
- private:
- int sort_column;
- const AbstractSortModel* source_model;
- };
- ColumnSortProxyModel::ColumnSortProxyModel(QObject* parent)
- : QAbstractProxyModel(parent)
- {
- }
- ColumnSortProxyModel::~ColumnSortProxyModel()
- {
- }
- QVariant ColumnSortProxyModel::data(const QModelIndex& index, int role) const
- {
- Q_ASSERT(index.isValid() && index.model() == this);
- return sourceModel()->data(mapToSource(index), role);
- }
- QVariant ColumnSortProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
- {
- return sourceModel()->headerData(section, orientation, role);
- }
- int ColumnSortProxyModel::rowCount(const QModelIndex& index) const
- {
- if (!sourceModel() || index.isValid())
- {
- return 0;
- }
- return sourceModel()->rowCount(index);
- }
- int ColumnSortProxyModel::columnCount(const QModelIndex& index) const
- {
- if (!sourceModel() || index.isValid())
- {
- return 0;
- }
- return sourceModel()->columnCount(index);
- }
- QModelIndex ColumnSortProxyModel::index(int row, int column, const QModelIndex& parent) const
- {
- Q_UNUSED(parent);
- Q_ASSERT(!parent.isValid());
- return createIndex(row, column);
- }
- QModelIndex ColumnSortProxyModel::parent(const QModelIndex& index) const
- {
- Q_UNUSED(index);
- return QModelIndex();
- }
- QModelIndex ColumnSortProxyModel::mapFromSource(const QModelIndex& sourceIndex) const
- {
- Q_ASSERT(!sourceIndex.isValid() || sourceIndex.model() == sourceModel());
- if (!sourceIndex.isValid())
- {
- return QModelIndex();
- }
- int row = m_mappingToSource.indexOf(sourceIndex.row());
- return createIndex(row, sourceIndex.column());
- }
- QModelIndex ColumnSortProxyModel::mapToSource(const QModelIndex& proxyIndex) const
- {
- Q_ASSERT(!proxyIndex.isValid() || proxyIndex.model() == this);
- if (!proxyIndex.isValid())
- {
- return QModelIndex();
- }
- int row = m_mappingToSource.at(proxyIndex.row());
- return sourceModel()->index(row, proxyIndex.column());
- }
- void ColumnSortProxyModel::setSourceModel(QAbstractItemModel* sourceModel)
- {
- Q_ASSERT(qobject_cast<AbstractSortModel*>(sourceModel));
- QAbstractProxyModel::setSourceModel(sourceModel);
- connect(sourceModel, &QAbstractItemModel::rowsInserted, this, &ColumnSortProxyModel::SortModel);
- connect(sourceModel, &QAbstractItemModel::rowsRemoved, this, &ColumnSortProxyModel::SortModel);
- connect(sourceModel, &QAbstractItemModel::modelAboutToBeReset, this, &ColumnSortProxyModel::beginResetModel);
- connect(sourceModel, &QAbstractItemModel::modelReset, this, [=]()
- {
- { QSignalBlocker sb(this);
- SortModel();
- } endResetModel();
- });
- connect(sourceModel, &QAbstractItemModel::layoutChanged, this, &ColumnSortProxyModel::SortModel);
- connect(sourceModel, &QAbstractItemModel::dataChanged, this, &ColumnSortProxyModel::SourceDataChanged);
- SortModel();
- }
- void ColumnSortProxyModel::sort(int column, Qt::SortOrder order)
- {
- int id = ColumnContains(column);
- if (id == -1)
- {
- AddColumn(column, order);
- }
- else
- {
- if (m_columns.at(id).sortOrder != order)
- {
- m_columns[id].sortOrder = order;
- SortModel();
- }
- }
- }
- void ColumnSortProxyModel::AddColumn(int column, Qt::SortOrder order)
- {
- if (ColumnContains(column) == -1)
- {
- m_columns.push_front({ column, order });
- SortModel();
- }
- }
- void ColumnSortProxyModel::AddColumnWithoutSorting(int column, Qt::SortOrder order)
- {
- if (ColumnContains(column) == -1)
- {
- m_columns.push_front({ column, order });
- }
- }
- void ColumnSortProxyModel::RemoveColumn(int column)
- {
- int id = ColumnContains(column);
- if (id != -1)
- {
- m_columns.remove(id);
- SortModel();
- }
- }
- void ColumnSortProxyModel::RemoveColumnWithoutSorting(int column)
- {
- int id = ColumnContains(column);
- if (id != -1)
- {
- m_columns.remove(id);
- }
- }
- void ColumnSortProxyModel::SetColumns(const QVector<int>& columns)
- {
- m_columns.clear();
- foreach(int col, columns)
- {
- m_columns.push_back({ col, Qt::AscendingOrder });
- }
- SortModel();
- }
- void ColumnSortProxyModel::ClearColumns()
- {
- SortModel();
- }
- bool ColumnSortProxyModel::IsColumnSorted(int col) const
- {
- int id = ColumnContains(col);
- return (id != -1);
- }
- Qt::SortOrder ColumnSortProxyModel::SortOrder(int col) const
- {
- int id = ColumnContains(col);
- if (id != -1)
- {
- return m_columns.at(id).sortOrder;
- }
- return Qt::AscendingOrder;
- }
- void ColumnSortProxyModel::SortModel()
- {
- emit layoutAboutToBeChanged();
- int size = sourceModel() ? sourceModel()->rowCount() : 0;
- m_mappingToSource.resize(size);
- for (int i = 0; i < size; ++i)
- {
- m_mappingToSource[i] = i;
- }
- foreach(Column col, m_columns)
- {
- if (col.sortOrder == Qt::AscendingOrder)
- {
- ColumnSortProxyModelLessThan lt(col.column, qobject_cast<AbstractSortModel*>(sourceModel()));
- std::stable_sort(m_mappingToSource.begin(), m_mappingToSource.end(), lt);
- }
- else
- {
- ColumnSortProxyModelGreaterThan gt(col.column, qobject_cast<AbstractSortModel*>(sourceModel()));
- std::stable_sort(m_mappingToSource.begin(), m_mappingToSource.end(), gt);
- }
- }
- emit layoutChanged();
- emit SortChanged();
- }
- void ColumnSortProxyModel::SourceDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight)
- {
- for (int col = topLeft.column(); col <= bottomRight.column(); ++col)
- {
- if (ColumnContains(col) != -1)
- {
- SortModel();
- return;
- }
- }
- }
- int ColumnSortProxyModel::ColumnContains(int col) const
- {
- for (int i = 0; i < m_columns.count(); ++i)
- {
- if (m_columns.at(i).column == col)
- {
- return i;
- }
- }
- return -1;
- }
- #include <Util/moc_ColumnSortProxyModel.cpp>
|