4#include <QtQmlModels/private/qqmlsortercompositor_p.h>
5#include <QtQmlModels/private/qqmlsortfilterproxymodel_p_p.h>
6#include <QtQmlModels/private/qqmlsortfilterproxymodel_p.h>
10QQmlSorterCompositor::QQmlSorterCompositor(QObject *parent)
11 : QQmlSorterBase(
new QQmlSorterCompositorPrivate, parent)
13 Q_D(QQmlSorterCompositor);
18 connect(d->m_sfpmModel, &QQmlSortFilterProxyModel::modelReset,
19 this, &QQmlSorterCompositor::updateSorters);
20 connect(d->m_sfpmModel, &QQmlSortFilterProxyModel::primarySorterChanged,
21 this, &QQmlSorterCompositor::updateEffectiveSorters);
24QQmlSorterCompositor::~QQmlSorterCompositor()
29void QQmlSorterCompositorPrivate::init()
31 Q_Q(QQmlSorterCompositor);
32 m_sfpmModel = qobject_cast<QQmlSortFilterProxyModel *>(q->parent());
35void QQmlSorterCompositor::append(QQmlListProperty<QQmlSorterBase> *sorterComp, QQmlSorterBase* sorter)
37 auto *sorterCompositor =
reinterpret_cast<QQmlSorterCompositor *>(sorterComp->object);
38 sorterCompositor->append(sorter);
41qsizetype QQmlSorterCompositor::count(QQmlListProperty<QQmlSorterBase> *sorterComp)
43 auto *sorterCompositor =
reinterpret_cast<QQmlSorterCompositor *> (sorterComp->object);
44 return sorterCompositor->count();
47QQmlSorterBase *QQmlSorterCompositor::at(QQmlListProperty<QQmlSorterBase> *sorterComp, qsizetype index)
49 auto *sorterCompositor =
reinterpret_cast<QQmlSorterCompositor *> (sorterComp->object);
50 return sorterCompositor->at(index);
53void QQmlSorterCompositor::clear(QQmlListProperty<QQmlSorterBase> *sorterComp)
55 auto *sorterCompositor =
reinterpret_cast<QQmlSorterCompositor *> (sorterComp->object);
56 sorterCompositor->clear();
59void QQmlSorterCompositor::append(QQmlSorterBase *sorter)
63 Q_D(QQmlSorterCompositor);
64 d->m_sorters.append(sorter);
69 QObject::connect(sorter, &QQmlSorterBase::invalidateModel,
70 d->m_sfpmModel, &QQmlSortFilterProxyModel::invalidate);
74 QObject::connect(sorter, &QQmlSorterBase::invalidateCache,
75 this, &QQmlSorterCompositor::updateCache);
78 QObject::connect(sorter, &QQmlSorterBase::sortOrderChanged,
79 this, [d] { d->resetPrimarySorter(); });
80 QObject::connect(sorter, &QQmlSorterBase::columnChanged,
81 this, [d] { d->resetPrimarySorter(); });
84 emit d->m_sfpmModel->sortersChanged();
87qsizetype QQmlSorterCompositor::count()
89 Q_D(QQmlSorterCompositor);
90 return d->m_sorters.count();
93QQmlSorterBase* QQmlSorterCompositor::at(qsizetype index)
95 Q_D(QQmlSorterCompositor);
96 return d->m_sorters.at(index);
99void QQmlSorterCompositor::clear()
101 Q_D(QQmlSorterCompositor);
102 d->m_effectiveSorters.clear();
103 d->m_sorters.clear();
105 emit d->m_sfpmModel->sortersChanged();
108QList<QQmlSorterBase *> QQmlSorterCompositor::sorters()
110 Q_D(QQmlSorterCompositor);
114QQmlListProperty<QQmlSorterBase> QQmlSorterCompositor::sortersListProperty()
116 Q_D(QQmlSorterCompositor);
117 return QQmlListProperty<QQmlSorterBase>(
reinterpret_cast<QObject*>(
this), &d->m_sorters,
118 QQmlSorterCompositor::append,
119 QQmlSorterCompositor::count,
120 QQmlSorterCompositor::at,
121 QQmlSorterCompositor::clear);
124void QQmlSorterCompositor::updateEffectiveSorters()
126 Q_D(QQmlSorterCompositor);
128 if (!d->m_primarySorter || !d->m_primarySorter->enabled()) {
133 QList<QQmlSorterBase *> sorters;
134 sorters.append(d->m_primarySorter);
135 std::copy_if(d->m_effectiveSorters.constBegin(), d->m_effectiveSorters.constEnd(),
136 std::back_inserter(sorters), [d](QQmlSorterBase *sorter){
139 return (sorter != d->m_primarySorter);
141 d->m_effectiveSorters = sorters;
144void QQmlSorterCompositor::updateSorters()
146 Q_D(QQmlSorterCompositor);
149 for (
auto &sorter: d->m_sorters)
150 sorter->update(d->m_sfpmModel);
154void QQmlSorterCompositor::updateCache()
156 Q_D(QQmlSorterCompositor);
158 d->m_effectiveSorters.clear();
159 if (d->m_sfpmModel && d->m_sfpmModel->sourceModel()) {
161 QList<QQmlSorterBase *> sorters = d->m_sorters;
162 std::stable_sort(sorters.begin(), sorters.end(),
163 [](QQmlSorterBase *sorterLeft, QQmlSorterBase *sorterRight) {
164 return sorterLeft->priority() < sorterRight->priority();
167 std::copy_if(sorters.begin(), sorters.end(), std::back_inserter(d->m_effectiveSorters),
168 [](QQmlSorterBase *sorter) {
return sorter->enabled(); });
171 d->resetPrimarySorter();
175bool QQmlSorterCompositor::lessThan(
const QModelIndex& sourceLeft,
const QModelIndex& sourceRight,
const QQmlSortFilterProxyModel *proxyModel)
const
177 Q_D(
const QQmlSorterCompositor);
178 for (
const auto &sorter : d->m_effectiveSorters) {
179 const int sortSection = sorter->column();
180 if ((sortSection > -1) && (sortSection < proxyModel->sourceModel()->columnCount())) {
181 const auto *sourceModel = proxyModel->sourceModel();
182 const QPartialOrdering result = sorter->compare(sourceModel->index(sourceLeft.row(), sortSection),
183 sourceModel->index(sourceRight.row(), sortSection),
185 if (result == QPartialOrdering::Less || result == QPartialOrdering::Greater) {
186 auto *priv =
static_cast<
const QQmlSortFilterProxyModelPrivate *>(QQmlSortFilterProxyModelPrivate::get(proxyModel));
187 return (priv->m_sortOrder == sorter->sortOrder()) ? result < 0 : result > 0;
192 return sourceLeft.row() < sourceRight.row();
195void QQmlSorterCompositorPrivate::setPrimarySorter(QQmlSorterBase *sorter)
197 if (sorter ==
nullptr ||
198 (std::find(m_sorters.constBegin(), m_sorters.constEnd(), sorter) != m_sorters.constEnd())) {
199 m_primarySorter = sorter;
200 if (m_primarySorter && m_primarySorter->enabled()) {
201 m_sfpmModel->setPrimarySortOrder(m_primarySorter->sortOrder());
202 m_sfpmModel->setPrimarySortColumn(m_primarySorter->column());
206 resetPrimarySorter();
209void QQmlSorterCompositorPrivate::resetPrimarySorter()
211 if (!m_primarySorter) {
212 if (!m_effectiveSorters.isEmpty()) {
214 const auto *sorter = m_effectiveSorters.at(0);
215 m_sfpmModel->setPrimarySortOrder(sorter->sortOrder());
216 m_sfpmModel->setPrimarySortColumn(sorter->column());
220 m_sfpmModel->setPrimarySortOrder(Qt::AscendingOrder);
221 m_sfpmModel->setPrimarySortColumn(0);
228#include "moc_qqmlsortercompositor_p.cpp"