Merge pull request #1270 from RumovZ/flag-manager
Add flag manager and hook
This commit is contained in:
commit
1e57693b36
@ -18,7 +18,6 @@ from anki.utils import isMac
|
||||
from aqt import AnkiQt, gui_hooks
|
||||
from aqt.editor import Editor
|
||||
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.collection import redo, undo
|
||||
from aqt.operations.note import remove_notes
|
||||
@ -175,7 +174,7 @@ class Browser(QMainWindow):
|
||||
def set_flag_func(desired_flag: int) -> Callable:
|
||||
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(
|
||||
getattr(self.form, flag.action).triggered, set_flag_func(flag.index)
|
||||
)
|
||||
@ -212,6 +211,7 @@ class Browser(QMainWindow):
|
||||
self._cleanup_preview()
|
||||
self.editor.cleanup()
|
||||
self.table.cleanup()
|
||||
self.sidebar.cleanup()
|
||||
saveSplitter(self.form.splitter, "editor3")
|
||||
saveGeom(self, "editor")
|
||||
saveState(self, "editor")
|
||||
@ -702,13 +702,13 @@ class Browser(QMainWindow):
|
||||
flag = self.card and self.card.user_flag()
|
||||
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)
|
||||
|
||||
qtMenuShortcutWorkaround(self.form.menuFlag)
|
||||
|
||||
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)
|
||||
|
||||
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.operation_did_execute.append(self.on_operation_did_execute)
|
||||
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:
|
||||
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.operation_did_execute.remove(self.on_operation_did_execute)
|
||||
gui_hooks.focus_did_change.remove(self.on_focus_change)
|
||||
gui_hooks.flag_label_did_change.remove(self._update_flag_labels)
|
||||
|
||||
# Undo
|
||||
######################################################################
|
||||
|
@ -26,7 +26,6 @@ from aqt.browser.sidebar.searchbar import SidebarSearchBar
|
||||
from aqt.browser.sidebar.toolbar import SidebarTool, SidebarToolbar
|
||||
from aqt.clayout import CardLayout
|
||||
from aqt.fields import FieldDialog
|
||||
from aqt.flags import load_flags
|
||||
from aqt.models import Models
|
||||
from aqt.operations import CollectionOp, QueryOp
|
||||
from aqt.operations.deck import (
|
||||
@ -109,6 +108,11 @@ class SidebarTreeView(QTreeView):
|
||||
self.toolbar = SidebarToolbar(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
|
||||
def tool(self) -> SidebarTool:
|
||||
return self._tool
|
||||
@ -677,7 +681,7 @@ class SidebarTreeView(QTreeView):
|
||||
)
|
||||
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(
|
||||
SidebarItem(
|
||||
name=flag.label,
|
||||
@ -961,12 +965,8 @@ class SidebarTreeView(QTreeView):
|
||||
###########################
|
||||
|
||||
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
|
||||
self.browser._update_flag_labels()
|
||||
self.refresh()
|
||||
self.mw.flags.rename_flag(item.id, new_name)
|
||||
|
||||
# Decks
|
||||
###########################
|
||||
|
138
qt/aqt/flags.py
138
qt/aqt/flags.py
@ -3,11 +3,11 @@
|
||||
from __future__ import annotations
|
||||
|
||||
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 aqt import colors
|
||||
from aqt import colors, gui_hooks
|
||||
from aqt.theme import ColoredIcon
|
||||
from aqt.utils import tr
|
||||
|
||||
@ -30,60 +30,82 @@ class Flag:
|
||||
action: str
|
||||
|
||||
|
||||
def load_flags(col: Collection) -> List[Flag]:
|
||||
"""Return a list of all flags, reloading labels from the config."""
|
||||
class FlagManager:
|
||||
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", {}))
|
||||
icon = ColoredIcon(path=":/icons/flag.svg", color=colors.DISABLED)
|
||||
def all(self) -> List[Flag]:
|
||||
"""Return a list of all flags."""
|
||||
if self._flags is None:
|
||||
self._load_flags()
|
||||
return self._flags
|
||||
|
||||
return [
|
||||
Flag(
|
||||
1,
|
||||
labels["1"] if "1" in labels else tr.actions_flag_red(),
|
||||
icon.with_color(colors.FLAG1_FG),
|
||||
SearchNode(flag=SearchNode.FLAG_RED),
|
||||
"actionRed_Flag",
|
||||
),
|
||||
Flag(
|
||||
2,
|
||||
labels["2"] if "2" in labels else tr.actions_flag_orange(),
|
||||
icon.with_color(colors.FLAG2_FG),
|
||||
SearchNode(flag=SearchNode.FLAG_ORANGE),
|
||||
"actionOrange_Flag",
|
||||
),
|
||||
Flag(
|
||||
3,
|
||||
labels["3"] if "3" in labels else tr.actions_flag_green(),
|
||||
icon.with_color(colors.FLAG3_FG),
|
||||
SearchNode(flag=SearchNode.FLAG_GREEN),
|
||||
"actionGreen_Flag",
|
||||
),
|
||||
Flag(
|
||||
4,
|
||||
labels["4"] if "4" in labels else tr.actions_flag_blue(),
|
||||
icon.with_color(colors.FLAG4_FG),
|
||||
SearchNode(flag=SearchNode.FLAG_BLUE),
|
||||
"actionBlue_Flag",
|
||||
),
|
||||
Flag(
|
||||
5,
|
||||
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",
|
||||
),
|
||||
]
|
||||
def get_flag(self, flag_index: int) -> Flag:
|
||||
if not 1 <= flag_index <= len(self.all()):
|
||||
raise Exception(f"Flag index out of range (1-{len(self.all())}).")
|
||||
return self.all()[flag_index - 1]
|
||||
|
||||
def rename_flag(self, flag_index: int, new_name: str) -> None:
|
||||
if new_name in ("", self.get_flag(flag_index).label):
|
||||
return
|
||||
labels = self.mw.col.get_config("flagLabels", {})
|
||||
labels[str(flag_index)] = self.get_flag(flag_index).label = new_name
|
||||
self.mw.col.set_config("flagLabels", labels)
|
||||
gui_hooks.flag_label_did_change()
|
||||
|
||||
def _load_flags(self) -> None:
|
||||
labels = cast(Dict[str, str], self.mw.col.get_config("flagLabels", {}))
|
||||
icon = ColoredIcon(path=":/icons/flag.svg", color=colors.DISABLED)
|
||||
|
||||
self._flags = [
|
||||
Flag(
|
||||
1,
|
||||
labels["1"] if "1" in labels else tr.actions_flag_red(),
|
||||
icon.with_color(colors.FLAG1_FG),
|
||||
SearchNode(flag=SearchNode.FLAG_RED),
|
||||
"actionRed_Flag",
|
||||
),
|
||||
Flag(
|
||||
2,
|
||||
labels["2"] if "2" in labels else tr.actions_flag_orange(),
|
||||
icon.with_color(colors.FLAG2_FG),
|
||||
SearchNode(flag=SearchNode.FLAG_ORANGE),
|
||||
"actionOrange_Flag",
|
||||
),
|
||||
Flag(
|
||||
3,
|
||||
labels["3"] if "3" in labels else tr.actions_flag_green(),
|
||||
icon.with_color(colors.FLAG3_FG),
|
||||
SearchNode(flag=SearchNode.FLAG_GREEN),
|
||||
"actionGreen_Flag",
|
||||
),
|
||||
Flag(
|
||||
4,
|
||||
labels["4"] if "4" in labels else tr.actions_flag_blue(),
|
||||
icon.with_color(colors.FLAG4_FG),
|
||||
SearchNode(flag=SearchNode.FLAG_BLUE),
|
||||
"actionBlue_Flag",
|
||||
),
|
||||
Flag(
|
||||
5,
|
||||
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",
|
||||
),
|
||||
]
|
||||
|
@ -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.dbcheck import check_db
|
||||
from aqt.emptycards import show_empty_cards
|
||||
from aqt.flags import FlagManager
|
||||
from aqt.legacy import install_pylib_legacy
|
||||
from aqt.mediacheck import check_media_db
|
||||
from aqt.mediasync import MediaSyncer
|
||||
@ -113,6 +114,7 @@ class AnkiQt(QMainWindow):
|
||||
self.col: Optional[Collection] = None
|
||||
self.taskman = TaskManager(self)
|
||||
self.media_syncer = MediaSyncer(self)
|
||||
self.flags = FlagManager(self)
|
||||
aqt.mw = self
|
||||
self.app = app
|
||||
self.pm = profileManager
|
||||
|
@ -25,7 +25,6 @@ from anki.utils import stripHTML
|
||||
from aqt import AnkiQt, gui_hooks
|
||||
from aqt.browser.card_info import CardInfoDialog
|
||||
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.note import remove_notes
|
||||
from aqt.operations.scheduling import (
|
||||
@ -447,7 +446,7 @@ class Reviewer:
|
||||
(Qt.Key_F5, self.replayAudio),
|
||||
*(
|
||||
(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.bury_current_note),
|
||||
@ -904,7 +903,7 @@ time = %(time)d;
|
||||
self.set_flag_func(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],
|
||||
|
@ -946,6 +946,11 @@ gui_hooks.webview_did_inject_style_into_page.append(mytest)
|
||||
args=["menu: QMenu", "deck_id: int"],
|
||||
legacy_hook="showDeckOptions",
|
||||
),
|
||||
Hook(
|
||||
name="flag_label_did_change",
|
||||
args=[],
|
||||
doc="Used to update the GUI when a new flag label is assigned.",
|
||||
),
|
||||
]
|
||||
|
||||
suffix = ""
|
||||
|
Loading…
Reference in New Issue
Block a user