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 BrowserPreviewer as PreviewDialog
|
||||||
from aqt.previewer import Previewer
|
from aqt.previewer import Previewer
|
||||||
from aqt.qt import *
|
from aqt.qt import *
|
||||||
from aqt.sidebar import SidebarTreeView
|
from aqt.sidebar import SidebarSearchBar, SidebarTreeView
|
||||||
from aqt.theme import theme_manager
|
from aqt.theme import theme_manager
|
||||||
from aqt.utils import (
|
from aqt.utils import (
|
||||||
TR,
|
TR,
|
||||||
|
@ -912,6 +912,17 @@ QTableView {{ gridline-color: {grid} }}
|
||||||
self.sidebar = SidebarTreeView(self)
|
self.sidebar = SidebarTreeView(self)
|
||||||
self.sidebarTree = self.sidebar # legacy alias
|
self.sidebarTree = self.sidebar # legacy alias
|
||||||
dw.setWidget(self.sidebar)
|
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.setFloating(False)
|
||||||
|
|
||||||
self.sidebarDockWidget.setTitleBarWidget(QWidget())
|
self.sidebarDockWidget.setTitleBarWidget(QWidget())
|
||||||
|
@ -921,12 +932,19 @@ QTableView {{ gridline-color: {grid} }}
|
||||||
# UI is more responsive
|
# UI is more responsive
|
||||||
self.mw.progress.timer(10, self.sidebar.refresh, False)
|
self.mw.progress.timer(10, self.sidebar.refresh, False)
|
||||||
|
|
||||||
def focusSidebar(self) -> None:
|
def showSidebar(self) -> None:
|
||||||
# workaround for PyQt focus bug
|
# workaround for PyQt focus bug
|
||||||
self.editor.hideCompleters()
|
self.editor.hideCompleters()
|
||||||
self.sidebarDockWidget.setVisible(True)
|
self.sidebarDockWidget.setVisible(True)
|
||||||
|
|
||||||
|
def focusSidebar(self) -> None:
|
||||||
|
self.showSidebar()
|
||||||
self.sidebar.setFocus()
|
self.sidebar.setFocus()
|
||||||
|
|
||||||
|
def focusSidebarSearchBar(self) -> None:
|
||||||
|
self.showSidebar()
|
||||||
|
self.sidebar.searchBar.setFocus()
|
||||||
|
|
||||||
# legacy
|
# legacy
|
||||||
def maybeRefreshSidebar(self) -> None:
|
def maybeRefreshSidebar(self) -> None:
|
||||||
self.sidebar.refresh()
|
self.sidebar.refresh()
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import copy
|
||||||
|
import re
|
||||||
from concurrent.futures import Future
|
from concurrent.futures import Future
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Iterable, List, Optional
|
from typing import Iterable, List, Optional
|
||||||
|
@ -177,6 +179,49 @@ class SidebarModel(QAbstractItemModel):
|
||||||
# then ourselves
|
# then ourselves
|
||||||
tree.setExpanded(parent, True)
|
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):
|
class SidebarTreeView(QTreeView):
|
||||||
def __init__(self, browser: aqt.browser.Browser) -> None:
|
def __init__(self, browser: aqt.browser.Browser) -> None:
|
||||||
|
@ -222,6 +267,7 @@ class SidebarTreeView(QTreeView):
|
||||||
def on_done(fut: Future):
|
def on_done(fut: Future):
|
||||||
root = fut.result()
|
root = fut.result()
|
||||||
model = SidebarModel(root)
|
model = SidebarModel(root)
|
||||||
|
self.flattened_model = model.flattened()
|
||||||
self.setModel(model)
|
self.setModel(model)
|
||||||
model.expandWhereNeccessary(self)
|
model.expandWhereNeccessary(self)
|
||||||
|
|
||||||
|
@ -359,6 +405,7 @@ class SidebarTreeView(QTreeView):
|
||||||
not node.collapsed,
|
not node.collapsed,
|
||||||
item_type=SidebarItemType.DECK,
|
item_type=SidebarItemType.DECK,
|
||||||
id=node.deck_id,
|
id=node.deck_id,
|
||||||
|
full_name=head + node.name,
|
||||||
)
|
)
|
||||||
root.addChild(item)
|
root.addChild(item)
|
||||||
newhead = head + node.name + "::"
|
newhead = head + node.name + "::"
|
||||||
|
@ -384,6 +431,7 @@ class SidebarTreeView(QTreeView):
|
||||||
":/icons/notetype.svg",
|
":/icons/notetype.svg",
|
||||||
self._template_filter(nt["name"], c),
|
self._template_filter(nt["name"], c),
|
||||||
item_type=SidebarItemType.TEMPLATE,
|
item_type=SidebarItemType.TEMPLATE,
|
||||||
|
full_name=nt["name"] + "::" + tmpl["name"],
|
||||||
)
|
)
|
||||||
item.addChild(child)
|
item.addChild(child)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue