diff --git a/pylib/.pylintrc b/pylib/.pylintrc
index e8b5122bd..bcd91244d 100644
--- a/pylib/.pylintrc
+++ b/pylib/.pylintrc
@@ -11,6 +11,9 @@ ignored-classes=
BuryOrSuspendCardsIn,
NoteIsDuplicateOrEmptyOut
+[REPORTS]
+output-format=colorized
+
[MESSAGES CONTROL]
disable=C,R,
fixme,
diff --git a/pylib/anki/importing/anki2.py b/pylib/anki/importing/anki2.py
index 4cb4e9853..b5f4ca44f 100644
--- a/pylib/anki/importing/anki2.py
+++ b/pylib/anki/importing/anki2.py
@@ -138,7 +138,7 @@ class Anki2Importer(Importer):
else:
dupesIdentical.append(note)
- self.log.append(self.dst.tr(TR.IMPORTING_NOTES_FOUND_IN_FILE, val=total))
+ self.log.append(self.dst.tr.importing_notes_found_in_file(val=total))
if dupesIgnored:
self.log.append(
@@ -153,9 +153,7 @@ class Anki2Importer(Importer):
)
)
if add:
- self.log.append(
- self.dst.tr(TR.IMPORTING_NOTES_ADDED_FROM_FILE, val=len(add))
- )
+ self.log.append(self.dst.tr.importing_notes_added_from_file(val=len(add)))
if dupesIdentical:
self.log.append(
self.dst.tr(
diff --git a/pylib/anki/importing/csvfile.py b/pylib/anki/importing/csvfile.py
index e4595a377..7bcd760b1 100644
--- a/pylib/anki/importing/csvfile.py
+++ b/pylib/anki/importing/csvfile.py
@@ -53,7 +53,7 @@ class TextImporter(NoteImporter):
note = self.noteFromFields(row)
notes.append(note)
except (csv.Error) as e:
- log.append(self.col.tr(TR.IMPORTING_ABORTED, val=str(e)))
+ log.append(self.col.tr.importing_aborted(val=str(e)))
self.log = log
self.ignored = ignored
self.close()
diff --git a/pylib/anki/importing/mnemo.py b/pylib/anki/importing/mnemo.py
index 5e0ca41bf..3f699799e 100644
--- a/pylib/anki/importing/mnemo.py
+++ b/pylib/anki/importing/mnemo.py
@@ -7,7 +7,6 @@ from typing import cast
from anki.db import DB
from anki.importing.noteimp import ForeignCard, ForeignNote, NoteImporter
-from anki.lang import TR
from anki.stdmodels import addBasicModel, addClozeModel
@@ -103,7 +102,7 @@ acq_reps+ret_reps, lapses, card_type_id from cards"""
self.total += total
self._addCloze(cloze)
self.total += total
- self.log.append(self.col.tr(TR.IMPORTING_NOTE_IMPORTED, count=self.total))
+ self.log.append(self.col.tr.importing_note_imported(count=self.total))
def fields(self):
return self._fields
diff --git a/pylib/anki/importing/noteimp.py b/pylib/anki/importing/noteimp.py
index 1865fac1d..125450bbb 100644
--- a/pylib/anki/importing/noteimp.py
+++ b/pylib/anki/importing/noteimp.py
@@ -152,16 +152,14 @@ class NoteImporter(Importer):
# first field must exist
if not fld0:
self.log.append(
- self.col.tr(TR.IMPORTING_EMPTY_FIRST_FIELD, val=" ".join(n.fields))
+ self.col.tr.importing_empty_first_field(val=" ".join(n.fields))
)
continue
csum = fieldChecksum(fld0)
# earlier in import?
if fld0 in firsts and self.importMode != ADD_MODE:
# duplicates in source file; log and ignore
- self.log.append(
- self.col.tr(TR.IMPORTING_APPEARED_TWICE_IN_FILE, val=fld0)
- )
+ self.log.append(self.col.tr.importing_appeared_twice_in_file(val=fld0))
continue
firsts[fld0] = True
# already exists?
@@ -221,15 +219,15 @@ class NoteImporter(Importer):
if conf["new"]["order"] == NEW_CARDS_RANDOM:
self.col.sched.randomizeCards(did)
- part1 = self.col.tr(TR.IMPORTING_NOTE_ADDED, count=len(new))
- part2 = self.col.tr(TR.IMPORTING_NOTE_UPDATED, count=self.updateCount)
+ part1 = self.col.tr.importing_note_added(count=len(new))
+ part2 = self.col.tr.importing_note_updated(count=self.updateCount)
if self.importMode == UPDATE_MODE:
unchanged = dupeCount - self.updateCount
elif self.importMode == IGNORE_MODE:
unchanged = dupeCount
else:
unchanged = 0
- part3 = self.col.tr(TR.IMPORTING_NOTE_UNCHANGED, count=unchanged)
+ part3 = self.col.tr.importing_note_unchanged(count=unchanged)
self.log.append(f"{part1}, {part2}, {part3}.")
self.log.extend(updateLog)
self.total = len(self._ids)
diff --git a/pylib/anki/latex.py b/pylib/anki/latex.py
index 7b6e2c0f5..217382491 100644
--- a/pylib/anki/latex.py
+++ b/pylib/anki/latex.py
@@ -12,7 +12,6 @@ from typing import Any, List, Optional, Tuple
import anki
import anki._backend.backend_pb2 as _pb
from anki import hooks
-from anki.lang import TR
from anki.models import NoteType
from anki.template import TemplateRenderContext, TemplateRenderOutput
from anki.utils import call, isMac, namedtmp, tmpdir
@@ -129,7 +128,7 @@ def _save_latex_image(
# don't mind if the sequence is only part of a command
bad_re = f"\\{bad}[^a-zA-Z]"
if re.search(bad_re, tmplatex):
- return col.tr(TR.MEDIA_FOR_SECURITY_REASONS_IS_NOT, val=bad)
+ return col.tr.media_for_security_reasons_is_not(val=bad)
# commands to use
if svg:
@@ -165,8 +164,8 @@ def _save_latex_image(
def _errMsg(col: anki.collection.Collection, type: str, texpath: str) -> Any:
- msg = f"{col.tr(TR.MEDIA_ERROR_EXECUTING, val=type)}
"
- msg += f"{col.tr(TR.MEDIA_GENERATED_FILE, val=texpath)}
"
+ msg = f"{col.tr.media_error_executing(val=type)}
"
+ msg += f"{col.tr.media_generated_file(val=texpath)}
"
try:
with open(namedtmp("latex_log.txt", rm=False)) as f:
log = f.read()
diff --git a/pylib/anki/models.py b/pylib/anki/models.py
index 1050f9faa..2a3337b2c 100644
--- a/pylib/anki/models.py
+++ b/pylib/anki/models.py
@@ -14,7 +14,7 @@ import anki # pylint: disable=unused-import
import anki._backend.backend_pb2 as _pb
from anki.consts import *
from anki.errors import NotFoundError
-from anki.lang import TR, without_unicode_isolation
+from anki.lang import without_unicode_isolation
from anki.stdmodels import StockNotetypeKind
from anki.utils import (
checksum,
@@ -276,7 +276,7 @@ class ModelManager:
"Copy, save and return."
m2 = copy.deepcopy(m)
m2["name"] = without_unicode_isolation(
- self.col.tr(TR.NOTETYPES_COPY, val=m2["name"])
+ self.col.tr.notetypes_copy(val=m2["name"])
)
m2["id"] = 0
self.add(m2)
diff --git a/pylib/anki/stats.py b/pylib/anki/stats.py
index ad844305d..bd7de3e44 100644
--- a/pylib/anki/stats.py
+++ b/pylib/anki/stats.py
@@ -246,7 +246,7 @@ from revlog where id > ? """
self._line(
i,
"Total",
- self.col.tr(TR.STATISTICS_REVIEWS, reviews=tot),
+ self.col.tr.statistics_reviews(reviews=tot),
)
self._line(i, "Average", self._avgDay(tot, num, "reviews"))
tomorrow = self.col.db.scalar(
diff --git a/pylib/tests/test_collection.py b/pylib/tests/test_collection.py
index 81d790628..90a2c462e 100644
--- a/pylib/tests/test_collection.py
+++ b/pylib/tests/test_collection.py
@@ -154,8 +154,8 @@ def test_translate():
col.tr.card_template_rendering_front_side_problem()
== "Front template has a problem:"
)
- assert no_uni(col.tr(TR.STATISTICS_REVIEWS, reviews=1)) == "1 review"
- assert no_uni(col.tr(TR.STATISTICS_REVIEWS, reviews=2)) == "2 reviews"
+ assert no_uni(col.tr.statistics_reviews(reviews=1)) == "1 review"
+ assert no_uni(col.tr.statistics_reviews(reviews=2)) == "2 reviews"
def test_db_named_args(capsys):
diff --git a/pylib/tools/rewrite_tr.py b/pylib/tools/rewrite_tr.py
index a6f7856b8..b91aa8f6c 100644
--- a/pylib/tools/rewrite_tr.py
+++ b/pylib/tools/rewrite_tr.py
@@ -9,12 +9,13 @@ from re import Match
import stringcase
-TR_REF = re.compile(r"tr\(TR.([^,)]+)\)")
+TR_REF = re.compile(r"tr\(TR.([^,) ]+),\s*([^)]+)\)")
def repl(m: Match) -> str:
name = m.group(1).lower()
- return f"tr.{name}()"
+ args = m.group(2)
+ return f"tr.{name}({args})"
def update_py(path: str) -> None:
diff --git a/qt/aqt/about.py b/qt/aqt/about.py
index b286b9d14..662b7862e 100644
--- a/qt/aqt/about.py
+++ b/qt/aqt/about.py
@@ -95,14 +95,14 @@ def show(mw: aqt.AnkiQt) -> QDialog:
abouttext = "
"
abouttext += f"{tr.about_anki_is_a_friendly_intelligent_spaced()}"
abouttext += f"
{tr.about_anki_is_licensed_under_the_agpl3()}"
- abouttext += f"
{tr(TR.ABOUT_VERSION, val=versionWithBuild())}
"
+ abouttext += f"
{tr.about_version(val=versionWithBuild())}
"
abouttext += ("Python %s Qt %s PyQt %s
") % (
platform.python_version(),
QT_VERSION_STR,
PYQT_VERSION_STR,
)
abouttext += (
- without_unicode_isolation(tr(TR.ABOUT_VISIT_WEBSITE, val=aqt.appWebsite))
+ without_unicode_isolation(tr.about_visit_website(val=aqt.appWebsite))
+ ""
)
diff --git a/qt/aqt/addcards.py b/qt/aqt/addcards.py
index 0f1231d7d..6b7be39a1 100644
--- a/qt/aqt/addcards.py
+++ b/qt/aqt/addcards.py
@@ -18,7 +18,6 @@ from aqt.notetypechooser import NoteTypeChooser
from aqt.qt import *
from aqt.sound import av_player
from aqt.utils import (
- TR,
HelpPage,
addCloseShortcut,
askUser,
@@ -100,7 +99,7 @@ class AddCards(QDialog):
else:
sc = "Ctrl+H"
b.setShortcut(QKeySequence(sc))
- b.setToolTip(tr(TR.ADDING_SHORTCUT, val=shortcut(sc)))
+ b.setToolTip(tr.adding_shortcut(val=shortcut(sc)))
qconnect(b.clicked, self.onHistory)
b.setEnabled(False)
self.historyButton = b
@@ -170,7 +169,7 @@ class AddCards(QDialog):
txt = htmlToTextLine(", ".join(fields))
if len(txt) > 30:
txt = f"{txt[:30]}..."
- line = tr(TR.ADDING_EDIT, val=txt)
+ line = tr.adding_edit(val=txt)
line = gui_hooks.addcards_will_add_history_entry(line, note)
a = m.addAction(line)
qconnect(a.triggered, lambda b, nid=nid: self.editHistory(nid))
diff --git a/qt/aqt/addons.py b/qt/aqt/addons.py
index 607e912fd..b0294a288 100644
--- a/qt/aqt/addons.py
+++ b/qt/aqt/addons.py
@@ -433,7 +433,7 @@ class AddonManager:
return True
except OSError as e:
showWarning(
- tr(TR.ADDONS_UNABLE_TO_UPDATE_OR_DELETE_ADDON, val=str(e)),
+ tr.addons_unable_to_update_or_delete_addon(val=str(e)),
textFormat="plain",
)
return False
@@ -479,14 +479,12 @@ class AddonManager:
"manifest": tr.addons_invalid_addon_manifest(),
}
- msg = messages.get(
- result.errmsg, tr(TR.ADDONS_UNKNOWN_ERROR, val=result.errmsg)
- )
+ msg = messages.get(result.errmsg, tr.addons_unknown_error(val=result.errmsg))
if mode == "download":
- template = tr(TR.ADDONS_ERROR_DOWNLOADING_IDS_ERRORS, id=base, error=msg)
+ template = tr.addons_error_downloading_ids_errors(id=base, error=msg)
else:
- template = tr(TR.ADDONS_ERROR_INSTALLING_BASES_ERRORS, base=base, error=msg)
+ template = tr.addons_error_installing_bases_errors(base=base, error=msg)
return [template]
@@ -496,9 +494,9 @@ class AddonManager:
name = result.name or base
if mode == "download":
- template = tr(TR.ADDONS_DOWNLOADED_FNAMES, fname=name)
+ template = tr.addons_downloaded_fnames(fname=name)
else:
- template = tr(TR.ADDONS_INSTALLED_NAMES, name=name)
+ template = tr.addons_installed_names(name=name)
strings = [template]
@@ -754,7 +752,7 @@ class AddonsDialog(QDialog):
if not addon.enabled:
return f"{name} {tr.addons_disabled2()}"
elif not addon.compatible():
- return f"{name} {tr(TR.ADDONS_REQUIRES, val=self.compatible_string(addon))}"
+ return f"{name} {tr.addons_requires(val=self.compatible_string(addon))}"
return name
@@ -849,9 +847,7 @@ class AddonsDialog(QDialog):
selected = self.selectedAddons()
if not selected:
return
- if not askUser(
- tr(TR.ADDONS_DELETE_THE_NUMD_SELECTED_ADDON, count=len(selected))
- ):
+ if not askUser(tr.addons_delete_the_numd_selected_addon(count=len(selected))):
return
for dir in selected:
if not self.mgr.deleteAddon(dir):
@@ -1015,7 +1011,7 @@ def describe_log_entry(id_and_entry: DownloadLogEntry) -> str:
if entry.status_code in (403, 404):
buf += tr.addons_invalid_code_or_addon_not_available()
else:
- buf += tr(TR.QT_MISC_UNEXPECTED_RESPONSE_CODE, val=entry.status_code)
+ buf += tr.qt_misc_unexpected_response_code(val=entry.status_code)
else:
buf += (
tr.addons_please_check_your_internet_connection()
diff --git a/qt/aqt/browser.py b/qt/aqt/browser.py
index 3560e69d9..17b3d1fc6 100644
--- a/qt/aqt/browser.py
+++ b/qt/aqt/browser.py
@@ -739,7 +739,7 @@ class Browser(QMainWindow):
cur = len(self.model.cards)
self.setWindowTitle(
without_unicode_isolation(
- tr(TR.BROWSING_WINDOW_TITLE, total=cur, selected=selected)
+ tr.browsing_window_title(total=cur, selected=selected)
)
)
return selected
@@ -1162,7 +1162,7 @@ where id in %s"""
remove_notes(
mw=self.mw,
note_ids=nids,
- success=lambda _: tooltip(tr(TR.BROWSING_NOTE_DELETED, count=len(nids))),
+ success=lambda _: tooltip(tr.browsing_note_deleted(count=len(nids))),
)
# legacy
@@ -1216,7 +1216,7 @@ where id in %s"""
note_ids=self.selected_notes(),
space_separated_tags=tags,
success=lambda out: tooltip(
- tr(TR.BROWSING_NOTES_UPDATED, count=out.count), parent=self
+ tr.browsing_notes_updated(count=out.count), parent=self
),
)
@@ -1232,7 +1232,7 @@ where id in %s"""
note_ids=self.selected_notes(),
space_separated_tags=tags,
success=lambda out: tooltip(
- tr(TR.BROWSING_NOTES_UPDATED, count=out.count), parent=self
+ tr.browsing_notes_updated(count=out.count), parent=self
),
)
@@ -1482,9 +1482,9 @@ where id in %s"""
t = ""
groups = len(res)
notes = sum(len(r[1]) for r in res)
- part1 = tr(TR.BROWSING_GROUP, count=groups)
- part2 = tr(TR.BROWSING_NOTE_COUNT, count=notes)
- t += tr(TR.BROWSING_FOUND_AS_ACROSS_BS, part=part1, whole=part2)
+ part1 = tr.browsing_group(count=groups)
+ part2 = tr.browsing_note_count(count=notes)
+ t += tr.browsing_found_as_across_bs(part=part1, whole=part2)
t += "
"
for val, nids in res:
t += (
@@ -1495,7 +1495,7 @@ where id in %s"""
SearchNode(nids=SearchNode.IdList(ids=nids))
)
),
- tr(TR.BROWSING_NOTE_COUNT, count=len(nids)),
+ tr.browsing_note_count(count=len(nids)),
html.escape(val),
)
)
@@ -1682,7 +1682,7 @@ class ChangeModel(QDialog):
targets = [x["name"] for x in dst] + [tr.browsing_nothing()]
indices = {}
for i, x in enumerate(src):
- l.addWidget(QLabel(tr(TR.BROWSING_CHANGE_TO, val=x["name"])), i, 0)
+ l.addWidget(QLabel(tr.browsing_change_to(val=x["name"])), i, 0)
cb = QComboBox()
cb.addItems(targets)
idx = min(i, len(targets) - 1)
diff --git a/qt/aqt/clayout.py b/qt/aqt/clayout.py
index b18abf136..e6f90945c 100644
--- a/qt/aqt/clayout.py
+++ b/qt/aqt/clayout.py
@@ -68,7 +68,7 @@ class CardLayout(QDialog):
self.setupShortcuts()
self.setWindowTitle(
without_unicode_isolation(
- tr(TR.CARD_TEMPLATES_CARD_TYPES_FOR, val=self.model["name"])
+ tr.card_templates_card_types_for(val=self.model["name"])
)
)
disable_help_button(self)
@@ -230,7 +230,7 @@ class CardLayout(QDialog):
cnt = self.mw.col.models.useCount(self.model)
self.tform.changes_affect_label.setText(
- self.col.tr(TR.CARD_TEMPLATES_CHANGES_WILL_AFFECT_NOTES, count=cnt)
+ self.col.tr.card_templates_changes_will_affect_notes(count=cnt)
)
qconnect(tform.edit_area.textChanged, self.write_edits_to_template_and_redraw)
@@ -253,7 +253,7 @@ class CardLayout(QDialog):
qconnect(widg.returnPressed, self.on_search_next)
def setup_cloze_number_box(self) -> None:
- names = (tr(TR.CARD_TEMPLATES_CLOZE, val=n) for n in self.cloze_numbers)
+ names = (tr.card_templates_cloze(val=n) for n in self.cloze_numbers)
self.pform.cloze_number_combo.addItems(names)
try:
idx = self.cloze_numbers.index(self.ord + 1)
@@ -558,7 +558,7 @@ class CardLayout(QDialog):
card_cnt = fut.result()
template = self.current_template()
- cards = tr(TR.CARD_TEMPLATES_CARD_COUNT, count=card_cnt)
+ cards = tr.card_templates_card_count(count=card_cnt)
msg = tr(
TR.CARD_TEMPLATES_DELETE_THE_AS_CARD_TYPE_AND,
template=template["name"],
@@ -600,7 +600,7 @@ class CardLayout(QDialog):
template = self.current_template()
current_pos = self.templates.index(template) + 1
pos_txt = getOnlyText(
- tr(TR.CARD_TEMPLATES_ENTER_NEW_CARD_POSITION_1, val=n),
+ tr.card_templates_enter_new_card_position_1(val=n),
default=str(current_pos),
)
if not pos_txt:
@@ -623,7 +623,7 @@ class CardLayout(QDialog):
def _newCardName(self) -> str:
n = len(self.templates) + 1
while 1:
- name = without_unicode_isolation(tr(TR.CARD_TEMPLATES_CARD, val=n))
+ name = without_unicode_isolation(tr.card_templates_card(val=n))
if name not in [t["name"] for t in self.templates]:
break
n += 1
@@ -631,7 +631,7 @@ class CardLayout(QDialog):
def onAddCard(self) -> None:
cnt = self.mw.col.models.useCount(self.model)
- txt = tr(TR.CARD_TEMPLATES_THIS_WILL_CREATE_CARD_PROCEED, count=cnt)
+ txt = tr.card_templates_this_will_create_card_proceed(count=cnt)
if not askUser(txt):
return
if not self.change_tracker.mark_schema():
@@ -728,7 +728,7 @@ class CardLayout(QDialog):
d.setMinimumWidth(400)
l = QVBoxLayout()
lab = QLabel(
- tr(TR.CARD_TEMPLATES_ENTER_DECK_TO_PLACE_NEW, val="%s")
+ tr.card_templates_enter_deck_to_place_new(val="%s")
% self.current_template()["name"]
)
lab.setWordWrap(True)
diff --git a/qt/aqt/deck_ops.py b/qt/aqt/deck_ops.py
index 571b33519..d0eaa4eb1 100644
--- a/qt/aqt/deck_ops.py
+++ b/qt/aqt/deck_ops.py
@@ -6,7 +6,6 @@ from __future__ import annotations
from typing import Callable, Sequence
from anki.decks import DeckID
-from anki.lang import TR
from aqt import AnkiQt, QWidget
from aqt.main import PerformOpOptionalSuccessCallback
from aqt.utils import getOnlyText, tooltip, tr
@@ -21,7 +20,7 @@ def remove_decks(
mw.perform_op(
lambda: mw.col.decks.remove(deck_ids),
success=lambda out: tooltip(
- tr(TR.BROWSING_CARDS_DELETED, count=out.count), parent=parent
+ tr.browsing_cards_deleted(count=out.count), parent=parent
),
)
@@ -32,7 +31,7 @@ def reparent_decks(
mw.perform_op(
lambda: mw.col.decks.reparent(deck_ids=deck_ids, new_parent=new_parent),
success=lambda out: tooltip(
- tr(TR.BROWSING_REPARENTED_DECKS, count=out.count), parent=parent
+ tr.browsing_reparented_decks(count=out.count), parent=parent
),
)
diff --git a/qt/aqt/deckbrowser.py b/qt/aqt/deckbrowser.py
index e20960aa1..8b30494be 100644
--- a/qt/aqt/deckbrowser.py
+++ b/qt/aqt/deckbrowser.py
@@ -16,7 +16,7 @@ from aqt.deck_ops import add_deck_dialog, remove_decks, rename_deck, reparent_de
from aqt.qt import *
from aqt.sound import av_player
from aqt.toolbar import BottomBar
-from aqt.utils import TR, askUser, getOnlyText, openLink, shortcut, showInfo, tr
+from aqt.utils import askUser, getOnlyText, openLink, shortcut, showInfo, tr
class DeckBrowserBottomBar:
@@ -306,7 +306,7 @@ class DeckBrowser:
drawLinks = deepcopy(self.drawLinks)
for b in drawLinks:
if b[0]:
- b[0] = tr(TR.ACTIONS_SHORTCUT_KEY, val=shortcut(b[0]))
+ b[0] = tr.actions_shortcut_key(val=shortcut(b[0]))
buf += """
""" % tuple(
b
diff --git a/qt/aqt/deckconf.py b/qt/aqt/deckconf.py
index cd8346706..691c0798e 100644
--- a/qt/aqt/deckconf.py
+++ b/qt/aqt/deckconf.py
@@ -12,7 +12,6 @@ from anki.lang import without_unicode_isolation
from aqt import gui_hooks
from aqt.qt import *
from aqt.utils import (
- TR,
HelpPage,
askUser,
disable_help_button,
@@ -50,7 +49,7 @@ class DeckConf(QDialog):
self.onRestore,
)
self.setWindowTitle(
- without_unicode_isolation(tr(TR.ACTIONS_OPTIONS_FOR, val=self.deck["name"]))
+ without_unicode_isolation(tr.actions_options_for(val=self.deck["name"]))
)
disable_help_button(self)
# qt doesn't size properly with altered fonts otherwise
@@ -160,7 +159,7 @@ class DeckConf(QDialog):
self.loadConfs()
def setChildren(self) -> None:
- if not askUser(tr(TR.SCHEDULING_SET_ALL_DECKS_BELOW_TO, val=self.deck["name"])):
+ if not askUser(tr.scheduling_set_all_decks_below_to(val=self.deck["name"])):
return
for did in self.childDids:
deck = self.mw.col.decks.get(did)
@@ -168,7 +167,7 @@ class DeckConf(QDialog):
continue
deck["conf"] = self.deck["conf"]
self.mw.col.decks.save(deck)
- tooltip(tr(TR.SCHEDULING_DECK_UPDATED, count=len(self.childDids)))
+ tooltip(tr.scheduling_deck_updated(count=len(self.childDids)))
# Loading
##################################################
@@ -194,7 +193,7 @@ class DeckConf(QDialog):
lim = x
else:
lim = min(x, lim)
- return tr(TR.SCHEDULING_PARENT_LIMIT, val=lim)
+ return tr.scheduling_parent_limit(val=lim)
def loadConf(self) -> None:
self.conf = self.mw.col.decks.confForDid(self.deck["id"])
diff --git a/qt/aqt/editor.py b/qt/aqt/editor.py
index dc9054f0a..26aa542fe 100644
--- a/qt/aqt/editor.py
+++ b/qt/aqt/editor.py
@@ -965,7 +965,7 @@ class Editor:
filecontents = response.content
content_type = response.headers.get("content-type")
except (urllib.error.URLError, requests.exceptions.RequestException) as e:
- error_msg = tr(TR.EDITING_AN_ERROR_OCCURRED_WHILE_OPENING, val=str(e))
+ error_msg = tr.editing_an_error_occurred_while_opening(val=str(e))
return None
finally:
self.mw.progress.finish()
diff --git a/qt/aqt/emptycards.py b/qt/aqt/emptycards.py
index 3f0d7cedd..7b168f393 100644
--- a/qt/aqt/emptycards.py
+++ b/qt/aqt/emptycards.py
@@ -12,7 +12,7 @@ from anki.cards import CardID
from anki.collection import EmptyCardsReport
from aqt import gui_hooks
from aqt.qt import QDialog, QDialogButtonBox, qconnect
-from aqt.utils import TR, disable_help_button, restoreGeom, saveGeom, tooltip, tr
+from aqt.utils import disable_help_button, restoreGeom, saveGeom, tooltip, tr
def show_empty_cards(mw: aqt.main.AnkiQt) -> None:
@@ -83,7 +83,7 @@ class EmptyCardsDialog(QDialog):
count = fut.result()
finally:
self.close()
- tooltip(tr(TR.EMPTY_CARDS_DELETED_COUNT, cards=count))
+ tooltip(tr.empty_cards_deleted_count(cards=count))
self.mw.reset()
self.mw.taskman.run_in_background(delete, on_done)
diff --git a/qt/aqt/errors.py b/qt/aqt/errors.py
index 1bae9a867..13fff133d 100644
--- a/qt/aqt/errors.py
+++ b/qt/aqt/errors.py
@@ -11,7 +11,7 @@ from markdown import markdown
from aqt import mw
from aqt.main import AnkiQt
from aqt.qt import *
-from aqt.utils import TR, showText, showWarning, supportText, tr
+from aqt.utils import showText, showWarning, supportText, tr
if not os.environ.get("DEBUG"):
@@ -115,4 +115,4 @@ class ErrorHandler(QObject):
# highlight importance of first add-on:
addons[0] = f"{addons[0]}"
addons_str = ", ".join(addons)
- return f"{tr(TR.ADDONS_POSSIBLY_INVOLVED, addons=addons_str)}\n"
+ return f"{tr.addons_possibly_involved(addons=addons_str)}\n"
diff --git a/qt/aqt/exporting.py b/qt/aqt/exporting.py
index 347083408..9ffc76d32 100644
--- a/qt/aqt/exporting.py
+++ b/qt/aqt/exporting.py
@@ -16,7 +16,6 @@ from anki.decks import DeckID
from anki.exporting import Exporter, exporters
from aqt.qt import *
from aqt.utils import (
- TR,
checkInvalidFilename,
disable_help_button,
getSaveFile,
@@ -152,7 +151,7 @@ class ExportDialog(QDialog):
f = open(file, "wb")
f.close()
except OSError as e:
- showWarning(tr(TR.EXPORTING_COULDNT_SAVE_FILE, val=str(e)))
+ showWarning(tr.exporting_couldnt_save_file(val=str(e)))
else:
os.unlink(file)
@@ -160,7 +159,7 @@ class ExportDialog(QDialog):
def exported_media(cnt: int) -> None:
self.mw.taskman.run_on_main(
lambda: self.mw.progress.update(
- label=tr(TR.EXPORTING_EXPORTED_MEDIA_FILE, count=cnt)
+ label=tr.exporting_exported_media_file(count=cnt)
)
)
@@ -185,8 +184,8 @@ class ExportDialog(QDialog):
self.mw.reopen()
else:
if self.isTextNote:
- msg = tr(TR.EXPORTING_NOTE_EXPORTED, count=self.exporter.count)
+ msg = tr.exporting_note_exported(count=self.exporter.count)
else:
- msg = tr(TR.EXPORTING_CARD_EXPORTED, count=self.exporter.count)
+ msg = tr.exporting_card_exported(count=self.exporter.count)
tooltip(msg, period=3000)
QDialog.reject(self)
diff --git a/qt/aqt/fields.py b/qt/aqt/fields.py
index 881b65473..9fc0f35e4 100644
--- a/qt/aqt/fields.py
+++ b/qt/aqt/fields.py
@@ -12,7 +12,6 @@ from aqt import AnkiQt, gui_hooks
from aqt.qt import *
from aqt.schema_change_tracker import ChangeTracker
from aqt.utils import (
- TR,
HelpPage,
askUser,
disable_help_button,
@@ -39,7 +38,7 @@ class FieldDialog(QDialog):
self.form = aqt.forms.fields.Ui_Dialog()
self.form.setupUi(self)
self.setWindowTitle(
- without_unicode_isolation(tr(TR.FIELDS_FIELDS_FOR, val=self.model["name"]))
+ without_unicode_isolation(tr.fields_fields_for(val=self.model["name"]))
)
disable_help_button(self)
self.form.buttonBox.button(QDialogButtonBox.Help).setAutoDefault(False)
@@ -150,8 +149,8 @@ class FieldDialog(QDialog):
showWarning(tr.fields_notes_require_at_least_one_field())
return
count = self.mm.useCount(self.model)
- c = tr(TR.BROWSING_NOTE_COUNT, count=count)
- if not askUser(tr(TR.FIELDS_DELETE_FIELD_FROM, val=c)):
+ c = tr.browsing_note_count(count=count)
+ if not askUser(tr.fields_delete_field_from(val=c)):
return
if not self.change_tracker.mark_schema():
return
@@ -165,7 +164,7 @@ class FieldDialog(QDialog):
def onPosition(self, delta: int = -1) -> None:
idx = self.currentIdx
l = len(self.model["flds"])
- txt = getOnlyText(tr(TR.FIELDS_NEW_POSITION_1, val=l), default=str(idx + 1))
+ txt = getOnlyText(tr.fields_new_position_1(val=l), default=str(idx + 1))
if not txt:
return
try:
diff --git a/qt/aqt/filtered_deck.py b/qt/aqt/filtered_deck.py
index f2d321d07..21450e1aa 100644
--- a/qt/aqt/filtered_deck.py
+++ b/qt/aqt/filtered_deck.py
@@ -14,7 +14,6 @@ from aqt.qt import *
from aqt.scheduling_ops import add_or_update_filtered_deck
from aqt.theme import theme_manager
from aqt.utils import (
- TR,
HelpPage,
disable_help_button,
openHelp,
@@ -153,7 +152,7 @@ class FilteredDeckConfigDialog(QDialog):
form.filter2group.setVisible(show_second)
self.setWindowTitle(
- without_unicode_isolation(tr(TR.ACTIONS_OPTIONS_FOR, val=self.deck.name))
+ without_unicode_isolation(tr.actions_options_for(val=self.deck.name))
)
gui_hooks.filtered_deck_dialog_did_load_deck(self, deck)
diff --git a/qt/aqt/find_and_replace.py b/qt/aqt/find_and_replace.py
index 791c54671..4cbbd2349 100644
--- a/qt/aqt/find_and_replace.py
+++ b/qt/aqt/find_and_replace.py
@@ -6,7 +6,6 @@ from __future__ import annotations
from typing import List, Optional, Sequence
import aqt
-from anki.lang import TR
from anki.notes import NoteID
from aqt import AnkiQt, QWidget
from aqt.qt import QDialog, Qt
@@ -49,7 +48,7 @@ def find_and_replace(
match_case=match_case,
),
success=lambda out: tooltip(
- tr(TR.FINDREPLACE_NOTES_UPDATED, changed=out.count, total=len(note_ids)),
+ tr.findreplace_notes_updated(changed=out.count, total=len(note_ids)),
parent=parent,
),
)
@@ -74,7 +73,7 @@ def find_and_replace_tag(
match_case=match_case,
),
success=lambda out: tooltip(
- tr(TR.FINDREPLACE_NOTES_UPDATED, changed=out.count, total=len(note_ids)),
+ tr.findreplace_notes_updated(changed=out.count, total=len(note_ids)),
parent=parent,
),
)
diff --git a/qt/aqt/importing.py b/qt/aqt/importing.py
index 6727c805a..b70d0a2f7 100644
--- a/qt/aqt/importing.py
+++ b/qt/aqt/importing.py
@@ -18,7 +18,6 @@ from anki.importing.apkg import AnkiPackageImporter
from aqt import AnkiQt, gui_hooks
from aqt.qt import *
from aqt.utils import (
- TR,
HelpPage,
askUser,
disable_help_button,
@@ -44,7 +43,7 @@ class ChangeMap(QDialog):
n = 0
setCurrent = False
for field in self.model["flds"]:
- item = QListWidgetItem(tr(TR.IMPORTING_MAP_TO, val=field["name"]))
+ item = QListWidgetItem(tr.importing_map_to(val=field["name"]))
self.frm.fields.addItem(item)
if current == field["name"]:
setCurrent = True
@@ -177,7 +176,7 @@ class ImportDialog(QDialog):
d = tr.importing_colon()
else:
d = repr(d)
- txt = tr(TR.IMPORTING_FIELDS_SEPARATED_BY, val=d)
+ txt = tr.importing_fields_separated_by(val=d)
self.frm.autoDetect.setText(txt)
def accept(self) -> None:
@@ -260,12 +259,12 @@ class ImportDialog(QDialog):
self.grid.setSpacing(6)
fields = self.importer.fields()
for num in range(len(self.mapping)):
- text = tr(TR.IMPORTING_FIELD_OF_FILE_IS, val=num + 1)
+ text = tr.importing_field_of_file_is(val=num + 1)
self.grid.addWidget(QLabel(text), num, 0)
if self.mapping[num] == "_tags":
text = tr.importing_mapped_to_tags()
elif self.mapping[num]:
- text = tr(TR.IMPORTING_MAPPED_TO, val=self.mapping[num])
+ text = tr.importing_mapped_to(val=self.mapping[num])
else:
text = tr.importing_ignored()
self.grid.addWidget(QLabel(text), num, 1)
@@ -473,7 +472,7 @@ def _replaceWithApkg(mw: aqt.AnkiQt, filename: str, backup: bool) -> None:
):
mw.taskman.run_on_main(
lambda n=n: mw.progress.update( # type: ignore
- tr(TR.IMPORTING_PROCESSED_MEDIA_FILE, count=n)
+ tr.importing_processed_media_file(count=n)
)
)
size = z.getinfo(cStr).file_size
diff --git a/qt/aqt/main.py b/qt/aqt/main.py
index d993a88db..a1e8cee54 100644
--- a/qt/aqt/main.py
+++ b/qt/aqt/main.py
@@ -72,7 +72,6 @@ from aqt.sync import sync_collection, sync_login
from aqt.taskman import TaskManager
from aqt.theme import theme_manager
from aqt.utils import (
- TR,
HelpPage,
KeyboardModifiersPressed,
askUser,
@@ -151,7 +150,7 @@ class AnkiQt(QMainWindow):
self.setupAddons(args)
self.finish_ui_setup()
except:
- showInfo(tr(TR.QT_MISC_ERROR_DURING_STARTUP, val=traceback.format_exc()))
+ showInfo(tr.qt_misc_error_during_startup(val=traceback.format_exc()))
sys.exit(1)
# must call this after ui set up
if self.safeMode:
@@ -944,7 +943,7 @@ class AnkiQt(QMainWindow):
) -> str:
class_ = f"but {class_}"
if key:
- key = tr(TR.ACTIONS_SHORTCUT_KEY, val=key)
+ key = tr.actions_shortcut_key(val=key)
else:
key = ""
return """
@@ -1254,7 +1253,7 @@ title="%s" %s>%s""" % (
# full queue+gui reset required
self.reset()
- tooltip(tr(TR.UNDO_ACTION_UNDONE, action=name))
+ tooltip(tr.undo_action_undone(action=name))
gui_hooks.state_did_revert(name)
self.update_undo_actions()
if on_done:
@@ -1274,7 +1273,7 @@ title="%s" %s>%s""" % (
undo_action = None
if undo_action:
- undo_action = tr(TR.UNDO_UNDO_ACTION, val=undo_action)
+ undo_action = tr.undo_undo_action(val=undo_action)
self.form.actionUndo.setText(undo_action)
self.form.actionUndo.setEnabled(True)
gui_hooks.undo_state_did_change(True)
@@ -1289,7 +1288,7 @@ title="%s" %s>%s""" % (
undo_action = status.undo
if undo_action:
- undo_action = tr(TR.UNDO_UNDO_ACTION, val=undo_action)
+ undo_action = tr.undo_undo_action(val=undo_action)
self.form.actionUndo.setText(undo_action)
self.form.actionUndo.setEnabled(True)
gui_hooks.undo_state_did_change(True)
@@ -1459,8 +1458,8 @@ title="%s" %s>%s""" % (
if devMode:
print("clock is off; ignoring")
return
- diffText = tr(TR.QT_MISC_SECOND, count=diff)
- warn = tr(TR.QT_MISC_IN_ORDER_TO_ENSURE_YOUR_COLLECTION, val="%s") % diffText
+ diffText = tr.qt_misc_second(count=diff)
+ warn = tr.qt_misc_in_order_to_ensure_your_collection(val="%s") % diffText
showWarning(warn)
self.app.closeAllWindows()
diff --git a/qt/aqt/mediacheck.py b/qt/aqt/mediacheck.py
index 7e4ffcf31..deef4c47c 100644
--- a/qt/aqt/mediacheck.py
+++ b/qt/aqt/mediacheck.py
@@ -11,7 +11,6 @@ from typing import Iterable, List, Optional, Sequence, TypeVar
import aqt
from anki.collection import SearchNode
from anki.errors import Interrupted
-from anki.lang import TR
from anki.media import CheckMediaOut
from aqt.qt import *
from aqt.utils import (
@@ -163,7 +162,7 @@ class MediaChecker:
if self.progress_dialog.wantCancel:
return False
- self.mw.progress.update(tr(TR.MEDIA_CHECK_CHECKED, count=count))
+ self.mw.progress.update(tr.media_check_checked(count=count))
return True
def _on_trash_files(self, fnames: Sequence[str]) -> None:
@@ -181,13 +180,13 @@ class MediaChecker:
remaining -= len(chunk)
if time.time() - last_progress >= 0.3:
self.mw.progress.update(
- tr(TR.MEDIA_CHECK_FILES_REMAINING, count=remaining)
+ tr.media_check_files_remaining(count=remaining)
)
finally:
self.mw.progress.finish()
self.progress_dialog = None
- tooltip(tr(TR.MEDIA_CHECK_DELETE_UNUSED_COMPLETE, count=total))
+ tooltip(tr.media_check_delete_unused_complete(count=total))
def _on_empty_trash(self) -> None:
self.progress_dialog = self.mw.progress.start()
diff --git a/qt/aqt/models.py b/qt/aqt/models.py
index 20711e5f8..82d022e2a 100644
--- a/qt/aqt/models.py
+++ b/qt/aqt/models.py
@@ -13,7 +13,6 @@ from anki.notes import Note
from aqt import AnkiQt, gui_hooks
from aqt.qt import *
from aqt.utils import (
- TR,
HelpPage,
askUser,
disable_help_button,
@@ -127,7 +126,7 @@ class Models(QDialog):
self.models = notetypes
for m in self.models:
- mUse = tr(TR.BROWSING_NOTE_COUNT, count=m.use_count)
+ mUse = tr.browsing_note_count(count=m.use_count)
item = QListWidgetItem(f"{m.name} [{mUse}]")
self.form.modelsList.addItem(item)
self.form.modelsList.setCurrentRow(row)
@@ -179,7 +178,7 @@ class Models(QDialog):
frm.latexHeader.setText(nt["latexPre"])
frm.latexFooter.setText(nt["latexPost"])
d.setWindowTitle(
- without_unicode_isolation(tr(TR.ACTIONS_OPTIONS_FOR, val=nt["name"]))
+ without_unicode_isolation(tr.actions_options_for(val=nt["name"]))
)
qconnect(frm.buttonBox.helpRequested, lambda: openHelp(HelpPage.LATEX))
restoreGeom(d, "modelopts")
@@ -232,12 +231,12 @@ class AddModel(QDialog):
# standard models
self.models = []
for (name, func) in stdmodels.get_stock_notetypes(self.col):
- item = QListWidgetItem(tr(TR.NOTETYPES_ADD, val=name))
+ item = QListWidgetItem(tr.notetypes_add(val=name))
self.dialog.models.addItem(item)
self.models.append((True, func))
# add copies
for m in sorted(self.col.models.all(), key=itemgetter("name")):
- item = QListWidgetItem(tr(TR.NOTETYPES_CLONE, val=m["name"]))
+ item = QListWidgetItem(tr.notetypes_clone(val=m["name"]))
self.dialog.models.addItem(item)
self.models.append((False, m)) # type: ignore
self.dialog.models.setCurrentRow(0)
diff --git a/qt/aqt/overview.py b/qt/aqt/overview.py
index db79db38e..b1e626543 100644
--- a/qt/aqt/overview.py
+++ b/qt/aqt/overview.py
@@ -11,7 +11,7 @@ from aqt import gui_hooks
from aqt.scheduling_ops import empty_filtered_deck, rebuild_filtered_deck
from aqt.sound import av_player
from aqt.toolbar import BottomBar
-from aqt.utils import TR, askUserDialog, openLink, shortcut, tooltip, tr
+from aqt.utils import askUserDialog, openLink, shortcut, tooltip, tr
class OverviewBottomBar:
@@ -256,7 +256,7 @@ class Overview:
buf = ""
for b in links:
if b[0]:
- b[0] = tr(TR.ACTIONS_SHORTCUT_KEY, val=shortcut(b[0]))
+ b[0] = tr.actions_shortcut_key(val=shortcut(b[0]))
buf += """
""" % tuple(
b
diff --git a/qt/aqt/preferences.py b/qt/aqt/preferences.py
index 99ed7777a..31f8fd432 100644
--- a/qt/aqt/preferences.py
+++ b/qt/aqt/preferences.py
@@ -7,15 +7,7 @@ from anki.consts import newCardSchedulingLabels
from aqt import AnkiQt
from aqt.profiles import RecordingDriver, VideoDriver
from aqt.qt import *
-from aqt.utils import (
- TR,
- HelpPage,
- disable_help_button,
- openHelp,
- showInfo,
- showWarning,
- tr,
-)
+from aqt.utils import HelpPage, disable_help_button, openHelp, showInfo, showWarning, tr
class Preferences(QDialog):
@@ -282,7 +274,7 @@ for you than the default driver, please let us know on the Anki forums."""
def setup_video_driver(self) -> None:
self.video_drivers = VideoDriver.all_for_platform()
names = [
- tr(TR.PREFERENCES_VIDEO_DRIVER, driver=video_driver_name_for_platform(d))
+ tr.preferences_video_driver(driver=video_driver_name_for_platform(d))
for d in self.video_drivers
]
self.form.video_driver.addItems(names)
diff --git a/qt/aqt/previewer.py b/qt/aqt/previewer.py
index 606cd52cd..0a5ae6838 100644
--- a/qt/aqt/previewer.py
+++ b/qt/aqt/previewer.py
@@ -30,7 +30,7 @@ from aqt.qt import (
from aqt.reviewer import replay_audio
from aqt.sound import av_player, play_clicked_audio
from aqt.theme import theme_manager
-from aqt.utils import TR, disable_help_button, restoreGeom, saveGeom, tr
+from aqt.utils import disable_help_button, restoreGeom, saveGeom, tr
from aqt.webview import AnkiWebView
LastStateAndMod = Tuple[str, int, int]
@@ -89,12 +89,12 @@ class Previewer(QDialog):
)
self._replay.setAutoDefault(False)
self._replay.setShortcut(QKeySequence("R"))
- self._replay.setToolTip(tr(TR.ACTIONS_SHORTCUT_KEY, val="R"))
+ self._replay.setToolTip(tr.actions_shortcut_key(val="R"))
qconnect(self._replay.clicked, self._on_replay_audio)
both_sides_button = QCheckBox(tr.qt_misc_back_side_only())
both_sides_button.setShortcut(QKeySequence("B"))
- both_sides_button.setToolTip(tr(TR.ACTIONS_SHORTCUT_KEY, val="B"))
+ both_sides_button.setToolTip(tr.actions_shortcut_key(val="B"))
self.bbox.addButton(both_sides_button, QDialogButtonBox.ActionRole)
self._show_both_sides = self.mw.col.get_config_bool(
Config.Bool.PREVIEW_BOTH_SIDES
diff --git a/qt/aqt/profiles.py b/qt/aqt/profiles.py
index 02ab81c6a..4e83e611f 100644
--- a/qt/aqt/profiles.py
+++ b/qt/aqt/profiles.py
@@ -347,9 +347,7 @@ class ProfileManager:
os.rename(oldFolder, midFolder)
oldFolder = midFolder
else:
- showWarning(
- tr(TR.PROFILES_PLEASE_REMOVE_THE_FOLDER_AND, val=midFolder)
- )
+ showWarning(tr.profiles_please_remove_the_folder_and(val=midFolder))
self.name = oldName
return
else:
@@ -552,7 +550,7 @@ create table if not exists profiles
code = obj[1]
name = obj[0]
r = QMessageBox.question(
- None, "Anki", tr(TR.PROFILES_CONFIRM_LANG_CHOICE, lang=name), QMessageBox.Yes | QMessageBox.No, QMessageBox.No # type: ignore
+ None, "Anki", tr.profiles_confirm_lang_choice(lang=name), QMessageBox.Yes | QMessageBox.No, QMessageBox.No # type: ignore
)
if r != QMessageBox.Yes:
return self.setDefaultLang(f.lang.currentRow())
diff --git a/qt/aqt/reviewer.py b/qt/aqt/reviewer.py
index f3cffdb4b..21e6db977 100644
--- a/qt/aqt/reviewer.py
+++ b/qt/aqt/reviewer.py
@@ -33,14 +33,7 @@ from aqt.sound import av_player, play_clicked_audio, record_audio
from aqt.tag_ops import add_tags, remove_tags_for_notes
from aqt.theme import theme_manager
from aqt.toolbar import BottomBar
-from aqt.utils import (
- TR,
- askUserDialog,
- downArrow,
- qtMenuShortcutWorkaround,
- tooltip,
- tr,
-)
+from aqt.utils import askUserDialog, downArrow, qtMenuShortcutWorkaround, tooltip, tr
from aqt.webview import AnkiWebView
@@ -147,9 +140,9 @@ class Reviewer:
elapsed = self.mw.col.timeboxReached()
if elapsed:
assert not isinstance(elapsed, bool)
- part1 = tr(TR.STUDYING_CARD_STUDIED_IN, count=elapsed[1])
+ part1 = tr.studying_card_studied_in(count=elapsed[1])
mins = int(round(elapsed[0] / 60))
- part2 = tr(TR.STUDYING_MINUTE, count=mins)
+ part2 = tr.studying_minute(count=mins)
fin = tr.studying_finish()
diag = askUserDialog(f"{part1} {part2}", [tr.studying_continue(), fin])
diag.setIcon(QMessageBox.Information)
@@ -445,7 +438,7 @@ class Reviewer:
if clozeIdx:
warn = tr.studying_please_run_toolsempty_cards()
else:
- warn = tr(TR.STUDYING_TYPE_ANSWER_UNKNOWN_FIELD, val=fld)
+ warn = tr.studying_type_answer_unknown_field(val=fld)
return re.sub(self.typeAnsPat, warn, buf)
else:
# empty field, remove type answer pattern
@@ -626,7 +619,7 @@ time = %(time)d;
""" % dict(
rem=self._remaining(),
edit=tr.studying_edit(),
- editkey=tr(TR.ACTIONS_SHORTCUT_KEY, val="E"),
+ editkey=tr.actions_shortcut_key(val="E"),
more=tr.studying_more(),
downArrow=downArrow(),
time=self.card.timeTaken() // 1000,
@@ -637,7 +630,7 @@ time = %(time)d;
%s
""" % (
self._remaining(),
- tr(TR.ACTIONS_SHORTCUT_KEY, val=tr.studying_space()),
+ tr.actions_shortcut_key(val=tr.studying_space()),
tr.studying_show_answer(),
)
# wrap it in a table so it has the same top margin as the ease buttons
@@ -717,7 +710,7 @@ time = %(time)d;
%s""" % (
due,
extra,
- tr(TR.ACTIONS_SHORTCUT_KEY, val=i),
+ tr.actions_shortcut_key(val=i),
i,
i,
label,
@@ -905,9 +898,7 @@ time = %(time)d;
remove_notes(
mw=self.mw,
note_ids=[self.card.nid],
- success=lambda _: tooltip(
- tr(TR.STUDYING_NOTE_AND_ITS_CARD_DELETED, count=cnt)
- ),
+ success=lambda _: tooltip(tr.studying_note_and_its_card_deleted(count=cnt)),
)
def onRecordVoice(self) -> None:
diff --git a/qt/aqt/scheduling_ops.py b/qt/aqt/scheduling_ops.py
index 053209d92..9c7402ea1 100644
--- a/qt/aqt/scheduling_ops.py
+++ b/qt/aqt/scheduling_ops.py
@@ -9,7 +9,6 @@ import aqt
from anki.cards import CardID
from anki.collection import CARD_TYPE_NEW, Config
from anki.decks import DeckID
-from anki.lang import TR
from anki.notes import NoteID
from anki.scheduler import FilteredDeckForUpdate
from aqt import AnkiQt
@@ -33,7 +32,7 @@ def set_due_date_dialog(
)
prompt = "\n".join(
[
- tr(TR.SCHEDULING_SET_DUE_DATE_PROMPT, cards=len(card_ids)),
+ tr.scheduling_set_due_date_prompt(cards=len(card_ids)),
tr.scheduling_set_due_date_prompt_hint(),
]
)
@@ -49,7 +48,7 @@ def set_due_date_dialog(
mw.perform_op(
lambda: mw.col.sched.set_due_date(card_ids, days, config_key),
success=lambda _: tooltip(
- tr(TR.SCHEDULING_SET_DUE_DATE_DONE, cards=len(card_ids)),
+ tr.scheduling_set_due_date_done(cards=len(card_ids)),
parent=parent,
),
)
@@ -62,7 +61,7 @@ def forget_cards(*, mw: aqt.AnkiQt, parent: QWidget, card_ids: List[CardID]) ->
mw.perform_op(
lambda: mw.col.sched.schedule_cards_as_new(card_ids),
success=lambda _: tooltip(
- tr(TR.SCHEDULING_FORGOT_CARDS, cards=len(card_ids)), parent=parent
+ tr.scheduling_forgot_cards(cards=len(card_ids)), parent=parent
),
)
@@ -85,8 +84,8 @@ def reposition_new_cards_dialog(
frm = aqt.forms.reposition.Ui_Dialog()
frm.setupUi(d)
- txt = tr(TR.BROWSING_QUEUE_TOP, val=min_position)
- txt += "\n" + tr(TR.BROWSING_QUEUE_BOTTOM, val=max_position)
+ txt = tr.browsing_queue_top(val=min_position)
+ txt += "\n" + tr.browsing_queue_bottom(val=max_position)
frm.label.setText(txt)
frm.start.selectAll()
@@ -128,7 +127,7 @@ def reposition_new_cards(
shift_existing=shift_existing,
),
success=lambda out: tooltip(
- tr(TR.BROWSING_CHANGED_NEW_POSITION, count=out.count), parent=parent
+ tr.browsing_changed_new_position(count=out.count), parent=parent
),
)
diff --git a/qt/aqt/sidebar.py b/qt/aqt/sidebar.py
index 4ae1cf931..3e7ef40b8 100644
--- a/qt/aqt/sidebar.py
+++ b/qt/aqt/sidebar.py
@@ -1235,7 +1235,7 @@ class SidebarTreeView(QTreeView):
if (
not update
and name in conf
- and not askUser(tr(TR.BROWSING_CONFIRM_SAVED_SEARCH_OVERWRITE, name=name))
+ and not askUser(tr.browsing_confirm_saved_search_overwrite(name=name))
):
return
conf[name] = search
@@ -1261,7 +1261,7 @@ class SidebarTreeView(QTreeView):
except KeyError:
return
if new_name in conf and not askUser(
- tr(TR.BROWSING_CONFIRM_SAVED_SEARCH_OVERWRITE, name=new_name)
+ tr.browsing_confirm_saved_search_overwrite(name=new_name)
):
return
conf[new_name] = filt
diff --git a/qt/aqt/sound.py b/qt/aqt/sound.py
index a32a09a5f..70c6981cf 100644
--- a/qt/aqt/sound.py
+++ b/qt/aqt/sound.py
@@ -29,7 +29,6 @@ from aqt.profiles import RecordingDriver
from aqt.qt import *
from aqt.taskman import TaskManager
from aqt.utils import (
- TR,
disable_help_button,
restoreGeom,
saveGeom,
@@ -483,9 +482,9 @@ def _encode_mp3(src_wav: str, dst_mp3: str) -> None:
try:
retcode = retryWait(subprocess.Popen(cmd, startupinfo=startup_info(), env=env))
except Exception as e:
- raise Exception(tr(TR.MEDIA_ERROR_RUNNING, val=" ").join(cmd)) from e
+ raise Exception(tr.media_error_running(val=" ").join(cmd)) from e
if retcode != 0:
- raise Exception(tr(TR.MEDIA_ERROR_RUNNING, val=" ").join(cmd))
+ raise Exception(tr.media_error_running(val=" ").join(cmd))
os.unlink(src_wav)
@@ -764,7 +763,7 @@ class RecordDialog(QDialog):
def _on_timer(self) -> None:
self._recorder.on_timer()
duration = self._recorder.duration()
- self.label.setText(tr(TR.MEDIA_RECORDINGTIME, secs=f"{duration:0.1f}"))
+ self.label.setText(tr.media_recordingtime(secs=f"{duration:0.1f}"))
def accept(self) -> None:
self._timer.stop()
diff --git a/qt/aqt/sync.py b/qt/aqt/sync.py
index 69a93c477..2f3350633 100644
--- a/qt/aqt/sync.py
+++ b/qt/aqt/sync.py
@@ -10,7 +10,7 @@ from typing import Callable, Tuple
import aqt
from anki.errors import Interrupted, SyncError
-from anki.lang import TR, without_unicode_isolation
+from anki.lang import without_unicode_isolation
from anki.sync import SyncOutput, SyncStatus
from anki.utils import platDesc
from aqt.qt import (
@@ -296,7 +296,7 @@ def get_id_and_pass_from_user(
vbox = QVBoxLayout()
info_label = QLabel(
without_unicode_isolation(
- tr(TR.SYNC_ACCOUNT_REQUIRED, link="https://ankiweb.net/account/register")
+ tr.sync_account_required(link="https://ankiweb.net/account/register")
)
)
info_label.setOpenExternalLinks(True)
diff --git a/qt/aqt/tag_ops.py b/qt/aqt/tag_ops.py
index 5f2d3c66c..4589e60c1 100644
--- a/qt/aqt/tag_ops.py
+++ b/qt/aqt/tag_ops.py
@@ -6,7 +6,6 @@ from __future__ import annotations
from typing import Callable, Sequence
from anki.collection import OpChangesWithCount
-from anki.lang import TR
from anki.notes import NoteID
from aqt import AnkiQt, QWidget
from aqt.main import PerformOpOptionalSuccessCallback
@@ -41,7 +40,7 @@ def clear_unused_tags(*, mw: AnkiQt, parent: QWidget) -> None:
mw.perform_op(
mw.col.tags.clear_unused_tags,
success=lambda out: tooltip(
- tr(TR.BROWSING_REMOVED_UNUSED_TAGS_COUNT, count=out.count), parent=parent
+ tr.browsing_removed_unused_tags_count(count=out.count), parent=parent
),
)
@@ -56,7 +55,7 @@ def rename_tag(
) -> None:
def success(out: OpChangesWithCount) -> None:
if out.count:
- tooltip(tr(TR.BROWSING_NOTES_UPDATED, count=out.count), parent=parent)
+ tooltip(tr.browsing_notes_updated(count=out.count), parent=parent)
else:
showInfo(tr.browsing_tag_rename_warning_empty(), parent=parent)
@@ -73,7 +72,7 @@ def remove_tags_for_all_notes(
mw.perform_op(
lambda: mw.col.tags.remove(space_separated_tags=space_separated_tags),
success=lambda out: tooltip(
- tr(TR.BROWSING_NOTES_UPDATED, count=out.count), parent=parent
+ tr.browsing_notes_updated(count=out.count), parent=parent
),
)
@@ -84,6 +83,6 @@ def reparent_tags(
mw.perform_op(
lambda: mw.col.tags.reparent(tags=tags, new_parent=new_parent),
success=lambda out: tooltip(
- tr(TR.BROWSING_NOTES_UPDATED, count=out.count), parent=parent
+ tr.browsing_notes_updated(count=out.count), parent=parent
),
)
diff --git a/qt/aqt/toolbar.py b/qt/aqt/toolbar.py
index 4decea84d..a8bd20bce 100644
--- a/qt/aqt/toolbar.py
+++ b/qt/aqt/toolbar.py
@@ -9,7 +9,7 @@ from anki.sync import SyncStatus
from aqt import gui_hooks
from aqt.qt import *
from aqt.sync import get_sync_status
-from aqt.utils import TR, tr
+from aqt.utils import tr
from aqt.webview import AnkiWebView
@@ -102,28 +102,28 @@ class Toolbar:
"decks",
tr.actions_decks(),
self._deckLinkHandler,
- tip=tr(TR.ACTIONS_SHORTCUT_KEY, val="D"),
+ tip=tr.actions_shortcut_key(val="D"),
id="decks",
),
self.create_link(
"add",
tr.actions_add(),
self._addLinkHandler,
- tip=tr(TR.ACTIONS_SHORTCUT_KEY, val="A"),
+ tip=tr.actions_shortcut_key(val="A"),
id="add",
),
self.create_link(
"browse",
tr.qt_misc_browse(),
self._browseLinkHandler,
- tip=tr(TR.ACTIONS_SHORTCUT_KEY, val="B"),
+ tip=tr.actions_shortcut_key(val="B"),
id="browse",
),
self.create_link(
"stats",
tr.qt_misc_stats(),
self._statsLinkHandler,
- tip=tr(TR.ACTIONS_SHORTCUT_KEY, val="T"),
+ tip=tr.actions_shortcut_key(val="T"),
id="stats",
),
]
@@ -139,7 +139,7 @@ class Toolbar:
def _create_sync_link(self) -> str:
name = tr.qt_misc_sync()
- title = tr(TR.ACTIONS_SHORTCUT_KEY, val="Y")
+ title = tr.actions_shortcut_key(val="Y")
label = "sync"
self.link_handlers[label] = self._syncLinkHandler
diff --git a/qt/aqt/update.py b/qt/aqt/update.py
index 5be7f6686..231660259 100644
--- a/qt/aqt/update.py
+++ b/qt/aqt/update.py
@@ -10,7 +10,7 @@ import aqt
from anki.utils import platDesc, versionWithBuild
from aqt.main import AnkiQt
from aqt.qt import *
-from aqt.utils import TR, openLink, showText, tr
+from aqt.utils import openLink, showText, tr
class LatestVersionFinder(QThread):
@@ -57,7 +57,7 @@ class LatestVersionFinder(QThread):
def askAndUpdate(mw: aqt.AnkiQt, ver: str) -> None:
- baseStr = tr(TR.QT_MISC_ANKI_UPDATEDANKI_HAS_BEEN_RELEASED, val=ver)
+ baseStr = tr.qt_misc_anki_updatedanki_has_been_released(val=ver)
msg = QMessageBox(mw)
msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No) # type: ignore
msg.setIcon(QMessageBox.Information)
diff --git a/qt/aqt/utils.py b/qt/aqt/utils.py
index 2a57f82c2..44416a0ee 100644
--- a/qt/aqt/utils.py
+++ b/qt/aqt/utils.py
@@ -803,7 +803,7 @@ def closeTooltip() -> None:
def checkInvalidFilename(str: str, dirsep: bool = True) -> bool:
bad = invalidFilename(str, dirsep)
if bad:
- showWarning(tr(TR.QT_MISC_THE_FOLLOWING_CHARACTER_CAN_NOT_BE, val=bad))
+ showWarning(tr.qt_misc_the_following_character_can_not_be(val=bad))
return True
return False