mirror of
https://github.com/ankitects/anki.git
synced 2025-09-22 07:52:24 -04:00
Add search bar to the sidebar
https://github.com/ankitects/help-wanted/issues/6
This commit is contained in:
parent
322788133b
commit
208c713e39
2 changed files with 68 additions and 2 deletions
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
Loading…
Reference in a new issue