mirror of
https://github.com/ankitects/anki.git
synced 2025-09-20 15:02:21 -04:00
Merge pull request #447 from glutanimate/browser-sidebar-tree-hooks
Add browser_will_build_tree filter
This commit is contained in:
commit
0ec3bbe1af
3 changed files with 175 additions and 5 deletions
|
@ -11,6 +11,7 @@ import sre_constants
|
||||||
import time
|
import time
|
||||||
import unicodedata
|
import unicodedata
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
from enum import Enum
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
from typing import Callable, List, Optional, Union
|
from typing import Callable, List, Optional, Union
|
||||||
|
|
||||||
|
@ -418,6 +419,15 @@ class StatusDelegate(QItemDelegate):
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
|
|
||||||
|
class SidebarStage(Enum):
|
||||||
|
ROOT = 0
|
||||||
|
STANDARD = 1
|
||||||
|
FAVORITES = 2
|
||||||
|
DECKS = 3
|
||||||
|
MODELS = 4
|
||||||
|
TAGS = 5
|
||||||
|
|
||||||
|
|
||||||
class SidebarItem:
|
class SidebarItem:
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
|
@ -1085,11 +1095,27 @@ by clicking on one on the left."""
|
||||||
|
|
||||||
def buildTree(self) -> SidebarItem:
|
def buildTree(self) -> SidebarItem:
|
||||||
root = SidebarItem("", "")
|
root = SidebarItem("", "")
|
||||||
self._stdTree(root)
|
|
||||||
self._favTree(root)
|
handled = gui_hooks.browser_will_build_tree(
|
||||||
self._decksTree(root)
|
False, root, SidebarStage.ROOT, self
|
||||||
self._modelTree(root)
|
)
|
||||||
self._userTagTree(root)
|
if handled:
|
||||||
|
return root
|
||||||
|
|
||||||
|
for stage, builder in zip(
|
||||||
|
list(SidebarStage)[1:],
|
||||||
|
(
|
||||||
|
self._stdTree,
|
||||||
|
self._favTree,
|
||||||
|
self._decksTree,
|
||||||
|
self._modelTree,
|
||||||
|
self._userTagTree,
|
||||||
|
),
|
||||||
|
):
|
||||||
|
handled = gui_hooks.browser_will_build_tree(False, root, stage, self)
|
||||||
|
if not handled and builder:
|
||||||
|
builder(root)
|
||||||
|
|
||||||
return root
|
return root
|
||||||
|
|
||||||
def _stdTree(self, root) -> None:
|
def _stdTree(self, root) -> None:
|
||||||
|
|
|
@ -203,6 +203,105 @@ class _BrowserMenusDidInitHook:
|
||||||
browser_menus_did_init = _BrowserMenusDidInitHook()
|
browser_menus_did_init = _BrowserMenusDidInitHook()
|
||||||
|
|
||||||
|
|
||||||
|
class _BrowserWillBuildTreeFilter:
|
||||||
|
"""Used to add or replace items in the browser sidebar tree
|
||||||
|
|
||||||
|
'tree' is the root SidebarItem that all other items are added to.
|
||||||
|
|
||||||
|
'stage' is an enum describing the different construction stages of
|
||||||
|
the sidebar tree at which you can interject your changes.
|
||||||
|
The different values can be inspected by looking at
|
||||||
|
aqt.browser.SidebarStage.
|
||||||
|
|
||||||
|
If you want Anki to proceed with the construction of the tree stage
|
||||||
|
in question after your have performed your changes or additions,
|
||||||
|
return the 'handled' boolean unchanged.
|
||||||
|
|
||||||
|
On the other hand, if you want to prevent Anki from adding its own
|
||||||
|
items at a particular construction stage (e.g. in case your add-on
|
||||||
|
implements its own version of that particular stage), return 'True'.
|
||||||
|
|
||||||
|
If you return 'True' at SidebarStage.ROOT, the sidebar will not be
|
||||||
|
populated by any of the other construction stages. For any other stage
|
||||||
|
the tree construction will just continue as usual.
|
||||||
|
|
||||||
|
For example, if your code wishes to replace the tag tree, you could do:
|
||||||
|
|
||||||
|
def on_browser_will_build_tree(handled, root, stage, browser):
|
||||||
|
if stage != SidebarStage.TAGS:
|
||||||
|
# not at tag tree building stage, pass on
|
||||||
|
return handled
|
||||||
|
|
||||||
|
# your tag tree construction code
|
||||||
|
# root.addChild(...)
|
||||||
|
|
||||||
|
# your code handled tag tree construction, no need for Anki
|
||||||
|
# or other add-ons to build the tag tree
|
||||||
|
return True
|
||||||
|
"""
|
||||||
|
|
||||||
|
_hooks: List[
|
||||||
|
Callable[
|
||||||
|
[
|
||||||
|
bool,
|
||||||
|
"aqt.browser.SidebarItem",
|
||||||
|
"aqt.browser.SidebarStage",
|
||||||
|
"aqt.browser.Browser",
|
||||||
|
],
|
||||||
|
bool,
|
||||||
|
]
|
||||||
|
] = []
|
||||||
|
|
||||||
|
def append(
|
||||||
|
self,
|
||||||
|
cb: Callable[
|
||||||
|
[
|
||||||
|
bool,
|
||||||
|
"aqt.browser.SidebarItem",
|
||||||
|
"aqt.browser.SidebarStage",
|
||||||
|
"aqt.browser.Browser",
|
||||||
|
],
|
||||||
|
bool,
|
||||||
|
],
|
||||||
|
) -> None:
|
||||||
|
"""(handled: bool, tree: aqt.browser.SidebarItem, stage: aqt.browser.SidebarStage, browser: aqt.browser.Browser)"""
|
||||||
|
self._hooks.append(cb)
|
||||||
|
|
||||||
|
def remove(
|
||||||
|
self,
|
||||||
|
cb: Callable[
|
||||||
|
[
|
||||||
|
bool,
|
||||||
|
"aqt.browser.SidebarItem",
|
||||||
|
"aqt.browser.SidebarStage",
|
||||||
|
"aqt.browser.Browser",
|
||||||
|
],
|
||||||
|
bool,
|
||||||
|
],
|
||||||
|
) -> None:
|
||||||
|
if cb in self._hooks:
|
||||||
|
self._hooks.remove(cb)
|
||||||
|
|
||||||
|
def __call__(
|
||||||
|
self,
|
||||||
|
handled: bool,
|
||||||
|
tree: aqt.browser.SidebarItem,
|
||||||
|
stage: aqt.browser.SidebarStage,
|
||||||
|
browser: aqt.browser.Browser,
|
||||||
|
) -> bool:
|
||||||
|
for filter in self._hooks:
|
||||||
|
try:
|
||||||
|
handled = filter(handled, tree, stage, browser)
|
||||||
|
except:
|
||||||
|
# if the hook fails, remove it
|
||||||
|
self._hooks.remove(filter)
|
||||||
|
raise
|
||||||
|
return handled
|
||||||
|
|
||||||
|
|
||||||
|
browser_will_build_tree = _BrowserWillBuildTreeFilter()
|
||||||
|
|
||||||
|
|
||||||
class _BrowserWillShowContextMenuHook:
|
class _BrowserWillShowContextMenuHook:
|
||||||
_hooks: List[Callable[["aqt.browser.Browser", QMenu], None]] = []
|
_hooks: List[Callable[["aqt.browser.Browser", QMenu], None]] = []
|
||||||
|
|
||||||
|
|
|
@ -98,6 +98,51 @@ hooks = [
|
||||||
args=["browser: aqt.browser.Browser"],
|
args=["browser: aqt.browser.Browser"],
|
||||||
legacy_hook="browser.rowChanged",
|
legacy_hook="browser.rowChanged",
|
||||||
),
|
),
|
||||||
|
Hook(
|
||||||
|
name="browser_will_build_tree",
|
||||||
|
args=[
|
||||||
|
"handled: bool",
|
||||||
|
"tree: aqt.browser.SidebarItem",
|
||||||
|
"stage: aqt.browser.SidebarStage",
|
||||||
|
"browser: aqt.browser.Browser",
|
||||||
|
],
|
||||||
|
return_type="bool",
|
||||||
|
doc="""Used to add or replace items in the browser sidebar tree
|
||||||
|
|
||||||
|
'tree' is the root SidebarItem that all other items are added to.
|
||||||
|
|
||||||
|
'stage' is an enum describing the different construction stages of
|
||||||
|
the sidebar tree at which you can interject your changes.
|
||||||
|
The different values can be inspected by looking at
|
||||||
|
aqt.browser.SidebarStage.
|
||||||
|
|
||||||
|
If you want Anki to proceed with the construction of the tree stage
|
||||||
|
in question after your have performed your changes or additions,
|
||||||
|
return the 'handled' boolean unchanged.
|
||||||
|
|
||||||
|
On the other hand, if you want to prevent Anki from adding its own
|
||||||
|
items at a particular construction stage (e.g. in case your add-on
|
||||||
|
implements its own version of that particular stage), return 'True'.
|
||||||
|
|
||||||
|
If you return 'True' at SidebarStage.ROOT, the sidebar will not be
|
||||||
|
populated by any of the other construction stages. For any other stage
|
||||||
|
the tree construction will just continue as usual.
|
||||||
|
|
||||||
|
For example, if your code wishes to replace the tag tree, you could do:
|
||||||
|
|
||||||
|
def on_browser_will_build_tree(handled, root, stage, browser):
|
||||||
|
if stage != SidebarStage.TAGS:
|
||||||
|
# not at tag tree building stage, pass on
|
||||||
|
return handled
|
||||||
|
|
||||||
|
# your tag tree construction code
|
||||||
|
# root.addChild(...)
|
||||||
|
|
||||||
|
# your code handled tag tree construction, no need for Anki
|
||||||
|
# or other add-ons to build the tag tree
|
||||||
|
return True
|
||||||
|
""",
|
||||||
|
),
|
||||||
# States
|
# States
|
||||||
###################
|
###################
|
||||||
Hook(
|
Hook(
|
||||||
|
|
Loading…
Reference in a new issue