Sort/filter room members based on display name
This commit is contained in:
parent
226e9b0a85
commit
07d0515731
|
@ -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:
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user