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.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
######################################################################

View File

@ -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
###########################

View File

@ -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",
),
]

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.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

View File

@ -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],

View File

@ -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 = ""