Merge pull request #1270 from RumovZ/flag-manager

Add flag manager and hook
This commit is contained in:
Damien Elmes 2021-07-04 15:45:11 +10:00 committed by GitHub
commit 1e57693b36
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 102 additions and 72 deletions

View File

@ -18,7 +18,6 @@ from anki.utils import isMac
from aqt import AnkiQt, gui_hooks from aqt import AnkiQt, gui_hooks
from aqt.editor import Editor from aqt.editor import Editor
from aqt.exporting import ExportDialog from aqt.exporting import ExportDialog
from aqt.flags import load_flags
from aqt.operations.card import set_card_deck, set_card_flag from aqt.operations.card import set_card_deck, set_card_flag
from aqt.operations.collection import redo, undo from aqt.operations.collection import redo, undo
from aqt.operations.note import remove_notes from aqt.operations.note import remove_notes
@ -175,7 +174,7 @@ class Browser(QMainWindow):
def set_flag_func(desired_flag: int) -> Callable: def set_flag_func(desired_flag: int) -> Callable:
return lambda: self.set_flag_of_selected_cards(desired_flag) return lambda: self.set_flag_of_selected_cards(desired_flag)
for flag in load_flags(self.col): for flag in self.mw.flags.all():
qconnect( qconnect(
getattr(self.form, flag.action).triggered, set_flag_func(flag.index) getattr(self.form, flag.action).triggered, set_flag_func(flag.index)
) )
@ -212,6 +211,7 @@ class Browser(QMainWindow):
self._cleanup_preview() self._cleanup_preview()
self.editor.cleanup() self.editor.cleanup()
self.table.cleanup() self.table.cleanup()
self.sidebar.cleanup()
saveSplitter(self.form.splitter, "editor3") saveSplitter(self.form.splitter, "editor3")
saveGeom(self, "editor") saveGeom(self, "editor")
saveState(self, "editor") saveState(self, "editor")
@ -702,13 +702,13 @@ class Browser(QMainWindow):
flag = self.card and self.card.user_flag() flag = self.card and self.card.user_flag()
flag = flag or 0 flag = flag or 0
for f in load_flags(self.col): for f in self.mw.flags.all():
getattr(self.form, f.action).setChecked(flag == f.index) getattr(self.form, f.action).setChecked(flag == f.index)
qtMenuShortcutWorkaround(self.form.menuFlag) qtMenuShortcutWorkaround(self.form.menuFlag)
def _update_flag_labels(self) -> None: def _update_flag_labels(self) -> None:
for flag in load_flags(self.col): for flag in self.mw.flags.all():
getattr(self.form, flag.action).setText(flag.label) getattr(self.form, flag.action).setText(flag.label)
def toggle_mark_of_selected_notes(self, checked: bool) -> None: def toggle_mark_of_selected_notes(self, checked: bool) -> None:
@ -782,6 +782,7 @@ class Browser(QMainWindow):
gui_hooks.backend_did_block.append(self.table.on_backend_did_block) gui_hooks.backend_did_block.append(self.table.on_backend_did_block)
gui_hooks.operation_did_execute.append(self.on_operation_did_execute) gui_hooks.operation_did_execute.append(self.on_operation_did_execute)
gui_hooks.focus_did_change.append(self.on_focus_change) gui_hooks.focus_did_change.append(self.on_focus_change)
gui_hooks.flag_label_did_change.append(self._update_flag_labels)
def teardownHooks(self) -> None: def teardownHooks(self) -> None:
gui_hooks.undo_state_did_change.remove(self.on_undo_state_change) gui_hooks.undo_state_did_change.remove(self.on_undo_state_change)
@ -789,6 +790,7 @@ class Browser(QMainWindow):
gui_hooks.backend_did_block.remove(self.table.on_backend_will_block) gui_hooks.backend_did_block.remove(self.table.on_backend_will_block)
gui_hooks.operation_did_execute.remove(self.on_operation_did_execute) gui_hooks.operation_did_execute.remove(self.on_operation_did_execute)
gui_hooks.focus_did_change.remove(self.on_focus_change) gui_hooks.focus_did_change.remove(self.on_focus_change)
gui_hooks.flag_label_did_change.remove(self._update_flag_labels)
# Undo # Undo
###################################################################### ######################################################################

View File

@ -26,7 +26,6 @@ from aqt.browser.sidebar.searchbar import SidebarSearchBar
from aqt.browser.sidebar.toolbar import SidebarTool, SidebarToolbar from aqt.browser.sidebar.toolbar import SidebarTool, SidebarToolbar
from aqt.clayout import CardLayout from aqt.clayout import CardLayout
from aqt.fields import FieldDialog from aqt.fields import FieldDialog
from aqt.flags import load_flags
from aqt.models import Models from aqt.models import Models
from aqt.operations import CollectionOp, QueryOp from aqt.operations import CollectionOp, QueryOp
from aqt.operations.deck import ( from aqt.operations.deck import (
@ -109,6 +108,11 @@ class SidebarTreeView(QTreeView):
self.toolbar = SidebarToolbar(self) self.toolbar = SidebarToolbar(self)
self.searchBar = SidebarSearchBar(self) self.searchBar = SidebarSearchBar(self)
gui_hooks.flag_label_did_change.append(self.refresh)
def cleanup(self) -> None:
gui_hooks.flag_label_did_change.remove(self.refresh)
@property @property
def tool(self) -> SidebarTool: def tool(self) -> SidebarTool:
return self._tool return self._tool
@ -677,7 +681,7 @@ class SidebarTreeView(QTreeView):
) )
root.search_node = SearchNode(flag=SearchNode.FLAG_ANY) root.search_node = SearchNode(flag=SearchNode.FLAG_ANY)
for flag in load_flags(self.col): for flag in self.mw.flags.all():
root.add_child( root.add_child(
SidebarItem( SidebarItem(
name=flag.label, name=flag.label,
@ -961,12 +965,8 @@ class SidebarTreeView(QTreeView):
########################### ###########################
def rename_flag(self, item: SidebarItem, new_name: str) -> None: def rename_flag(self, item: SidebarItem, new_name: str) -> None:
labels = self.col.get_config("flagLabels", {})
labels[str(item.id)] = new_name
self.col.set_config("flagLabels", labels)
item.name = new_name item.name = new_name
self.browser._update_flag_labels() self.mw.flags.rename_flag(item.id, new_name)
self.refresh()
# Decks # Decks
########################### ###########################

View File

@ -3,11 +3,11 @@
from __future__ import annotations from __future__ import annotations
from dataclasses import dataclass from dataclasses import dataclass
from typing import Dict, List, cast from typing import Dict, List, Optional, cast
from anki import Collection import aqt
from anki.collection import SearchNode from anki.collection import SearchNode
from aqt import colors from aqt import colors, gui_hooks
from aqt.theme import ColoredIcon from aqt.theme import ColoredIcon
from aqt.utils import tr from aqt.utils import tr
@ -30,60 +30,82 @@ class Flag:
action: str action: str
def load_flags(col: Collection) -> List[Flag]: class FlagManager:
"""Return a list of all flags, reloading labels from the config.""" def __init__(self, mw: aqt.main.AnkiQt) -> None:
self.mw = mw
self._flags: Optional[List[Flag]] = None
labels = cast(Dict[str, str], col.get_config("flagLabels", {})) def all(self) -> List[Flag]:
icon = ColoredIcon(path=":/icons/flag.svg", color=colors.DISABLED) """Return a list of all flags."""
if self._flags is None:
self._load_flags()
return self._flags
return [ def get_flag(self, flag_index: int) -> Flag:
Flag( if not 1 <= flag_index <= len(self.all()):
1, raise Exception(f"Flag index out of range (1-{len(self.all())}).")
labels["1"] if "1" in labels else tr.actions_flag_red(), return self.all()[flag_index - 1]
icon.with_color(colors.FLAG1_FG),
SearchNode(flag=SearchNode.FLAG_RED), def rename_flag(self, flag_index: int, new_name: str) -> None:
"actionRed_Flag", if new_name in ("", self.get_flag(flag_index).label):
), return
Flag( labels = self.mw.col.get_config("flagLabels", {})
2, labels[str(flag_index)] = self.get_flag(flag_index).label = new_name
labels["2"] if "2" in labels else tr.actions_flag_orange(), self.mw.col.set_config("flagLabels", labels)
icon.with_color(colors.FLAG2_FG), gui_hooks.flag_label_did_change()
SearchNode(flag=SearchNode.FLAG_ORANGE),
"actionOrange_Flag", def _load_flags(self) -> None:
), labels = cast(Dict[str, str], self.mw.col.get_config("flagLabels", {}))
Flag( icon = ColoredIcon(path=":/icons/flag.svg", color=colors.DISABLED)
3,
labels["3"] if "3" in labels else tr.actions_flag_green(), self._flags = [
icon.with_color(colors.FLAG3_FG), Flag(
SearchNode(flag=SearchNode.FLAG_GREEN), 1,
"actionGreen_Flag", labels["1"] if "1" in labels else tr.actions_flag_red(),
), icon.with_color(colors.FLAG1_FG),
Flag( SearchNode(flag=SearchNode.FLAG_RED),
4, "actionRed_Flag",
labels["4"] if "4" in labels else tr.actions_flag_blue(), ),
icon.with_color(colors.FLAG4_FG), Flag(
SearchNode(flag=SearchNode.FLAG_BLUE), 2,
"actionBlue_Flag", labels["2"] if "2" in labels else tr.actions_flag_orange(),
), icon.with_color(colors.FLAG2_FG),
Flag( SearchNode(flag=SearchNode.FLAG_ORANGE),
5, "actionOrange_Flag",
labels["5"] if "5" in labels else tr.actions_flag_pink(), ),
icon.with_color(colors.FLAG5_FG), Flag(
SearchNode(flag=SearchNode.FLAG_PINK), 3,
"actionPink_Flag", labels["3"] if "3" in labels else tr.actions_flag_green(),
), icon.with_color(colors.FLAG3_FG),
Flag( SearchNode(flag=SearchNode.FLAG_GREEN),
6, "actionGreen_Flag",
labels["6"] if "6" in labels else tr.actions_flag_turquoise(), ),
icon.with_color(colors.FLAG6_FG), Flag(
SearchNode(flag=SearchNode.FLAG_TURQUOISE), 4,
"actionTurquoise_Flag", labels["4"] if "4" in labels else tr.actions_flag_blue(),
), icon.with_color(colors.FLAG4_FG),
Flag( SearchNode(flag=SearchNode.FLAG_BLUE),
7, "actionBlue_Flag",
labels["7"] if "7" in labels else tr.actions_flag_purple(), ),
icon.with_color(colors.FLAG7_FG), Flag(
SearchNode(flag=SearchNode.FLAG_PURPLE), 5,
"actionPurple_Flag", labels["5"] if "5" in labels else tr.actions_flag_pink(),
), icon.with_color(colors.FLAG5_FG),
] SearchNode(flag=SearchNode.FLAG_PINK),
"actionPink_Flag",
),
Flag(
6,
labels["6"] if "6" in labels else tr.actions_flag_turquoise(),
icon.with_color(colors.FLAG6_FG),
SearchNode(flag=SearchNode.FLAG_TURQUOISE),
"actionTurquoise_Flag",
),
Flag(
7,
labels["7"] if "7" in labels else tr.actions_flag_purple(),
icon.with_color(colors.FLAG7_FG),
SearchNode(flag=SearchNode.FLAG_PURPLE),
"actionPurple_Flag",
),
]

View File

@ -48,6 +48,7 @@ from aqt import gui_hooks
from aqt.addons import DownloadLogEntry, check_and_prompt_for_updates, show_log_to_user from aqt.addons import DownloadLogEntry, check_and_prompt_for_updates, show_log_to_user
from aqt.dbcheck import check_db from aqt.dbcheck import check_db
from aqt.emptycards import show_empty_cards from aqt.emptycards import show_empty_cards
from aqt.flags import FlagManager
from aqt.legacy import install_pylib_legacy from aqt.legacy import install_pylib_legacy
from aqt.mediacheck import check_media_db from aqt.mediacheck import check_media_db
from aqt.mediasync import MediaSyncer from aqt.mediasync import MediaSyncer
@ -113,6 +114,7 @@ class AnkiQt(QMainWindow):
self.col: Optional[Collection] = None self.col: Optional[Collection] = None
self.taskman = TaskManager(self) self.taskman = TaskManager(self)
self.media_syncer = MediaSyncer(self) self.media_syncer = MediaSyncer(self)
self.flags = FlagManager(self)
aqt.mw = self aqt.mw = self
self.app = app self.app = app
self.pm = profileManager self.pm = profileManager

View File

@ -25,7 +25,6 @@ from anki.utils import stripHTML
from aqt import AnkiQt, gui_hooks from aqt import AnkiQt, gui_hooks
from aqt.browser.card_info import CardInfoDialog from aqt.browser.card_info import CardInfoDialog
from aqt.deckoptions import confirm_deck_then_display_options from aqt.deckoptions import confirm_deck_then_display_options
from aqt.flags import load_flags
from aqt.operations.card import set_card_flag from aqt.operations.card import set_card_flag
from aqt.operations.note import remove_notes from aqt.operations.note import remove_notes
from aqt.operations.scheduling import ( from aqt.operations.scheduling import (
@ -447,7 +446,7 @@ class Reviewer:
(Qt.Key_F5, self.replayAudio), (Qt.Key_F5, self.replayAudio),
*( *(
(f"Ctrl+{flag.index}", self.set_flag_func(flag.index)) (f"Ctrl+{flag.index}", self.set_flag_func(flag.index))
for flag in load_flags(self.mw.col) for flag in self.mw.flags.all()
), ),
("*", self.toggle_mark_on_current_note), ("*", self.toggle_mark_on_current_note),
("=", self.bury_current_note), ("=", self.bury_current_note),
@ -904,7 +903,7 @@ time = %(time)d;
self.set_flag_func(flag.index), self.set_flag_func(flag.index),
dict(checked=currentFlag == flag.index), dict(checked=currentFlag == flag.index),
] ]
for flag in load_flags(self.mw.col) for flag in self.mw.flags.all()
], ],
], ],
[tr.studying_bury_card(), "-", self.bury_current_card], [tr.studying_bury_card(), "-", self.bury_current_card],

View File

@ -946,6 +946,11 @@ gui_hooks.webview_did_inject_style_into_page.append(mytest)
args=["menu: QMenu", "deck_id: int"], args=["menu: QMenu", "deck_id: int"],
legacy_hook="showDeckOptions", legacy_hook="showDeckOptions",
), ),
Hook(
name="flag_label_did_change",
args=[],
doc="Used to update the GUI when a new flag label is assigned.",
),
] ]
suffix = "" suffix = ""