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 (
QObject, QSortFilterProxyModel, Qt, pyqtProperty, pyqtSignal, pyqtSlot
QModelIndex, QObject, QSortFilterProxyModel, Qt, pyqtProperty, pyqtSignal,
pyqtSlot
)
from .list_model import ListModel
@ -15,9 +16,10 @@ class SortFilterProxy(QSortFilterProxyModel):
def __init__(self,
source_model: ListModel,
sort_by_role: str,
filter_by_role: str,
sort_by_role: str = "",
filter_by_role: str = "",
ascending: bool = True,
sort_func: Optional[Callable[[Any, Any], bool]] = None,
parent: QObject = None) -> None:
super().__init__(parent)
self.setDynamicSortFilter(False)
@ -28,6 +30,8 @@ class SortFilterProxy(QSortFilterProxyModel):
source_model.countChanged.connect(self.countChanged.emit)
source_model.changed.connect(self._apply_sort)
self.sort_func = sort_func
self._sort_by_role = ""
self.sortByRole = sort_by_role
self.ascending = ascending
@ -83,9 +87,15 @@ class SortFilterProxy(QSortFilterProxyModel):
numbers = self.sourceModel().roleNumbers()
try:
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])
except KeyError:
pass # Model doesn't have its roles set yet (empty model)
except (AttributeError, KeyError):
pass
def _apply_sort(self) -> None:
@ -93,6 +103,24 @@ class SortFilterProxy(QSortFilterProxyModel):
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
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()
def cancel(self):
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,
client: Client,
room_id: str,
@ -169,8 +174,8 @@ class SignalManager(QObject):
members = ListModel()
sorted_members = SortFilterProxy(
source_model = members,
sort_by_role = "userId", # TODO
filter_by_role = "userId",
filter_by_role = "displayName",
sort_func = self._members_sort_func,
)
categories["Invites"].rooms.upsert(
@ -209,8 +214,8 @@ class SignalManager(QObject):
members = ListModel()
sorted_members = SortFilterProxy(
source_model = members,
sort_by_role = "userId", # TODO
filter_by_role = "userId",
filter_by_role = "displayName",
sort_func = self._members_sort_func,
)
categories["Rooms"].rooms.upsert(
@ -252,8 +257,8 @@ class SignalManager(QObject):
members = ListModel()
sorted_members = SortFilterProxy(
source_model = members,
sort_by_role = "userId", # TODO
filter_by_role = "userId",
sort_by_role = "displayName",
filter_by_role = "displayName",
)
categories["Left"].rooms.upsert(

View File

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