From 208c713e393ec6d27549977b427d25c743432b31 Mon Sep 17 00:00:00 2001 From: abdo Date: Wed, 27 Jan 2021 01:35:40 +0300 Subject: [PATCH 1/8] Add search bar to the sidebar https://github.com/ankitects/help-wanted/issues/6 --- qt/aqt/browser.py | 22 ++++++++++++++++++++-- qt/aqt/sidebar.py | 48 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/qt/aqt/browser.py b/qt/aqt/browser.py index ee1576108..47c564ede 100644 --- a/qt/aqt/browser.py +++ b/qt/aqt/browser.py @@ -35,7 +35,7 @@ from aqt.main import ResetReason from aqt.previewer import BrowserPreviewer as PreviewDialog from aqt.previewer import Previewer from aqt.qt import * -from aqt.sidebar import SidebarTreeView +from aqt.sidebar import SidebarSearchBar, SidebarTreeView from aqt.theme import theme_manager from aqt.utils import ( TR, @@ -912,6 +912,17 @@ QTableView {{ gridline-color: {grid} }} self.sidebar = SidebarTreeView(self) self.sidebarTree = self.sidebar # legacy alias dw.setWidget(self.sidebar) + self.sidebar.searchBar = searchBar = SidebarSearchBar(self.sidebar) + qconnect( + QShortcut(QKeySequence("Ctrl+Shift+B"), self).activated, + self.focusSidebarSearchBar, + ) + l = QVBoxLayout() + l.addWidget(searchBar) + l.addWidget(self.sidebar) + w = QWidget() + w.setLayout(l) + dw.setWidget(w) self.sidebarDockWidget.setFloating(False) self.sidebarDockWidget.setTitleBarWidget(QWidget()) @@ -921,12 +932,19 @@ QTableView {{ gridline-color: {grid} }} # UI is more responsive self.mw.progress.timer(10, self.sidebar.refresh, False) - def focusSidebar(self) -> None: + def showSidebar(self) -> None: # workaround for PyQt focus bug self.editor.hideCompleters() self.sidebarDockWidget.setVisible(True) + + def focusSidebar(self) -> None: + self.showSidebar() self.sidebar.setFocus() + def focusSidebarSearchBar(self) -> None: + self.showSidebar() + self.sidebar.searchBar.setFocus() + # legacy def maybeRefreshSidebar(self) -> None: self.sidebar.refresh() diff --git a/qt/aqt/sidebar.py b/qt/aqt/sidebar.py index 0c68570e7..b6064c94a 100644 --- a/qt/aqt/sidebar.py +++ b/qt/aqt/sidebar.py @@ -4,6 +4,8 @@ from __future__ import annotations +import copy +import re from concurrent.futures import Future from enum import Enum from typing import Iterable, List, Optional @@ -177,6 +179,49 @@ class SidebarModel(QAbstractItemModel): # then ourselves tree.setExpanded(parent, True) + def flattened(self) -> SidebarModel: + "Returns a flattened representation of the model." + root = SidebarItem("", "", item_type=SidebarItemType.ROOT) + + def flatten_tree(children: Iterable[SidebarItem]): + for child in children: + child.name = child.full_name + root.addChild(child) + flatten_tree(child.children) + child.children = [] + + flatten_tree(copy.deepcopy(self.root.children)) + + return SidebarModel(root) + + +class SidebarSearchBar(QLineEdit): + def __init__(self, sidebar): + QLineEdit.__init__(self, sidebar) + self.sidebar = sidebar + qconnect(self.textChanged, self.onTextChanged) + + def onTextChanged(self, text: str): + if text == "": + self.sidebar.refresh() + else: + # show matched items in the sidebar + root = SidebarItem("", "", item_type=SidebarItemType.ROOT) + pattern = re.compile("(?i).*{}.*".format(re.escape(text))) + for item in self.sidebar.flattened_model.root.children: + if pattern.match(item.name) or pattern.match(item.full_name): + root.addChild(item) + + self.sidebar.setModel(SidebarModel(root)) + + def keyPressEvent(self, evt): + if evt.key() in (Qt.Key_Up, Qt.Key_Down): + self.sidebar.setFocus() + elif evt.key() in (Qt.Key_Enter, Qt.Key_Return): + self.onTextChanged(self.text()) + else: + QLineEdit.keyPressEvent(self, evt) + class SidebarTreeView(QTreeView): def __init__(self, browser: aqt.browser.Browser) -> None: @@ -222,6 +267,7 @@ class SidebarTreeView(QTreeView): def on_done(fut: Future): root = fut.result() model = SidebarModel(root) + self.flattened_model = model.flattened() self.setModel(model) model.expandWhereNeccessary(self) @@ -359,6 +405,7 @@ class SidebarTreeView(QTreeView): not node.collapsed, item_type=SidebarItemType.DECK, id=node.deck_id, + full_name=head + node.name, ) root.addChild(item) newhead = head + node.name + "::" @@ -384,6 +431,7 @@ class SidebarTreeView(QTreeView): ":/icons/notetype.svg", self._template_filter(nt["name"], c), item_type=SidebarItemType.TEMPLATE, + full_name=nt["name"] + "::" + tmpl["name"], ) item.addChild(child) From fbf2f673f42f1939925733af112b60246ebc496b Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Thu, 28 Jan 2021 17:47:58 +1000 Subject: [PATCH 2/8] fix sidebar model.parent() returning invalid values Triggered a crash when using a model proxy. --- qt/aqt/sidebar.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/qt/aqt/sidebar.py b/qt/aqt/sidebar.py index b6064c94a..a812bc53b 100644 --- a/qt/aqt/sidebar.py +++ b/qt/aqt/sidebar.py @@ -123,9 +123,8 @@ class SidebarModel(QAbstractItemModel): if parentItem is None or parentItem == self.root: return QModelIndex() - row = parentItem.rowForChild(childItem) - if row is None: - return QModelIndex() + grandparent = parentItem.parentItem or self.root + row = grandparent.rowForChild(parentItem) return self.createIndex(row, 0, parentItem) @@ -269,6 +268,10 @@ class SidebarTreeView(QTreeView): model = SidebarModel(root) self.flattened_model = model.flattened() self.setModel(model) + + #from PyQt5.QtTest import QAbstractItemModelTester + #tester = QAbstractItemModelTester(model) + model.expandWhereNeccessary(self) self.mw.taskman.run_in_background(self._root_tree, on_done) From 8b08687b0ca8eb8ecbcb7fc20fcd6d3a994ed31b Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Thu, 28 Jan 2021 18:51:18 +1000 Subject: [PATCH 3/8] basic tree-based filtering with a sort proxy Some things left to do: - instead of searching on each keystroke, have the keystroke start a timer and wait 600-1000ms before performing the search - handle the case .refresh() is called while searching It would also be nice to have some visual distinction between matching rows and their non-matching parents. --- qt/aqt/sidebar.py | 116 +++++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 62 deletions(-) diff --git a/qt/aqt/sidebar.py b/qt/aqt/sidebar.py index a812bc53b..3a33b5a19 100644 --- a/qt/aqt/sidebar.py +++ b/qt/aqt/sidebar.py @@ -4,8 +4,6 @@ from __future__ import annotations -import copy -import re from concurrent.futures import Future from enum import Enum from typing import Iterable, List, Optional @@ -68,6 +66,7 @@ class SidebarItem: self.children: List["SidebarItem"] = [] self.parentItem: Optional["SidebarItem"] = None self.tooltip: Optional[str] = None + self.row_in_parent: Optional[int] = None def addChild(self, cb: "SidebarItem") -> None: self.children.append(cb) @@ -84,6 +83,13 @@ class SidebarModel(QAbstractItemModel): def __init__(self, root: SidebarItem) -> None: super().__init__() self.root = root + self._cache_rows(root) + + def _cache_rows(self, node: SidebarItem): + "Cache index of children in parent." + for row, item in enumerate(node.children): + item.row_in_parent = row + self._cache_rows(item) # Qt API ###################################################################### @@ -123,8 +129,7 @@ class SidebarModel(QAbstractItemModel): if parentItem is None or parentItem == self.root: return QModelIndex() - grandparent = parentItem.parentItem or self.root - row = grandparent.rowForChild(parentItem) + row = parentItem.row_in_parent return self.createIndex(row, 0, parentItem) @@ -151,67 +156,29 @@ class SidebarModel(QAbstractItemModel): print("iconFromRef() deprecated") return theme_manager.icon_from_resources(iconRef) - def expandWhereNeccessary(self, tree: QTreeView) -> None: - for row, child in enumerate(self.root.children): - if child.expanded: - idx = self.index(row, 0, QModelIndex()) - self._expandWhereNeccessary(idx, tree) - def _expandWhereNeccessary(self, parent: QModelIndex, tree: QTreeView) -> None: - parentItem: SidebarItem - if not parent.isValid(): - parentItem = self.root - else: - parentItem = parent.internalPointer() - - # nothing to do? - if not parentItem.expanded: - return - - # expand children - for row, child in enumerate(parentItem.children): - if not child.expanded: - continue - childIdx = self.index(row, 0, parent) - self._expandWhereNeccessary(childIdx, tree) - - # then ourselves - tree.setExpanded(parent, True) - - def flattened(self) -> SidebarModel: - "Returns a flattened representation of the model." - root = SidebarItem("", "", item_type=SidebarItemType.ROOT) - - def flatten_tree(children: Iterable[SidebarItem]): - for child in children: - child.name = child.full_name - root.addChild(child) - flatten_tree(child.children) - child.children = [] - - flatten_tree(copy.deepcopy(self.root.children)) - - return SidebarModel(root) +def expand_where_necessary( + model: QAbstractItemModel, tree: QTreeView, parent=None +) -> None: + parent = parent or QModelIndex() + for row in range(model.rowCount(parent)): + idx = model.index(row, 0, parent) + if not idx.isValid(): + continue + expand_where_necessary(model, tree, idx) + item = idx.internalPointer() + if item.expanded: + tree.setExpanded(idx, True) class SidebarSearchBar(QLineEdit): - def __init__(self, sidebar): + def __init__(self, sidebar: SidebarTreeView): QLineEdit.__init__(self, sidebar) self.sidebar = sidebar qconnect(self.textChanged, self.onTextChanged) def onTextChanged(self, text: str): - if text == "": - self.sidebar.refresh() - else: - # show matched items in the sidebar - root = SidebarItem("", "", item_type=SidebarItemType.ROOT) - pattern = re.compile("(?i).*{}.*".format(re.escape(text))) - for item in self.sidebar.flattened_model.root.children: - if pattern.match(item.name) or pattern.match(item.full_name): - root.addChild(item) - - self.sidebar.setModel(SidebarModel(root)) + self.sidebar.search_for(text) def keyPressEvent(self, evt): if evt.key() in (Qt.Key_Up, Qt.Key_Down): @@ -228,6 +195,7 @@ class SidebarTreeView(QTreeView): self.browser = browser self.mw = browser.mw self.col = self.mw.col + self.searching = False self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.onContextMenu) # type: ignore @@ -266,16 +234,36 @@ class SidebarTreeView(QTreeView): def on_done(fut: Future): root = fut.result() model = SidebarModel(root) - self.flattened_model = model.flattened() + + # from PyQt5.QtTest import QAbstractItemModelTester + # tester = QAbstractItemModelTester(model) + + self.searching = False self.setModel(model) - - #from PyQt5.QtTest import QAbstractItemModelTester - #tester = QAbstractItemModelTester(model) - - model.expandWhereNeccessary(self) + expand_where_necessary(model, self) self.mw.taskman.run_in_background(self._root_tree, on_done) + def search_for(self, text: str): + if not text.strip(): + self.refresh() + return + if not isinstance(self.model(), QSortFilterProxyModel): + filter_model = QSortFilterProxyModel(self) + filter_model.setSourceModel(self.model()) + filter_model.setFilterCaseSensitivity(False) # type: ignore + filter_model.setRecursiveFilteringEnabled(True) + self.setModel(filter_model) + else: + filter_model = self.model() + + self.searching = True + # Without collapsing first, can be very slow. Surely there's + # a better way than this? + self.collapseAll() + filter_model.setFilterFixedString(text) + self.expandAll() + def onClickCurrent(self) -> None: idx = self.currentIndex() if idx.isValid(): @@ -295,9 +283,13 @@ class SidebarTreeView(QTreeView): super().keyPressEvent(event) def onExpansion(self, idx: QModelIndex) -> None: + if self.searching: + return self._onExpansionChange(idx, True) def onCollapse(self, idx: QModelIndex) -> None: + if self.searching: + return self._onExpansionChange(idx, False) def _onExpansionChange(self, idx: QModelIndex, expanded: bool) -> None: From b148095243140a730c7f126d3a678a200aa2e4a2 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Thu, 28 Jan 2021 18:58:51 +1000 Subject: [PATCH 4/8] basic match highlighting --- qt/aqt/sidebar.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/qt/aqt/sidebar.py b/qt/aqt/sidebar.py index 3a33b5a19..2126536e2 100644 --- a/qt/aqt/sidebar.py +++ b/qt/aqt/sidebar.py @@ -195,7 +195,7 @@ class SidebarTreeView(QTreeView): self.browser = browser self.mw = browser.mw self.col = self.mw.col - self.searching = False + self.current_search = False self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.onContextMenu) # type: ignore @@ -238,7 +238,7 @@ class SidebarTreeView(QTreeView): # from PyQt5.QtTest import QAbstractItemModelTester # tester = QAbstractItemModelTester(model) - self.searching = False + self.current_search = None self.setModel(model) expand_where_necessary(model, self) @@ -257,13 +257,23 @@ class SidebarTreeView(QTreeView): else: filter_model = self.model() - self.searching = True + self.current_search = text # Without collapsing first, can be very slow. Surely there's # a better way than this? self.collapseAll() filter_model.setFilterFixedString(text) self.expandAll() + def drawRow(self, painter: QPainter, options: QStyleOptionViewItem, idx: QModelIndex): + if not self.current_search: + return super().drawRow(painter, options, idx) + if self.current_search.lower() in self.model().mapToSource(idx).internalPointer().name.lower(): + brush = QBrush(QColor("lightyellow")) + painter.save() + painter.fillRect(options.rect, brush) + painter.restore() + return super().drawRow(painter, options, idx) + def onClickCurrent(self) -> None: idx = self.currentIndex() if idx.isValid(): @@ -283,12 +293,12 @@ class SidebarTreeView(QTreeView): super().keyPressEvent(event) def onExpansion(self, idx: QModelIndex) -> None: - if self.searching: + if self.current_search: return self._onExpansionChange(idx, True) def onCollapse(self, idx: QModelIndex) -> None: - if self.searching: + if self.current_search: return self._onExpansionChange(idx, False) From 2224fce9368e82a204796e39756dafad597a3dc0 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Thu, 28 Jan 2021 19:10:06 +1000 Subject: [PATCH 5/8] fix crashes when activating context menu/items while searching --- qt/aqt/sidebar.py | 46 ++++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/qt/aqt/sidebar.py b/qt/aqt/sidebar.py index 2126536e2..1d62476ec 100644 --- a/qt/aqt/sidebar.py +++ b/qt/aqt/sidebar.py @@ -91,6 +91,9 @@ class SidebarModel(QAbstractItemModel): item.row_in_parent = row self._cache_rows(item) + def item_for_index(self, idx: QModelIndex) -> SidebarItem: + return idx.internalPointer() + # Qt API ###################################################################### @@ -157,20 +160,25 @@ class SidebarModel(QAbstractItemModel): return theme_manager.icon_from_resources(iconRef) -def expand_where_necessary( - model: QAbstractItemModel, tree: QTreeView, parent=None -) -> None: +def expand_where_necessary(model: SidebarModel, tree: QTreeView, parent=None) -> None: parent = parent or QModelIndex() for row in range(model.rowCount(parent)): idx = model.index(row, 0, parent) if not idx.isValid(): continue expand_where_necessary(model, tree, idx) - item = idx.internalPointer() - if item.expanded: + item = model.item_for_index(idx) + if item and item.expanded: tree.setExpanded(idx, True) +class FilterModel(QSortFilterProxyModel): + def item_for_index(self, idx: QModelIndex) -> Optional[SidebarItem]: + if not idx.isValid(): + return None + return self.mapToSource(idx).internalPointer() + + class SidebarSearchBar(QLineEdit): def __init__(self, sidebar: SidebarTreeView): QLineEdit.__init__(self, sidebar) @@ -195,7 +203,7 @@ class SidebarTreeView(QTreeView): self.browser = browser self.mw = browser.mw self.col = self.mw.col - self.current_search = False + self.current_search: Optional[str] = None self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.onContextMenu) # type: ignore @@ -226,6 +234,9 @@ class SidebarTreeView(QTreeView): bgcolor = QPalette().window().color().name() self.setStyleSheet("QTreeView { background: '%s'; }" % bgcolor) + def model(self) -> Union[FilterModel, SidebarModel]: + return super().model() + def refresh(self) -> None: "Refresh list. No-op if sidebar is not visible." if not self.isVisible(): @@ -248,8 +259,8 @@ class SidebarTreeView(QTreeView): if not text.strip(): self.refresh() return - if not isinstance(self.model(), QSortFilterProxyModel): - filter_model = QSortFilterProxyModel(self) + if not isinstance(self.model(), FilterModel): + filter_model = FilterModel(self) filter_model.setSourceModel(self.model()) filter_model.setFilterCaseSensitivity(False) # type: ignore filter_model.setRecursiveFilteringEnabled(True) @@ -264,10 +275,14 @@ class SidebarTreeView(QTreeView): filter_model.setFilterFixedString(text) self.expandAll() - def drawRow(self, painter: QPainter, options: QStyleOptionViewItem, idx: QModelIndex): - if not self.current_search: + def drawRow( + self, painter: QPainter, options: QStyleOptionViewItem, idx: QModelIndex + ): + if self.current_search is None: return super().drawRow(painter, options, idx) - if self.current_search.lower() in self.model().mapToSource(idx).internalPointer().name.lower(): + if not (item := self.model().item_for_index(idx)): + return super().drawRow(painter, options, idx) + if self.current_search.lower() in item.name.lower(): brush = QBrush(QColor("lightyellow")) painter.save() painter.fillRect(options.rect, brush) @@ -276,8 +291,7 @@ class SidebarTreeView(QTreeView): def onClickCurrent(self) -> None: idx = self.currentIndex() - if idx.isValid(): - item: "aqt.browser.SidebarItem" = idx.internalPointer() + if item := self.model().item_for_index(idx): if item.onClick: item.onClick() @@ -303,8 +317,8 @@ class SidebarTreeView(QTreeView): self._onExpansionChange(idx, False) def _onExpansionChange(self, idx: QModelIndex, expanded: bool) -> None: - item: "aqt.browser.SidebarItem" = idx.internalPointer() - if item.expanded != expanded: + item = self.model().item_for_index(idx) + if item and item.expanded != expanded: item.expanded = expanded if item.onExpanded: item.onExpanded(expanded) @@ -476,7 +490,7 @@ class SidebarTreeView(QTreeView): def onContextMenu(self, point: QPoint) -> None: idx: QModelIndex = self.indexAt(point) - item: "aqt.browser.SidebarItem" = idx.internalPointer() + item = self.model().item_for_index(idx) if not item: return item_type: SidebarItemType = item.item_type From 6850e0f78ef949ae03d944d2db18a33006cfe0dc Mon Sep 17 00:00:00 2001 From: abdo Date: Fri, 29 Jan 2021 02:36:13 +0300 Subject: [PATCH 6/8] Make sidebar search matching work with full_name instead of name --- qt/aqt/sidebar.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/qt/aqt/sidebar.py b/qt/aqt/sidebar.py index 1d62476ec..798ef4301 100644 --- a/qt/aqt/sidebar.py +++ b/qt/aqt/sidebar.py @@ -140,7 +140,7 @@ class SidebarModel(QAbstractItemModel): if not index.isValid(): return QVariant() - if role not in (Qt.DisplayRole, Qt.DecorationRole, Qt.ToolTipRole): + if role not in (Qt.DisplayRole, Qt.DecorationRole, Qt.ToolTipRole, Qt.EditRole): return QVariant() item: SidebarItem = index.internalPointer() @@ -149,6 +149,8 @@ class SidebarModel(QAbstractItemModel): return QVariant(item.name) elif role == Qt.ToolTipRole: return QVariant(item.tooltip) + elif role == Qt.EditRole: + return QVariant(item.full_name) else: return QVariant(theme_manager.icon_from_resources(item.icon)) @@ -264,6 +266,7 @@ class SidebarTreeView(QTreeView): filter_model.setSourceModel(self.model()) filter_model.setFilterCaseSensitivity(False) # type: ignore filter_model.setRecursiveFilteringEnabled(True) + filter_model.setFilterRole(Qt.EditRole) self.setModel(filter_model) else: filter_model = self.model() @@ -282,7 +285,7 @@ class SidebarTreeView(QTreeView): return super().drawRow(painter, options, idx) if not (item := self.model().item_for_index(idx)): return super().drawRow(painter, options, idx) - if self.current_search.lower() in item.name.lower(): + if self.current_search.lower() in item.full_name.lower(): brush = QBrush(QColor("lightyellow")) painter.save() painter.fillRect(options.rect, brush) From 9492c8305e12a3367d105ea652acd3eddf302b7d Mon Sep 17 00:00:00 2001 From: abdo Date: Fri, 29 Jan 2021 03:40:32 +0300 Subject: [PATCH 7/8] Wait for some time before performing sidebar search --- qt/aqt/sidebar.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/qt/aqt/sidebar.py b/qt/aqt/sidebar.py index 798ef4301..b9f4ef332 100644 --- a/qt/aqt/sidebar.py +++ b/qt/aqt/sidebar.py @@ -185,16 +185,24 @@ class SidebarSearchBar(QLineEdit): def __init__(self, sidebar: SidebarTreeView): QLineEdit.__init__(self, sidebar) self.sidebar = sidebar + self.timer = QTimer(self) + self.timer.setInterval(600) + self.timer.setSingleShot(True) + qconnect(self.timer.timeout, self.onSearch) qconnect(self.textChanged, self.onTextChanged) def onTextChanged(self, text: str): - self.sidebar.search_for(text) + if not self.timer.isActive(): + self.timer.start() + + def onSearch(self): + self.sidebar.search_for(self.text()) def keyPressEvent(self, evt): if evt.key() in (Qt.Key_Up, Qt.Key_Down): self.sidebar.setFocus() elif evt.key() in (Qt.Key_Enter, Qt.Key_Return): - self.onTextChanged(self.text()) + self.onSearch() else: QLineEdit.keyPressEvent(self, evt) From 903008f2bd2c1199605d1bf1943eb0fbb1184ce0 Mon Sep 17 00:00:00 2001 From: abdo Date: Fri, 29 Jan 2021 04:20:15 +0300 Subject: [PATCH 8/8] Handle sidebar refreshing while searching --- qt/aqt/sidebar.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/qt/aqt/sidebar.py b/qt/aqt/sidebar.py index b9f4ef332..b12029efc 100644 --- a/qt/aqt/sidebar.py +++ b/qt/aqt/sidebar.py @@ -259,14 +259,17 @@ class SidebarTreeView(QTreeView): # from PyQt5.QtTest import QAbstractItemModelTester # tester = QAbstractItemModelTester(model) - self.current_search = None self.setModel(model) - expand_where_necessary(model, self) + if self.current_search: + self.search_for(self.current_search) + else: + expand_where_necessary(model, self) self.mw.taskman.run_in_background(self._root_tree, on_done) def search_for(self, text: str): if not text.strip(): + self.current_search = None self.refresh() return if not isinstance(self.model(), FilterModel): @@ -528,7 +531,7 @@ class SidebarTreeView(QTreeView): self.mw.col.decks.rename(deck, new_name) except DeckRenameError as e: return showWarning(e.description) - self.browser.maybeRefreshSidebar() + self.refresh() self.mw.deckBrowser.refresh() def remove_tag(self, item: "aqt.browser.SidebarItem") -> None: @@ -545,7 +548,7 @@ class SidebarTreeView(QTreeView): self.mw.requireReset(reason=ResetReason.BrowserRemoveTags, context=self) self.browser.model.endReset() fut.result() - self.browser.maybeRefreshSidebar() + self.refresh() self.mw.checkpoint(tr(TR.ACTIONS_REMOVE_TAG)) self.browser.model.beginReset() @@ -573,7 +576,7 @@ class SidebarTreeView(QTreeView): showInfo(tr(TR.BROWSING_TAG_RENAME_WARNING_EMPTY)) return - self.browser.maybeRefreshSidebar() + self.refresh() self.mw.checkpoint(tr(TR.ACTIONS_RENAME_TAG)) self.browser.model.beginReset() @@ -593,7 +596,7 @@ class SidebarTreeView(QTreeView): self.mw.requireReset(reason=ResetReason.BrowserDeleteDeck, context=self) self.browser.search() self.browser.model.endReset() - self.browser.maybeRefreshSidebar() + self.refresh() res = fut.result() # Required to check for errors self.mw.checkpoint(tr(TR.DECKS_DELETE_DECK))