Sort/filter room members based on display name

This commit is contained in:
miruka 2019-05-15 16:46:56 -04:00
parent 226e9b0a85
commit 07d0515731
4 changed files with 51 additions and 13 deletions

View File

@ -1,7 +1,8 @@
from typing import Dict from typing import Any, Callable, Dict, Optional
from PyQt5.QtCore import ( from PyQt5.QtCore import (
QObject, QSortFilterProxyModel, Qt, pyqtProperty, pyqtSignal, pyqtSlot QModelIndex, QObject, QSortFilterProxyModel, Qt, pyqtProperty, pyqtSignal,
pyqtSlot
) )
from .list_model import ListModel from .list_model import ListModel
@ -15,9 +16,10 @@ class SortFilterProxy(QSortFilterProxyModel):
def __init__(self, def __init__(self,
source_model: ListModel, source_model: ListModel,
sort_by_role: str, sort_by_role: str = "",
filter_by_role: str, filter_by_role: str = "",
ascending: bool = True, ascending: bool = True,
sort_func: Optional[Callable[[Any, Any], bool]] = None,
parent: QObject = None) -> None: parent: QObject = None) -> None:
super().__init__(parent) super().__init__(parent)
self.setDynamicSortFilter(False) self.setDynamicSortFilter(False)
@ -28,6 +30,8 @@ class SortFilterProxy(QSortFilterProxyModel):
source_model.countChanged.connect(self.countChanged.emit) source_model.countChanged.connect(self.countChanged.emit)
source_model.changed.connect(self._apply_sort) source_model.changed.connect(self._apply_sort)
self.sort_func = sort_func
self._sort_by_role = "" self._sort_by_role = ""
self.sortByRole = sort_by_role self.sortByRole = sort_by_role
self.ascending = ascending self.ascending = ascending
@ -83,9 +87,15 @@ class SortFilterProxy(QSortFilterProxyModel):
numbers = self.sourceModel().roleNumbers() numbers = self.sourceModel().roleNumbers()
try: try:
self.setSortRole(numbers[self.sortByRole]) self.setSortRole(numbers[self.sortByRole])
except (AttributeError, KeyError):
# Model doesn't have its roles set yet (empty model), or no
# self.sortByRole passed
pass
try:
self.setFilterRole(numbers[self.filterByRole]) self.setFilterRole(numbers[self.filterByRole])
except KeyError: except (AttributeError, KeyError):
pass # Model doesn't have its roles set yet (empty model) pass
def _apply_sort(self) -> None: def _apply_sort(self) -> None:
@ -93,6 +103,24 @@ class SortFilterProxy(QSortFilterProxyModel):
self.sort(0, order) self.sort(0, order)
# Sorting/filtering implementations
def lessThan(self, source_left: QModelIndex, source_right: QModelIndex
) -> bool:
left = self.sourceModel()[source_left.row()]
right = self.sourceModel()[source_right.row()]
if self.sort_func:
return self.sort_func(left, right)
role = self.sortByRole
try:
return getattr(left, role) < getattr(right, role)
except TypeError: # comparison between the two types not supported
return False
# The rest # The rest
def __repr__(self) -> str: def __repr__(self) -> str:

View File

@ -39,6 +39,11 @@ class PyQtFuture(QObject):
) )
def __lt__(self, other: "PyQtFuture") -> bool:
# This is to allow sorting, e.g. from SortFilterProxy.lessThan()
return self.value < other.value
@pyqtSlot() @pyqtSlot()
def cancel(self): def cancel(self):
self.future.cancel() self.future.cancel()

View File

@ -153,6 +153,11 @@ class SignalManager(QObject):
) )
def _members_sort_func(self, left: RoomMember, right: RoomMember) -> bool:
users = self.backend.users
return users[left.userId].displayName < users[right.userId].displayName
def onRoomInvited(self, def onRoomInvited(self,
client: Client, client: Client,
room_id: str, room_id: str,
@ -169,8 +174,8 @@ class SignalManager(QObject):
members = ListModel() members = ListModel()
sorted_members = SortFilterProxy( sorted_members = SortFilterProxy(
source_model = members, source_model = members,
sort_by_role = "userId", # TODO filter_by_role = "displayName",
filter_by_role = "userId", sort_func = self._members_sort_func,
) )
categories["Invites"].rooms.upsert( categories["Invites"].rooms.upsert(
@ -209,8 +214,8 @@ class SignalManager(QObject):
members = ListModel() members = ListModel()
sorted_members = SortFilterProxy( sorted_members = SortFilterProxy(
source_model = members, source_model = members,
sort_by_role = "userId", # TODO filter_by_role = "displayName",
filter_by_role = "userId", sort_func = self._members_sort_func,
) )
categories["Rooms"].rooms.upsert( categories["Rooms"].rooms.upsert(
@ -252,8 +257,8 @@ class SignalManager(QObject):
members = ListModel() members = ListModel()
sorted_members = SortFilterProxy( sorted_members = SortFilterProxy(
source_model = members, source_model = members,
sort_by_role = "userId", # TODO sort_by_role = "displayName",
filter_by_role = "userId", filter_by_role = "displayName",
) )
categories["Left"].rooms.upsert( categories["Left"].rooms.upsert(

View File

@ -7,7 +7,7 @@ MouseArea {
width: memberList.width width: memberList.width
height: childrenRect.height height: childrenRect.height
property var member: Backend.users.get(modelData) property var member: Backend.users.get(userId)
HRowLayout { HRowLayout {
width: parent.width width: parent.width