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:
Ren Tatsumoto 2023-05-18 07:47:51 +00:00 committed by GitHub
parent f4f5844ca3
commit a378e2923e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 50 additions and 10 deletions

View file

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

View file

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

View file

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

View file

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

View file

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