feat: Add Sorter.priority property
This commit is contained in:
parent
314598ae54
commit
53c01b6ee3
|
@ -365,7 +365,13 @@ bool QQmlSortFilterProxyModel::lessThan(const QModelIndex& source_left, const QM
|
|||
if (QSortFilterProxyModel::lessThan(source_right, source_left))
|
||||
return !m_ascendingSortOrder;
|
||||
}
|
||||
for(auto sorter : m_sorters) {
|
||||
auto sortedSorters = m_sorters;
|
||||
std::stable_sort(sortedSorters.begin(),
|
||||
sortedSorters.end(),
|
||||
[] (Sorter* a, Sorter* b) {
|
||||
return a->priority() > b->priority();
|
||||
});
|
||||
for(auto sorter : sortedSorters) {
|
||||
if (sorter->enabled()) {
|
||||
int comparison = sorter->compareRows(source_left, source_right, *this);
|
||||
if (comparison != 0)
|
||||
|
|
|
@ -79,6 +79,30 @@ void Sorter::setSortOrder(Qt::SortOrder sortOrder)
|
|||
invalidate();
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty int Sorter::priority
|
||||
|
||||
This property holds the sort priority of this sorter.
|
||||
Sorters with a higher priority are applied first.
|
||||
In case of equal priority, Sorters are ordered by their insertion order.
|
||||
|
||||
By default, the priority is 0.
|
||||
*/
|
||||
int Sorter::priority() const
|
||||
{
|
||||
return m_priority;
|
||||
}
|
||||
|
||||
void Sorter::setPriority(int priority)
|
||||
{
|
||||
if (m_priority == priority)
|
||||
return;
|
||||
|
||||
m_priority = priority;
|
||||
Q_EMIT priorityChanged();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
int Sorter::compareRows(const QModelIndex &source_left, const QModelIndex &source_right, const QQmlSortFilterProxyModel& proxyModel) const
|
||||
{
|
||||
int comparison = compare(source_left, source_right, proxyModel);
|
||||
|
|
|
@ -13,6 +13,7 @@ class Sorter : public QObject
|
|||
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
|
||||
Q_PROPERTY(bool ascendingOrder READ ascendingOrder WRITE setAscendingOrder NOTIFY sortOrderChanged)
|
||||
Q_PROPERTY(Qt::SortOrder sortOrder READ sortOrder WRITE setSortOrder NOTIFY sortOrderChanged)
|
||||
Q_PROPERTY(int priority READ priority WRITE setPriority NOTIFY priorityChanged)
|
||||
|
||||
public:
|
||||
Sorter(QObject* parent = nullptr);
|
||||
|
@ -27,6 +28,9 @@ public:
|
|||
Qt::SortOrder sortOrder() const;
|
||||
void setSortOrder(Qt::SortOrder sortOrder);
|
||||
|
||||
int priority() const;
|
||||
void setPriority(int priority);
|
||||
|
||||
int compareRows(const QModelIndex& source_left, const QModelIndex& source_right, const QQmlSortFilterProxyModel& proxyModel) const;
|
||||
|
||||
virtual void proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel);
|
||||
|
@ -34,6 +38,7 @@ public:
|
|||
Q_SIGNALS:
|
||||
void enabledChanged();
|
||||
void sortOrderChanged();
|
||||
void priorityChanged();
|
||||
|
||||
void invalidated();
|
||||
|
||||
|
@ -45,6 +50,7 @@ protected:
|
|||
private:
|
||||
bool m_enabled = true;
|
||||
Qt::SortOrder m_sortOrder = Qt::AscendingOrder;
|
||||
int m_priority = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -23,14 +23,12 @@ Item {
|
|||
id: testModel
|
||||
sourceModel: dataModel
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: sorterRoleModel
|
||||
ListElement { roleName: "a" }
|
||||
ListElement { roleName: "b" }
|
||||
ListElement { roleName: "c" }
|
||||
}
|
||||
|
||||
Instantiator {
|
||||
id: sorterInstantiator
|
||||
model: sorterRoleModel
|
||||
|
@ -40,21 +38,41 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
SortFilterProxyModel {
|
||||
id: testModelPriority
|
||||
sourceModel: dataModel
|
||||
}
|
||||
ListModel {
|
||||
id: sorterRoleModelPriority
|
||||
ListElement { roleName: "a" }
|
||||
ListElement { roleName: "b" }
|
||||
ListElement { roleName: "c" }
|
||||
}
|
||||
Instantiator {
|
||||
id: sorterInstantiatorPriority
|
||||
model: sorterRoleModelPriority
|
||||
delegate: RoleSorter {
|
||||
SorterContainer.container: testModelPriority
|
||||
roleName: model.roleName
|
||||
priority: -model.index
|
||||
}
|
||||
}
|
||||
|
||||
TestCase {
|
||||
name: "SorterContainerAttached"
|
||||
|
||||
function modelValues() {
|
||||
function modelValues(model) {
|
||||
var modelValues = [];
|
||||
|
||||
for (var i = 0; i < testModel.count; i++)
|
||||
modelValues.push(testModel.get(i));
|
||||
for (var i = 0; i < model.count; i++)
|
||||
modelValues.push(model.get(i));
|
||||
|
||||
return modelValues;
|
||||
}
|
||||
|
||||
function test_sorterContainers() {
|
||||
compare(sorterInstantiator.count, 3);
|
||||
compare(modelValues(), [
|
||||
compare(modelValues(testModel), [
|
||||
{ a: 1, b: 7, c: 3 },
|
||||
{ a: 1, b: 8, c: 5 },
|
||||
{ a: 1, b: 8, c: 6 },
|
||||
|
@ -68,7 +86,7 @@ Item {
|
|||
sorterRoleModel.remove(0); // a, b, c --> b, c
|
||||
wait(0);
|
||||
compare(sorterInstantiator.count, 2);
|
||||
compare(JSON.stringify(modelValues()), JSON.stringify([
|
||||
compare(JSON.stringify(modelValues(testModel)), JSON.stringify([
|
||||
{ a: 2, b: 1, c: 7 },
|
||||
{ a: 3, b: 2, c: 8 },
|
||||
{ a: 3, b: 2, c: 9 },
|
||||
|
@ -80,5 +98,34 @@ Item {
|
|||
{ a: 2, b: 9, c: 1 },
|
||||
]));
|
||||
}
|
||||
|
||||
function test_sorterContainersPriority() {
|
||||
compare(sorterInstantiatorPriority.count, 3);
|
||||
compare(JSON.stringify(modelValues(testModelPriority)), JSON.stringify([
|
||||
{ a: 1, b: 7, c: 3 },
|
||||
{ a: 1, b: 8, c: 5 },
|
||||
{ a: 1, b: 8, c: 6 },
|
||||
{ a: 2, b: 1, c: 7 },
|
||||
{ a: 2, b: 6, c: 2 },
|
||||
{ a: 2, b: 9, c: 1 },
|
||||
{ a: 3, b: 2, c: 8 },
|
||||
{ a: 3, b: 2, c: 9 },
|
||||
{ a: 3, b: 5, c: 0 }
|
||||
]));
|
||||
sorterRoleModelPriority.move(0, 1, 1); // a, b, c --> b, a, c
|
||||
wait(0);
|
||||
compare(sorterInstantiatorPriority.count, 3);
|
||||
compare(JSON.stringify(modelValues(testModelPriority)), JSON.stringify([
|
||||
{ a: 2, b: 1, c: 7 },
|
||||
{ a: 3, b: 2, c: 8 },
|
||||
{ a: 3, b: 2, c: 9 },
|
||||
{ a: 3, b: 5, c: 0 },
|
||||
{ a: 2, b: 6, c: 2 },
|
||||
{ a: 1, b: 7, c: 3 },
|
||||
{ a: 1, b: 8, c: 5 },
|
||||
{ a: 1, b: 8, c: 6 },
|
||||
{ a: 2, b: 9, c: 1 }
|
||||
]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,10 +7,10 @@ import SortFilterProxyModel.Test 0.2
|
|||
Item {
|
||||
ListModel {
|
||||
id: listModel
|
||||
ListElement { test: "first"; test2: "c" }
|
||||
ListElement { test: "second"; test2: "a" }
|
||||
ListElement { test: "third"; test2: "b" }
|
||||
ListElement { test: "fourth"; test2: "b" }
|
||||
ListElement { test: "first"; test2: "c"; test3: 1 }
|
||||
ListElement { test: "second"; test2: "a"; test3: 0 }
|
||||
ListElement { test: "third"; test2: "b"; test3: 2}
|
||||
ListElement { test: "fourth"; test2: "b"; test3: 3 }
|
||||
}
|
||||
|
||||
ListModel {
|
||||
|
@ -74,6 +74,12 @@ Item {
|
|||
RoleSorter { roleName: "test" }
|
||||
]
|
||||
|
||||
property list<RoleSorter> sortersWithPriority: [
|
||||
RoleSorter { roleName: "test3" },
|
||||
RoleSorter { roleName: "test" },
|
||||
RoleSorter { roleName: "test2"; priority: 1 }
|
||||
]
|
||||
|
||||
SortFilterProxyModel {
|
||||
id: testModel
|
||||
sourceModel: listModel
|
||||
|
@ -123,6 +129,15 @@ Item {
|
|||
verifyModelValues(testModel, expectedValues);
|
||||
}
|
||||
|
||||
function test_sortersWithPriority() {
|
||||
testModel.sorters = sortersWithPriority;
|
||||
var expectedValues = ["second", "third", "fourth", "first"];
|
||||
verifyModelValues(testModel, expectedValues);
|
||||
testModel.sorters[0].priority = 2;
|
||||
expectedValues = ["second", "first", "third", "fourth"];
|
||||
verifyModelValues(testModel, expectedValues);
|
||||
}
|
||||
|
||||
function test_noRolesFirstModel() {
|
||||
noRolesFirstListModel.append([{test: "b"}, {test: "a"}]);
|
||||
var expectedValues = ["a", "b"];
|
||||
|
|
Loading…
Reference in New Issue