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))
|
if (QSortFilterProxyModel::lessThan(source_right, source_left))
|
||||||
return !m_ascendingSortOrder;
|
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()) {
|
if (sorter->enabled()) {
|
||||||
int comparison = sorter->compareRows(source_left, source_right, *this);
|
int comparison = sorter->compareRows(source_left, source_right, *this);
|
||||||
if (comparison != 0)
|
if (comparison != 0)
|
||||||
|
|
|
@ -79,6 +79,30 @@ void Sorter::setSortOrder(Qt::SortOrder sortOrder)
|
||||||
invalidate();
|
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 Sorter::compareRows(const QModelIndex &source_left, const QModelIndex &source_right, const QQmlSortFilterProxyModel& proxyModel) const
|
||||||
{
|
{
|
||||||
int comparison = compare(source_left, source_right, proxyModel);
|
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 enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
|
||||||
Q_PROPERTY(bool ascendingOrder READ ascendingOrder WRITE setAscendingOrder NOTIFY sortOrderChanged)
|
Q_PROPERTY(bool ascendingOrder READ ascendingOrder WRITE setAscendingOrder NOTIFY sortOrderChanged)
|
||||||
Q_PROPERTY(Qt::SortOrder sortOrder READ sortOrder WRITE setSortOrder NOTIFY sortOrderChanged)
|
Q_PROPERTY(Qt::SortOrder sortOrder READ sortOrder WRITE setSortOrder NOTIFY sortOrderChanged)
|
||||||
|
Q_PROPERTY(int priority READ priority WRITE setPriority NOTIFY priorityChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Sorter(QObject* parent = nullptr);
|
Sorter(QObject* parent = nullptr);
|
||||||
|
@ -27,6 +28,9 @@ public:
|
||||||
Qt::SortOrder sortOrder() const;
|
Qt::SortOrder sortOrder() const;
|
||||||
void setSortOrder(Qt::SortOrder sortOrder);
|
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;
|
int compareRows(const QModelIndex& source_left, const QModelIndex& source_right, const QQmlSortFilterProxyModel& proxyModel) const;
|
||||||
|
|
||||||
virtual void proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel);
|
virtual void proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel);
|
||||||
|
@ -34,6 +38,7 @@ public:
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void enabledChanged();
|
void enabledChanged();
|
||||||
void sortOrderChanged();
|
void sortOrderChanged();
|
||||||
|
void priorityChanged();
|
||||||
|
|
||||||
void invalidated();
|
void invalidated();
|
||||||
|
|
||||||
|
@ -45,6 +50,7 @@ protected:
|
||||||
private:
|
private:
|
||||||
bool m_enabled = true;
|
bool m_enabled = true;
|
||||||
Qt::SortOrder m_sortOrder = Qt::AscendingOrder;
|
Qt::SortOrder m_sortOrder = Qt::AscendingOrder;
|
||||||
|
int m_priority = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,14 +23,12 @@ Item {
|
||||||
id: testModel
|
id: testModel
|
||||||
sourceModel: dataModel
|
sourceModel: dataModel
|
||||||
}
|
}
|
||||||
|
|
||||||
ListModel {
|
ListModel {
|
||||||
id: sorterRoleModel
|
id: sorterRoleModel
|
||||||
ListElement { roleName: "a" }
|
ListElement { roleName: "a" }
|
||||||
ListElement { roleName: "b" }
|
ListElement { roleName: "b" }
|
||||||
ListElement { roleName: "c" }
|
ListElement { roleName: "c" }
|
||||||
}
|
}
|
||||||
|
|
||||||
Instantiator {
|
Instantiator {
|
||||||
id: sorterInstantiator
|
id: sorterInstantiator
|
||||||
model: sorterRoleModel
|
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 {
|
TestCase {
|
||||||
name: "SorterContainerAttached"
|
name: "SorterContainerAttached"
|
||||||
|
|
||||||
function modelValues() {
|
function modelValues(model) {
|
||||||
var modelValues = [];
|
var modelValues = [];
|
||||||
|
|
||||||
for (var i = 0; i < testModel.count; i++)
|
for (var i = 0; i < model.count; i++)
|
||||||
modelValues.push(testModel.get(i));
|
modelValues.push(model.get(i));
|
||||||
|
|
||||||
return modelValues;
|
return modelValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_sorterContainers() {
|
function test_sorterContainers() {
|
||||||
compare(sorterInstantiator.count, 3);
|
compare(sorterInstantiator.count, 3);
|
||||||
compare(modelValues(), [
|
compare(modelValues(testModel), [
|
||||||
{ a: 1, b: 7, c: 3 },
|
{ a: 1, b: 7, c: 3 },
|
||||||
{ a: 1, b: 8, c: 5 },
|
{ a: 1, b: 8, c: 5 },
|
||||||
{ a: 1, b: 8, c: 6 },
|
{ a: 1, b: 8, c: 6 },
|
||||||
|
@ -68,7 +86,7 @@ Item {
|
||||||
sorterRoleModel.remove(0); // a, b, c --> b, c
|
sorterRoleModel.remove(0); // a, b, c --> b, c
|
||||||
wait(0);
|
wait(0);
|
||||||
compare(sorterInstantiator.count, 2);
|
compare(sorterInstantiator.count, 2);
|
||||||
compare(JSON.stringify(modelValues()), JSON.stringify([
|
compare(JSON.stringify(modelValues(testModel)), JSON.stringify([
|
||||||
{ a: 2, b: 1, c: 7 },
|
{ a: 2, b: 1, c: 7 },
|
||||||
{ a: 3, b: 2, c: 8 },
|
{ a: 3, b: 2, c: 8 },
|
||||||
{ a: 3, b: 2, c: 9 },
|
{ a: 3, b: 2, c: 9 },
|
||||||
|
@ -80,5 +98,34 @@ Item {
|
||||||
{ a: 2, b: 9, c: 1 },
|
{ 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 {
|
Item {
|
||||||
ListModel {
|
ListModel {
|
||||||
id: listModel
|
id: listModel
|
||||||
ListElement { test: "first"; test2: "c" }
|
ListElement { test: "first"; test2: "c"; test3: 1 }
|
||||||
ListElement { test: "second"; test2: "a" }
|
ListElement { test: "second"; test2: "a"; test3: 0 }
|
||||||
ListElement { test: "third"; test2: "b" }
|
ListElement { test: "third"; test2: "b"; test3: 2}
|
||||||
ListElement { test: "fourth"; test2: "b" }
|
ListElement { test: "fourth"; test2: "b"; test3: 3 }
|
||||||
}
|
}
|
||||||
|
|
||||||
ListModel {
|
ListModel {
|
||||||
|
@ -74,6 +74,12 @@ Item {
|
||||||
RoleSorter { roleName: "test" }
|
RoleSorter { roleName: "test" }
|
||||||
]
|
]
|
||||||
|
|
||||||
|
property list<RoleSorter> sortersWithPriority: [
|
||||||
|
RoleSorter { roleName: "test3" },
|
||||||
|
RoleSorter { roleName: "test" },
|
||||||
|
RoleSorter { roleName: "test2"; priority: 1 }
|
||||||
|
]
|
||||||
|
|
||||||
SortFilterProxyModel {
|
SortFilterProxyModel {
|
||||||
id: testModel
|
id: testModel
|
||||||
sourceModel: listModel
|
sourceModel: listModel
|
||||||
|
@ -123,6 +129,15 @@ Item {
|
||||||
verifyModelValues(testModel, expectedValues);
|
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() {
|
function test_noRolesFirstModel() {
|
||||||
noRolesFirstListModel.append([{test: "b"}, {test: "a"}]);
|
noRolesFirstListModel.append([{test: "b"}, {test: "a"}]);
|
||||||
var expectedValues = ["a", "b"];
|
var expectedValues = ["a", "b"];
|
||||||
|
|
Loading…
Reference in New Issue