5#include <QtQmlModels/private/qqmlsortercompositor_p.h>
6#include <QtQmlModels/private/qqmlsortfilterproxymodel_p_p.h>
7#include <QtQmlModels/private/qqmlsortfilterproxymodel_p.h>
11QQmlSorterCompositor::QQmlSorterCompositor(QObject *parent)
12 : QQmlSorterBase(
new QQmlSorterCompositorPrivate, parent)
14 Q_D(QQmlSorterCompositor);
19 connect(d->m_sfpmModel, &QQmlSortFilterProxyModel::modelReset,
20 this, &QQmlSorterCompositor::updateSorters);
21 connect(d->m_sfpmModel, &QQmlSortFilterProxyModel::primarySorterChanged,
22 this, &QQmlSorterCompositor::updateEffectiveSorters);
25QQmlSorterCompositor::~QQmlSorterCompositor()
30void QQmlSorterCompositorPrivate::init()
32 Q_Q(QQmlSorterCompositor);
33 m_sfpmModel = qobject_cast<QQmlSortFilterProxyModel *>(q->parent());
36void QQmlSorterCompositor::append(QQmlListProperty<QQmlSorterBase> *sorterComp, QQmlSorterBase* sorter)
38 auto *sorterCompositor =
reinterpret_cast<QQmlSorterCompositor *>(sorterComp->object);
39 sorterCompositor->append(sorter);
42qsizetype QQmlSorterCompositor::count(QQmlListProperty<QQmlSorterBase> *sorterComp)
44 auto *sorterCompositor =
reinterpret_cast<QQmlSorterCompositor *> (sorterComp->object);
45 return sorterCompositor->count();
48QQmlSorterBase *QQmlSorterCompositor::at(QQmlListProperty<QQmlSorterBase> *sorterComp, qsizetype index)
50 auto *sorterCompositor =
reinterpret_cast<QQmlSorterCompositor *> (sorterComp->object);
51 return sorterCompositor->at(index);
54void QQmlSorterCompositor::clear(QQmlListProperty<QQmlSorterBase> *sorterComp)
56 auto *sorterCompositor =
reinterpret_cast<QQmlSorterCompositor *> (sorterComp->object);
57 sorterCompositor->clear();
60void QQmlSorterCompositor::append(QQmlSorterBase *sorter)
64 Q_D(QQmlSorterCompositor);
65 d->m_sorters.append(sorter);
70 QObject::connect(sorter, &QQmlSorterBase::invalidateModel,
71 d->m_sfpmModel, &QQmlSortFilterProxyModel::invalidate);
75 QObject::connect(sorter, &QQmlSorterBase::invalidateCache,
76 this, &QQmlSorterCompositor::updateCache);
79 QObject::connect(sorter, &QQmlSorterBase::sortOrderChanged,
80 this, [d] { d->resetPrimarySorter(); });
81 QObject::connect(sorter, &QQmlSorterBase::columnChanged,
82 this, [d] { d->resetPrimarySorter(); });
85 emit d->m_sfpmModel->sortersChanged();
88qsizetype QQmlSorterCompositor::count()
90 Q_D(QQmlSorterCompositor);
91 return d->m_sorters.count();
94QQmlSorterBase* QQmlSorterCompositor::at(qsizetype index)
96 Q_D(QQmlSorterCompositor);
97 return d->m_sorters.at(index);
100void QQmlSorterCompositor::clear()
102 Q_D(QQmlSorterCompositor);
103 d->m_effectiveSorters.clear();
104 d->m_sorters.clear();
106 emit d->m_sfpmModel->sortersChanged();
109QList<QQmlSorterBase *> QQmlSorterCompositor::sorters()
111 Q_D(QQmlSorterCompositor);
115QQmlListProperty<QQmlSorterBase> QQmlSorterCompositor::sortersListProperty()
117 Q_D(QQmlSorterCompositor);
118 return QQmlListProperty<QQmlSorterBase>(
reinterpret_cast<QObject*>(
this), &d->m_sorters,
119 QQmlSorterCompositor::append,
120 QQmlSorterCompositor::count,
121 QQmlSorterCompositor::at,
122 QQmlSorterCompositor::clear);
125void QQmlSorterCompositor::updateEffectiveSorters()
127 Q_D(QQmlSorterCompositor);
129 if (!d->m_primarySorter || !d->m_primarySorter->enabled()) {
134 QList<QQmlSorterBase *> sorters;
135 sorters.append(d->m_primarySorter);
136 std::copy_if(d->m_effectiveSorters.constBegin(), d->m_effectiveSorters.constEnd(),
137 std::back_inserter(sorters), [d](QQmlSorterBase *sorter){
140 return (sorter != d->m_primarySorter);
142 d->m_effectiveSorters = sorters;
145void QQmlSorterCompositor::updateSorters()
147 Q_D(QQmlSorterCompositor);
150 for (
auto &sorter: d->m_sorters)
151 sorter->update(d->m_sfpmModel);
155void QQmlSorterCompositor::updateCache()
157 Q_D(QQmlSorterCompositor);
159 d->m_effectiveSorters.clear();
160 if (d->m_sfpmModel && d->m_sfpmModel->sourceModel()) {
162 QList<QQmlSorterBase *> sorters = d->m_sorters;
163 std::stable_sort(sorters.begin(), sorters.end(),
164 [](QQmlSorterBase *sorterLeft, QQmlSorterBase *sorterRight) {
165 return sorterLeft->priority() < sorterRight->priority();
168 std::copy_if(sorters.begin(), sorters.end(), std::back_inserter(d->m_effectiveSorters),
169 [](QQmlSorterBase *sorter) {
return sorter->enabled(); });
172 d->resetPrimarySorter();
176bool QQmlSorterCompositor::lessThan(
const QModelIndex& sourceLeft,
const QModelIndex& sourceRight,
const QQmlSortFilterProxyModel *proxyModel)
const
178 Q_D(
const QQmlSorterCompositor);
179 for (
const auto &sorter : d->m_effectiveSorters) {
180 const int sortSection = sorter->column();
181 if ((sortSection > -1) && (sortSection < proxyModel->sourceModel()->columnCount())) {
182 const auto *sourceModel = proxyModel->sourceModel();
183 const QPartialOrdering result = sorter->compare(sourceModel->index(sourceLeft.row(), sortSection),
184 sourceModel->index(sourceRight.row(), sortSection),
186 if (result == QPartialOrdering::Less || result == QPartialOrdering::Greater) {
187 auto *priv =
static_cast<
const QQmlSortFilterProxyModelPrivate *>(QQmlSortFilterProxyModelPrivate::get(proxyModel));
188 return (priv->m_sortOrder == sorter->sortOrder()) ? result < 0 : result > 0;
193 return sourceLeft.row() < sourceRight.row();
196void QQmlSorterCompositorPrivate::setPrimarySorter(QQmlSorterBase *sorter)
198 if (sorter ==
nullptr ||
199 (std::find(m_sorters.constBegin(), m_sorters.constEnd(), sorter) != m_sorters.constEnd())) {
200 m_primarySorter = sorter;
201 if (m_primarySorter && m_primarySorter->enabled()) {
202 m_sfpmModel->setPrimarySortOrder(m_primarySorter->sortOrder());
203 m_sfpmModel->setPrimarySortColumn(m_primarySorter->column());
207 resetPrimarySorter();
210void QQmlSorterCompositorPrivate::resetPrimarySorter()
212 if (!m_primarySorter) {
213 if (!m_effectiveSorters.isEmpty()) {
215 const auto *sorter = m_effectiveSorters.at(0);
216 m_sfpmModel->setPrimarySortOrder(sorter->sortOrder());
217 m_sfpmModel->setPrimarySortColumn(sorter->column());
221 m_sfpmModel->setPrimarySortOrder(Qt::AscendingOrder);
222 m_sfpmModel->setPrimarySortColumn(0);
229#include "moc_qqmlsortercompositor_p.cpp"