Replace SortFilterProxyModel by DelegateModel
This commit is contained in:
		
							
								
								
									
										2
									
								
								TODO.md
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								TODO.md
									
									
									
									
									
								
							| @@ -5,11 +5,11 @@ | |||||||
| - update glass theme | - update glass theme | ||||||
| - back/front buttons in small window | - back/front buttons in small window | ||||||
| - minimum sizes | - minimum sizes | ||||||
| - save/restore swipeview current rooms for accounts |  | ||||||
| - lag when switching accounts | - lag when switching accounts | ||||||
| - message delegate too tall | - message delegate too tall | ||||||
| - unread counts on accounts | - unread counts on accounts | ||||||
| - fix compact mode | - fix compact mode | ||||||
|  | - left rooms opacity | ||||||
|  |  | ||||||
| - fix escape keybinds (filter rooms, message selection) | - fix escape keybinds (filter rooms, message selection) | ||||||
| - if last room event is a membership change, it won't be visible in timeline | - if last room event is a membership change, it won't be visible in timeline | ||||||
|   | |||||||
| @@ -58,11 +58,6 @@ dev { | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| # Libraries includes |  | ||||||
|  |  | ||||||
| include(submodules/SortFilterProxyModel/SortFilterProxyModel.pri) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| # Custom functions | # Custom functions | ||||||
|  |  | ||||||
| defineReplace(glob_filenames) { | defineReplace(glob_filenames) { | ||||||
|   | |||||||
							
								
								
									
										50
									
								
								src/gui/Base/HFilterModel.qml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/gui/Base/HFilterModel.qml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | |||||||
|  | // SPDX-License-Identifier: LGPL-3.0-or-later | ||||||
|  |  | ||||||
|  | import QtQuick 2.12 | ||||||
|  | import QtQml.Models 2.12 | ||||||
|  |  | ||||||
|  | DelegateModel { | ||||||
|  |     filterOnGroup: "filtered" | ||||||
|  |  | ||||||
|  |     groups: DelegateModelGroup { | ||||||
|  |         id: filtered | ||||||
|  |         name: "filtered" | ||||||
|  |         includeByDefault: false | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     onAcceptItemChanged: refilterAll() | ||||||
|  |  | ||||||
|  |     items.onChanged: { | ||||||
|  |         for (let i = 0; i < inserted.length; i++) | ||||||
|  |             for (let offset = 0; offset <= inserted[i].count - 1; offset++) | ||||||
|  |                 refilterAt(inserted[i].index + offset) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     property var acceptItem: item => true | ||||||
|  |     readonly property alias filtered: filtered | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     function refilterAt(index) { | ||||||
|  |         const item = items.get(index) | ||||||
|  |         item.inFiltered = acceptItem(item.model) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function refilterAll() { | ||||||
|  |         for (let i = 0; i < items.count; i++) refilterAt(i) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function filteredFindIndex(id) { | ||||||
|  |         for (let i = 0; i < filtered.count; i++) | ||||||
|  |             if (filtered.get(i).id === id) return i | ||||||
|  |  | ||||||
|  |         return null | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function filteredFind(id) { | ||||||
|  |         for (let i = 0; i < filtered.count; i++) | ||||||
|  |             if (filtered.get(i).id === id) return get(i) | ||||||
|  |  | ||||||
|  |         return null | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,20 +0,0 @@ | |||||||
| // SPDX-License-Identifier: LGPL-3.0-or-later |  | ||||||
|  |  | ||||||
| import QtQuick 2.12 |  | ||||||
| import SortFilterProxyModel 0.2 |  | ||||||
|  |  | ||||||
| SortFilterProxyModel { |  | ||||||
|     function findIndex(id) { |  | ||||||
|         for (let i = 0; i < count; i++) |  | ||||||
|             if (get(i).id === id) return i |  | ||||||
|  |  | ||||||
|         return null |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     function find(id) { |  | ||||||
|         for (let i = 0; i < count; i++) |  | ||||||
|             if (get(i).id === id) return get(i) |  | ||||||
|  |  | ||||||
|         return null |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -34,7 +34,10 @@ HColumnLayout { | |||||||
|             roomList.currentIndex === -1 ? |             roomList.currentIndex === -1 ? | ||||||
|             -1 : |             -1 : | ||||||
|             model.findIndex( |             model.findIndex( | ||||||
|                 roomList.model.get(roomList.currentIndex).for_account, -1, |                 roomList.model.filtered.get( | ||||||
|  |                     roomList.currentIndex, | ||||||
|  |                 ).model.for_account, | ||||||
|  |                 -1, | ||||||
|             ) |             ) | ||||||
|  |  | ||||||
|         highlight: Item { |         highlight: Item { | ||||||
|   | |||||||
| @@ -20,13 +20,13 @@ HTextField { | |||||||
|  |  | ||||||
|     Keys.onEnterPressed: Keys.onReturnPressed(event) |     Keys.onEnterPressed: Keys.onReturnPressed(event) | ||||||
|     Keys.onReturnPressed: { |     Keys.onReturnPressed: { | ||||||
|         if (window.settings.clearRoomFilterOnEnter) text = "" |  | ||||||
|         roomList.showRoomAtIndex() |         roomList.showRoomAtIndex() | ||||||
|  |         if (window.settings.clearRoomFilterOnEnter) text = "" | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     Keys.onEscapePressed: { |     Keys.onEscapePressed: { | ||||||
|         if (window.settings.clearRoomFilterOnEscape) text = "" |  | ||||||
|         mainUI.pageLoader.forceActiveFocus() |         mainUI.pageLoader.forceActiveFocus() | ||||||
|  |         if (window.settings.clearRoomFilterOnEscape) text = "" | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -2,13 +2,21 @@ | |||||||
|  |  | ||||||
| import QtQuick 2.12 | import QtQuick 2.12 | ||||||
| import QtQuick.Layouts 1.12 | import QtQuick.Layouts 1.12 | ||||||
| import SortFilterProxyModel 0.2 |  | ||||||
| import ".." | import ".." | ||||||
| import "../Base" | import "../Base" | ||||||
|  |  | ||||||
| HListView { | HListView { | ||||||
|     id: roomList |     id: roomList | ||||||
|     model: filter ? proxyModel : proxyModel.sourceModel |  | ||||||
|  |     model: HFilterModel { | ||||||
|  |         model: ModelStore.get("every_room") | ||||||
|  |         delegate: Room { | ||||||
|  |             width: roomList.width | ||||||
|  |             onActivated: showRoomAtIndex(model.index) | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         acceptItem: item => utils.filterMatches(filter, item.display_name) | ||||||
|  |     } | ||||||
|  |  | ||||||
|     section.property: "for_account" |     section.property: "for_account" | ||||||
|     section.labelPositioning: |     section.labelPositioning: | ||||||
| @@ -18,10 +26,7 @@ HListView { | |||||||
|         width: roomList.width |         width: roomList.width | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     delegate: Room { |     onFilterChanged: model.refilterAll() | ||||||
|         width: roomList.width |  | ||||||
|         onActivated: showRoomAtIndex(model.index) |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     property string filter: "" |     property string filter: "" | ||||||
| @@ -50,22 +55,23 @@ HListView { | |||||||
|  |  | ||||||
|     function showRoomAtIndex(index=currentIndex) { |     function showRoomAtIndex(index=currentIndex) { | ||||||
|         if (index === -1) index = 0 |         if (index === -1) index = 0 | ||||||
|         index = Math.min(index, model.count - 1) |         index = Math.min(index, model.filtered.count - 1) | ||||||
|  |  | ||||||
|         const room = model.get(index) |         const room = model.filtered.get(index).model | ||||||
|         pageLoader.showRoom(room.for_account, room.id) |         pageLoader.showRoom(room.for_account, room.id) | ||||||
|         currentIndex = index |         currentIndex = index | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     function showAccountRoomAtIndex(index) { |     function showAccountRoomAtIndex(index) { | ||||||
|         const userId = |         const userId = model.filtered.get( | ||||||
|             model.get(currentIndex === -1 ? 0 : currentIndex).for_account |             currentIndex === -1 ?  0 : currentIndex | ||||||
|  |         ).model.for_account | ||||||
|  |  | ||||||
|         const rooms = ModelStore.get(userId, "rooms") |         const rooms = ModelStore.get(userId, "rooms") | ||||||
|         if (! rooms.count) return |         if (! rooms.count) return | ||||||
|  |  | ||||||
|         const room = rooms.get(utils.numberWrapAt(index, rooms.count)) |         const room = rooms.get(utils.numberWrapAt(index, rooms.count)) | ||||||
|         showRoomAtIndex(model.findIndex(room.id)) |         showRoomAtIndex(model.filteredFindIndex(room.id)) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -97,15 +103,6 @@ HListView { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     HSortFilterProxyModel { |  | ||||||
|         id: proxyModel |  | ||||||
|         sourceModel: ModelStore.get("every_room") |  | ||||||
|  |  | ||||||
|         filters: ExpressionFilter { |  | ||||||
|             expression: utils.filterMatches(filter, model.display_name) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Rectangle { |     Rectangle { | ||||||
|         anchors.fill: parent |         anchors.fill: parent | ||||||
|         z: -100 |         z: -100 | ||||||
|   | |||||||
| @@ -2,7 +2,6 @@ | |||||||
|  |  | ||||||
| import QtQuick 2.12 | import QtQuick 2.12 | ||||||
| import QtQuick.Layouts 1.12 | import QtQuick.Layouts 1.12 | ||||||
| import SortFilterProxyModel 0.2 |  | ||||||
| import "../../.." | import "../../.." | ||||||
| import "../../../Base" | import "../../../Base" | ||||||
|  |  | ||||||
| @@ -14,26 +13,17 @@ HColumnLayout { | |||||||
|         id: memberList |         id: memberList | ||||||
|         clip: true |         clip: true | ||||||
|  |  | ||||||
|         // https://github.com/oKcerG/SortFilterProxyModel/issues/75 |         model: HFilterModel { | ||||||
|         model: filterField.text ? proxy : proxy.sourceModel |             model: ModelStore.get(chat.userId, chat.roomId, "members") | ||||||
|  |             delegate: MemberDelegate { width: memberList.width } | ||||||
|  |  | ||||||
|         delegate: MemberDelegate { |             acceptItem: item => | ||||||
|             width: memberList.width |                 utils.filterMatches(filterField.text, item.display_name) | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         Layout.fillWidth: true |         Layout.fillWidth: true | ||||||
|         Layout.fillHeight: true |         Layout.fillHeight: true | ||||||
|  |  | ||||||
|         readonly property HSortFilterProxyModel proxy: HSortFilterProxyModel { |  | ||||||
|             sourceModel: ModelStore.get(chat.userId, chat.roomId, "members") |  | ||||||
|  |  | ||||||
|             filters: ExpressionFilter { |  | ||||||
|                 expression: utils.filterMatches( |  | ||||||
|                    filterField.text, model.display_name, |  | ||||||
|                 ) |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         Rectangle { |         Rectangle { | ||||||
|             anchors.fill: parent |             anchors.fill: parent | ||||||
|             z: -100 |             z: -100 | ||||||
| @@ -68,6 +58,8 @@ HColumnLayout { | |||||||
|                 // declared normally |                 // declared normally | ||||||
|                 Component.onCompleted: placeholderText = qsTr("Filter members") |                 Component.onCompleted: placeholderText = qsTr("Filter members") | ||||||
|  |  | ||||||
|  |                 onTextChanged: memberList.model.refilterAll() | ||||||
|  |  | ||||||
|                 Behavior on opacity { HNumberAnimation {} } |                 Behavior on opacity { HNumberAnimation {} } | ||||||
|             } |             } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -227,6 +227,8 @@ QtObject { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     function filterMatches(filter, text) { |     function filterMatches(filter, text) { | ||||||
|  |         if (! filter) return true | ||||||
|  |  | ||||||
|         const filter_lower = filter.toLowerCase() |         const filter_lower = filter.toLowerCase() | ||||||
|  |  | ||||||
|         if (filter_lower === filter) { |         if (filter_lower === filter) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	