Merge pull request #1178 from RumovZ/flag-labels
Custom labels for flags
This commit is contained in:
commit
055f2907ec
@ -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)
|
||||
|
@ -40,6 +40,7 @@ class SidebarItemType(Enum):
|
||||
|
||||
def is_editable(self) -> bool:
|
||||
return self in (
|
||||
SidebarItemType.FLAG,
|
||||
SidebarItemType.SAVED_SEARCH,
|
||||
SidebarItemType.DECK,
|
||||
SidebarItemType.TAG,
|
||||
|
@ -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
|
||||
###########################
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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."
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user