Implement room filtering
This commit is contained in:
parent
bb86c39fe7
commit
d82cb50e30
1
TODO.md
1
TODO.md
|
@ -49,6 +49,7 @@
|
||||||
- Links preview
|
- Links preview
|
||||||
|
|
||||||
- Client improvements
|
- Client improvements
|
||||||
|
- Filtering rooms: smart case, fuzzy filter, search more than display names
|
||||||
- nio.MatrixRoom has `typing_users`, no need to handle it on our own
|
- nio.MatrixRoom has `typing_users`, no need to handle it on our own
|
||||||
- Don't send setTypingState False when focus lost if nothing in sendbox
|
- Don't send setTypingState False when focus lost if nothing in sendbox
|
||||||
- Initial sync filter and lazy load, see weechat-matrix `_handle_login()`
|
- Initial sync filter and lazy load, see weechat-matrix `_handle_login()`
|
||||||
|
|
|
@ -113,6 +113,14 @@ class Backend(QObject):
|
||||||
)
|
)
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
|
@pyqtSlot(str)
|
||||||
|
def setRoomFilter(self, pattern: str) -> None:
|
||||||
|
for account in self.accounts:
|
||||||
|
for categ in account.roomCategories:
|
||||||
|
categ.sortedRooms.filter = pattern
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def getDir(standard_dir: QStandardPaths.StandardLocation) -> str:
|
def getDir(standard_dir: QStandardPaths.StandardLocation) -> str:
|
||||||
path = QStandardPaths.writableLocation(standard_dir)
|
path = QStandardPaths.writableLocation(standard_dir)
|
||||||
|
|
|
@ -9,11 +9,14 @@ from .list_model import ListModel
|
||||||
|
|
||||||
class SortFilterProxy(QSortFilterProxyModel):
|
class SortFilterProxy(QSortFilterProxyModel):
|
||||||
sortByRoleChanged = pyqtSignal()
|
sortByRoleChanged = pyqtSignal()
|
||||||
|
filterByRoleChanged = pyqtSignal()
|
||||||
|
filterChanged = pyqtSignal()
|
||||||
countChanged = pyqtSignal(int)
|
countChanged = pyqtSignal(int)
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
source_model: ListModel,
|
source_model: ListModel,
|
||||||
sort_by_role: str,
|
sort_by_role: str,
|
||||||
|
filter_by_role: str,
|
||||||
ascending: bool = True,
|
ascending: bool = True,
|
||||||
parent: QObject = None) -> None:
|
parent: QObject = None) -> None:
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
|
@ -21,14 +24,24 @@ class SortFilterProxy(QSortFilterProxyModel):
|
||||||
self.setFilterCaseSensitivity(Qt.CaseInsensitive)
|
self.setFilterCaseSensitivity(Qt.CaseInsensitive)
|
||||||
|
|
||||||
self.setSourceModel(source_model)
|
self.setSourceModel(source_model)
|
||||||
source_model.rolesSet.connect(self._set_internal_sort_role)
|
source_model.rolesSet.connect(self._set_internal_sort_filter_role)
|
||||||
source_model.countChanged.connect(self.countChanged.emit)
|
source_model.countChanged.connect(self.countChanged.emit)
|
||||||
source_model.changed.connect(self._sort)
|
source_model.changed.connect(self._apply_sort)
|
||||||
|
|
||||||
self._sort_by_role = ""
|
self._sort_by_role = ""
|
||||||
self.sortByRole = sort_by_role
|
self.sortByRole = sort_by_role
|
||||||
self.ascending = ascending
|
self.ascending = ascending
|
||||||
|
|
||||||
|
self._filter_by_role = ""
|
||||||
|
self.filterByRole = filter_by_role
|
||||||
|
|
||||||
|
self._filter = None
|
||||||
|
self.filterChanged.connect(
|
||||||
|
lambda: self.countChanged.emit(self.rowCount())
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Sorting and filtering
|
||||||
|
|
||||||
@pyqtProperty(str, notify=sortByRoleChanged)
|
@pyqtProperty(str, notify=sortByRoleChanged)
|
||||||
def sortByRole(self) -> str:
|
def sortByRole(self) -> str:
|
||||||
|
@ -38,18 +51,50 @@ class SortFilterProxy(QSortFilterProxyModel):
|
||||||
@sortByRole.setter # type: ignore
|
@sortByRole.setter # type: ignore
|
||||||
def sortByRole(self, role: str) -> None:
|
def sortByRole(self, role: str) -> None:
|
||||||
self._sort_by_role = role
|
self._sort_by_role = role
|
||||||
self._set_internal_sort_role()
|
self._set_internal_sort_filter_role()
|
||||||
self.sortByRoleChanged.emit()
|
self.sortByRoleChanged.emit()
|
||||||
|
|
||||||
|
|
||||||
def _set_internal_sort_role(self) -> None:
|
@pyqtProperty(str, notify=filterByRoleChanged)
|
||||||
|
def filterByRole(self) -> str:
|
||||||
|
return self._filter_by_role
|
||||||
|
|
||||||
|
|
||||||
|
@filterByRole.setter # type: ignore
|
||||||
|
def filterByRole(self, role: str) -> None:
|
||||||
|
self._filter_by_role = role
|
||||||
|
self._set_internal_sort_filter_role()
|
||||||
|
self.filterByRoleChanged.emit()
|
||||||
|
|
||||||
|
|
||||||
|
@pyqtProperty(str, notify=filterChanged)
|
||||||
|
def filter(self) -> str:
|
||||||
|
return self._filter
|
||||||
|
|
||||||
|
|
||||||
|
@filter.setter # type: ignore
|
||||||
|
def filter(self, pattern: str) -> None:
|
||||||
|
self._filter = pattern
|
||||||
|
self.setFilterWildcard(pattern or "*")
|
||||||
|
self.filterChanged.emit()
|
||||||
|
|
||||||
|
|
||||||
|
def _set_internal_sort_filter_role(self) -> None:
|
||||||
numbers = self.sourceModel().roleNumbers()
|
numbers = self.sourceModel().roleNumbers()
|
||||||
try:
|
try:
|
||||||
self.setSortRole(numbers[self._sort_by_role])
|
self.setSortRole(numbers[self.sortByRole])
|
||||||
|
self.setFilterRole(numbers[self.filterByRole])
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass # Model doesn't have its roles set yet (empty model)
|
pass # Model doesn't have its roles set yet (empty model)
|
||||||
|
|
||||||
|
|
||||||
|
def _apply_sort(self) -> None:
|
||||||
|
order = Qt.AscendingOrder if self.ascending else Qt.DescendingOrder
|
||||||
|
self.sort(0, order)
|
||||||
|
|
||||||
|
|
||||||
|
# The rest
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return "%s(sortByRole=%r, sourceModel=%s)" % (
|
return "%s(sortByRole=%r, sourceModel=%s)" % (
|
||||||
type(self).__name__,
|
type(self).__name__,
|
||||||
|
@ -73,8 +118,3 @@ class SortFilterProxy(QSortFilterProxyModel):
|
||||||
|
|
||||||
def roleNames(self) -> Dict[int, bytes]:
|
def roleNames(self) -> Dict[int, bytes]:
|
||||||
return self.sourceModel().roleNames()
|
return self.sourceModel().roleNames()
|
||||||
|
|
||||||
|
|
||||||
def _sort(self) -> None:
|
|
||||||
order = Qt.AscendingOrder if self.ascending else Qt.DescendingOrder
|
|
||||||
self.sort(0, order)
|
|
||||||
|
|
|
@ -68,6 +68,7 @@ class SignalManager(QObject):
|
||||||
proxy = SortFilterProxy(
|
proxy = SortFilterProxy(
|
||||||
source_model = room_categories_kwargs[i]["rooms"],
|
source_model = room_categories_kwargs[i]["rooms"],
|
||||||
sort_by_role = "lastEventDateTime",
|
sort_by_role = "lastEventDateTime",
|
||||||
|
filter_by_role = "displayName",
|
||||||
ascending = False,
|
ascending = False,
|
||||||
)
|
)
|
||||||
room_categories_kwargs[i]["sortedRooms"] = proxy
|
room_categories_kwargs[i]["sortedRooms"] = proxy
|
||||||
|
|
|
@ -17,6 +17,8 @@ HRowLayout {
|
||||||
placeholderText: qsTr("Filter rooms")
|
placeholderText: qsTr("Filter rooms")
|
||||||
backgroundColor: HStyle.sidePane.filterRooms.background
|
backgroundColor: HStyle.sidePane.filterRooms.background
|
||||||
|
|
||||||
|
onTextChanged: Backend.setRoomFilter(text)
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: 32
|
Layout.preferredHeight: 32
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user