Merge pull request #1178 from RumovZ/flag-labels

Custom labels for flags
This commit is contained in:
Damien Elmes 2021-05-20 11:59:55 +10:00 committed by GitHub
commit 055f2907ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 123 additions and 78 deletions

View File

@ -42,6 +42,7 @@ from aqt.utils import (
current_top_level_widget,
ensure_editor_saved,
getTag,
load_flags,
no_arg_trigger,
openHelp,
qtMenuShortcutWorkaround,
@ -136,7 +137,6 @@ class Browser(QMainWindow):
self.sidebar.refresh_if_needed()
def setupMenus(self) -> None:
# pylint: disable=unnecessary-lambda
# actions
f = self.form
# edit
@ -166,16 +166,15 @@ class Browser(QMainWindow):
qconnect(f.action_set_due_date.triggered, self.set_due_date)
qconnect(f.action_forget.triggered, self.forget_cards)
qconnect(f.actionToggle_Suspend.triggered, self.suspend_selected_cards)
qconnect(f.actionRed_Flag.triggered, lambda: self.set_flag_of_selected_cards(1))
qconnect(
f.actionOrange_Flag.triggered, lambda: self.set_flag_of_selected_cards(2)
)
qconnect(
f.actionGreen_Flag.triggered, lambda: self.set_flag_of_selected_cards(3)
)
qconnect(
f.actionBlue_Flag.triggered, lambda: self.set_flag_of_selected_cards(4)
)
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):
qconnect(
getattr(self.form, flag.action).triggered, set_flag_func(flag.index)
)
self._update_flag_labels()
qconnect(f.actionExport.triggered, self._on_export_notes)
# jumps
qconnect(f.actionPreviousCard.triggered, self.onPreviousCard)
@ -711,18 +710,15 @@ where id in %s"""
flag = self.card and self.card.user_flag()
flag = flag or 0
flagActions = [
self.form.actionRed_Flag,
self.form.actionOrange_Flag,
self.form.actionGreen_Flag,
self.form.actionBlue_Flag,
]
for c, act in enumerate(flagActions):
act.setChecked(flag == c + 1)
for f in load_flags(self.col):
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):
getattr(self.form, flag.action).setText(flag.label)
def toggle_mark_of_selected_notes(self, checked: bool) -> None:
if checked:
self.add_tags_to_selected_notes(tags=MARKED_TAG)

View File

@ -40,6 +40,7 @@ class SidebarItemType(Enum):
def is_editable(self) -> bool:
return self in (
SidebarItemType.FLAG,
SidebarItemType.SAVED_SEARCH,
SidebarItemType.DECK,
SidebarItemType.TAG,

View File

@ -35,7 +35,14 @@ from aqt.operations.tag import (
)
from aqt.qt import *
from aqt.theme import ColoredIcon, theme_manager
from aqt.utils import KeyboardModifiersPressed, askUser, getOnlyText, showWarning, tr
from aqt.utils import (
KeyboardModifiersPressed,
askUser,
getOnlyText,
load_flags,
showWarning,
tr,
)
class SidebarStage(Enum):
@ -361,6 +368,8 @@ class SidebarTreeView(QTreeView):
self.rename_saved_search(item, new_name)
elif item.item_type == SidebarItemType.TAG:
self.rename_tag(item, new_name)
elif item.item_type == SidebarItemType.FLAG:
self.rename_flag(item, new_name)
# renaming may be asynchronous so always return False
return False
@ -600,35 +609,21 @@ class SidebarTreeView(QTreeView):
)
root.search_node = SearchNode(flag=SearchNode.FLAG_ANY)
type = SidebarItemType.FLAG
root.add_simple(
tr.actions_red_flag(),
icon=icon.with_color(colors.FLAG1_FG),
type=type,
search_node=SearchNode(flag=SearchNode.FLAG_RED),
)
root.add_simple(
tr.actions_orange_flag(),
icon=icon.with_color(colors.FLAG2_FG),
type=type,
search_node=SearchNode(flag=SearchNode.FLAG_ORANGE),
)
root.add_simple(
tr.actions_green_flag(),
icon=icon.with_color(colors.FLAG3_FG),
type=type,
search_node=SearchNode(flag=SearchNode.FLAG_GREEN),
)
root.add_simple(
tr.actions_blue_flag(),
icon=icon.with_color(colors.FLAG4_FG),
type=type,
search_node=SearchNode(flag=SearchNode.FLAG_BLUE),
)
for flag in load_flags(self.col):
root.add_child(
SidebarItem(
name=flag.label,
icon=flag.icon,
search_node=flag.search_node,
item_type=SidebarItemType.FLAG,
id=flag.index,
)
)
root.add_simple(
tr.browsing_no_flag(),
icon=icon.with_color(colors.DISABLED),
type=type,
icon=icon,
type=SidebarItemType.FLAG,
search_node=SearchNode(flag=SearchNode.FLAG_NONE),
)
@ -872,6 +867,17 @@ class SidebarTreeView(QTreeView):
lambda: set_children_expanded(False),
)
# Flags
###########################
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()
# Decks
###########################

View File

@ -51,7 +51,14 @@ from aqt.qt import *
from aqt.sound import av_player, play_clicked_audio, record_audio
from aqt.theme import theme_manager
from aqt.toolbar import BottomBar
from aqt.utils import askUserDialog, downArrow, qtMenuShortcutWorkaround, tooltip, tr
from aqt.utils import (
askUserDialog,
downArrow,
load_flags,
qtMenuShortcutWorkaround,
tooltip,
tr,
)
from aqt.webview import AnkiWebView
@ -443,7 +450,7 @@ class Reviewer:
def _shortcutKeys(
self,
) -> List[Union[Tuple[str, Callable], Tuple[Qt.Key, Callable]]]:
) -> Sequence[Union[Tuple[str, Callable], Tuple[Qt.Key, Callable]]]:
return [
("e", self.mw.onEditCurrent),
(" ", self.onEnterKey),
@ -452,10 +459,10 @@ class Reviewer:
("m", self.showContextMenu),
("r", self.replayAudio),
(Qt.Key_F5, self.replayAudio),
("Ctrl+1", lambda: self.set_flag_on_current_card(1)),
("Ctrl+2", lambda: self.set_flag_on_current_card(2)),
("Ctrl+3", lambda: self.set_flag_on_current_card(3)),
("Ctrl+4", lambda: self.set_flag_on_current_card(4)),
*(
(f"Ctrl+{flag.index}", self.set_flag_func(flag.index))
for flag in load_flags(self.mw.col)
),
("*", self.toggle_mark_on_current_note),
("=", self.bury_current_note),
("-", self.bury_current_card),
@ -905,29 +912,12 @@ time = %(time)d;
tr.studying_flag_card(),
[
[
tr.actions_red_flag(),
"Ctrl+1",
lambda: self.set_flag_on_current_card(1),
dict(checked=currentFlag == 1),
],
[
tr.actions_orange_flag(),
"Ctrl+2",
lambda: self.set_flag_on_current_card(2),
dict(checked=currentFlag == 2),
],
[
tr.actions_green_flag(),
"Ctrl+3",
lambda: self.set_flag_on_current_card(3),
dict(checked=currentFlag == 3),
],
[
tr.actions_blue_flag(),
"Ctrl+4",
lambda: self.set_flag_on_current_card(4),
dict(checked=currentFlag == 4),
],
flag.label,
f"Ctrl+{flag.index}",
self.set_flag_func(flag.index),
dict(checked=currentFlag == flag.index),
]
for flag in load_flags(self.mw.col)
],
],
[tr.studying_mark_note(), "*", self.toggle_mark_on_current_note],
@ -998,6 +988,9 @@ time = %(time)d;
redraw_flag
).run_in_background(initiator=self)
def set_flag_func(self, desired_flag: int) -> Callable:
return lambda: self.set_flag_on_current_card(desired_flag)
def toggle_mark_on_current_note(self) -> None:
def redraw_mark(out: OpChangesWithCount) -> None:
self.card.load()

View File

@ -6,12 +6,14 @@ import os
import re
import subprocess
import sys
from dataclasses import dataclass
from enum import Enum
from functools import wraps
from typing import (
TYPE_CHECKING,
Any,
Callable,
Dict,
List,
Literal,
Optional,
@ -35,10 +37,12 @@ from PyQt5.QtWidgets import (
import aqt
from anki import Collection
from anki.collection import SearchNode
from anki.lang import TR, tr_legacyglobal # pylint: disable=unused-import
from anki.utils import invalidFilename, isMac, isWin, noBundledLibs, versionWithBuild
from aqt import colors
from aqt.qt import *
from aqt.theme import theme_manager
from aqt.theme import ColoredIcon, theme_manager
if TYPE_CHECKING:
TextFormat = Union[Literal["plain", "rich"]]
@ -1023,6 +1027,51 @@ def no_arg_trigger(func: Callable) -> Callable:
return pyqtSlot()(func) # type: ignore
@dataclass
class Flag:
index: int
label: str
icon: ColoredIcon
search_node: SearchNode
action: str
def load_flags(col: Collection) -> List[Flag]:
labels = cast(Dict[str, str], col.get_config("flagLabels", {}))
icon = ColoredIcon(path=":/icons/flag.svg", color=colors.DISABLED)
return [
Flag(
1,
labels["1"] if "1" in labels else tr.actions_red_flag(),
icon.with_color(colors.FLAG1_FG),
SearchNode(flag=SearchNode.FLAG_RED),
"actionRed_Flag",
),
Flag(
2,
labels["2"] if "2" in labels else tr.actions_orange_flag(),
icon.with_color(colors.FLAG2_FG),
SearchNode(flag=SearchNode.FLAG_ORANGE),
"actionOrange_Flag",
),
Flag(
3,
labels["3"] if "3" in labels else tr.actions_green_flag(),
icon.with_color(colors.FLAG3_FG),
SearchNode(flag=SearchNode.FLAG_GREEN),
"actionGreen_Flag",
),
Flag(
4,
labels["4"] if "4" in labels else tr.actions_blue_flag(),
icon.with_color(colors.FLAG4_FG),
SearchNode(flag=SearchNode.FLAG_BLUE),
"actionBlue_Flag",
),
]
class KeyboardModifiersPressed:
"Util for type-safe checks of currently-pressed modifier keys."