mirror of
https://github.com/ankitects/anki.git
synced 2025-09-23 08:22:24 -04:00
Allow the user to configure answer keys (#2502)
* add methods that allow the user to configure answer keys * allow editing answer buttons in preferences * import optional * Give the layout referenced in code a clearer name (dae) * Update placeholder text and make it translatable (dae) The other items in the preferences screen don't have tooltips, so placeholder text may be easier for the user to discover than a tooltip.
This commit is contained in:
parent
f4f5844ca3
commit
a378e2923e
5 changed files with 50 additions and 10 deletions
|
@ -58,6 +58,7 @@ preferences-appearance = Appearance
|
|||
preferences-general = General
|
||||
preferences-style = Style
|
||||
preferences-review = Review
|
||||
preferences-answer-keys = Answer keys
|
||||
preferences-distractions = Distractions
|
||||
preferences-minimalist-mode = Minimalist mode
|
||||
preferences-editing = Editing
|
||||
|
@ -71,6 +72,7 @@ preferences-import-export = Import/Export
|
|||
preferences-network-timeout = Network timeout
|
||||
preferences-reset-window-sizes = Reset Window Sizes
|
||||
preferences-reset-window-sizes-complete = Window sizes and locations have been reset.
|
||||
preferences-shortcut-placeholder = Enter an unused shortcut key, or leave empty to disable.
|
||||
|
||||
## NO NEED TO TRANSLATE. This text is no longer used by Anki, and will be removed in the future.
|
||||
|
||||
|
|
|
@ -245,7 +245,7 @@
|
|||
<attribute name="title">
|
||||
<string>preferences_review</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<layout class="QVBoxLayout" name="review_options_layout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="schedulerGroup">
|
||||
<property name="title">
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# Copyright: Ankitects Pty Ltd and contributors
|
||||
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
import functools
|
||||
import re
|
||||
from typing import Any, cast
|
||||
|
||||
|
@ -47,8 +48,39 @@ class Preferences(QDialog):
|
|||
self.setup_collection()
|
||||
self.setup_profile()
|
||||
self.setup_global()
|
||||
self.setup_configurable_answer_keys()
|
||||
self.show()
|
||||
|
||||
def setup_configurable_answer_keys(self):
|
||||
"""
|
||||
Create a group box in Preferences with widgets that let the user edit answer keys.
|
||||
"""
|
||||
ease_labels = (
|
||||
(1, tr.studying_again()),
|
||||
(2, tr.studying_hard()),
|
||||
(3, tr.studying_good()),
|
||||
(4, tr.studying_easy()),
|
||||
)
|
||||
self.form.review_options_layout.addWidget(
|
||||
group := QGroupBox(tr.preferences_answer_keys())
|
||||
)
|
||||
group.setLayout(layout := QFormLayout())
|
||||
for ease, label in ease_labels:
|
||||
layout.addRow(
|
||||
label,
|
||||
line_edit := QLineEdit(self.mw.pm.get_answer_key(ease) or ""),
|
||||
)
|
||||
qconnect(
|
||||
line_edit.textChanged,
|
||||
functools.partial(self.mw.pm.set_answer_key, ease),
|
||||
)
|
||||
line_edit.setValidator(
|
||||
QRegularExpressionValidator(
|
||||
QRegularExpression(r"^[a-z0-9\]\[=,./;\'\\-]$")
|
||||
)
|
||||
)
|
||||
line_edit.setPlaceholderText(tr.preferences_shortcut_placeholder())
|
||||
|
||||
def accept(self) -> None:
|
||||
# avoid exception if main window is already closed
|
||||
if not self.mw.col:
|
||||
|
|
|
@ -10,7 +10,7 @@ import shutil
|
|||
import traceback
|
||||
from enum import Enum
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Any
|
||||
from typing import TYPE_CHECKING, Any, Optional
|
||||
|
||||
import anki.lang
|
||||
import aqt.forms
|
||||
|
@ -116,6 +116,8 @@ class LoadMetaResult:
|
|||
|
||||
|
||||
class ProfileManager:
|
||||
default_answer_keys = {ease_num: str(ease_num) for ease_num in range(1, 5)}
|
||||
|
||||
def __init__(self, base: Path) -> None: #
|
||||
"base should be retrieved via ProfileMangager.get_created_base_folder"
|
||||
## Settings which should be forgotten each Anki restart
|
||||
|
@ -537,6 +539,12 @@ create table if not exists profiles
|
|||
def set_spacebar_rates_card(self, on: bool) -> None:
|
||||
self.meta["spacebar_rates_card"] = on
|
||||
|
||||
def get_answer_key(self, ease: int) -> Optional[str]:
|
||||
return self.meta.setdefault("answer_keys", self.default_answer_keys).get(ease)
|
||||
|
||||
def set_answer_key(self, ease: int, key: str):
|
||||
self.meta.setdefault("answer_keys", self.default_answer_keys)[ease] = key
|
||||
|
||||
def hide_top_bar(self) -> bool:
|
||||
return self.meta.get("hide_top_bar", False)
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
import functools
|
||||
import json
|
||||
import random
|
||||
import re
|
||||
|
@ -507,14 +508,11 @@ class Reviewer:
|
|||
("o", self.onOptions),
|
||||
("i", self.on_card_info),
|
||||
("Ctrl+Alt+i", self.on_previous_card_info),
|
||||
("1", lambda: self._answerCard(1)),
|
||||
("2", lambda: self._answerCard(2)),
|
||||
("3", lambda: self._answerCard(3)),
|
||||
("4", lambda: self._answerCard(4)),
|
||||
("h", lambda: self._answerCard(1)),
|
||||
("j", lambda: self._answerCard(2)),
|
||||
("k", lambda: self._answerCard(3)),
|
||||
("l", lambda: self._answerCard(4)),
|
||||
*(
|
||||
(key, functools.partial(self._answerCard, ease))
|
||||
for ease in aqt.mw.pm.default_answer_keys
|
||||
if (key := aqt.mw.pm.get_answer_key(ease))
|
||||
),
|
||||
("u", self.mw.undo),
|
||||
("5", self.on_pause_audio),
|
||||
("6", self.on_seek_backward),
|
||||
|
|
Loading…
Reference in a new issue