update TR references that contain arguments

This commit is contained in:
Damien Elmes 2021-03-26 14:21:04 +10:00
parent 8294b18c68
commit b7587cb8d2
42 changed files with 139 additions and 178 deletions

View file

@ -11,6 +11,9 @@ ignored-classes=
BuryOrSuspendCardsIn, BuryOrSuspendCardsIn,
NoteIsDuplicateOrEmptyOut NoteIsDuplicateOrEmptyOut
[REPORTS]
output-format=colorized
[MESSAGES CONTROL] [MESSAGES CONTROL]
disable=C,R, disable=C,R,
fixme, fixme,

View file

@ -138,7 +138,7 @@ class Anki2Importer(Importer):
else: else:
dupesIdentical.append(note) 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: if dupesIgnored:
self.log.append( self.log.append(
@ -153,9 +153,7 @@ class Anki2Importer(Importer):
) )
) )
if add: if add:
self.log.append( self.log.append(self.dst.tr.importing_notes_added_from_file(val=len(add)))
self.dst.tr(TR.IMPORTING_NOTES_ADDED_FROM_FILE, val=len(add))
)
if dupesIdentical: if dupesIdentical:
self.log.append( self.log.append(
self.dst.tr( self.dst.tr(

View file

@ -53,7 +53,7 @@ class TextImporter(NoteImporter):
note = self.noteFromFields(row) note = self.noteFromFields(row)
notes.append(note) notes.append(note)
except (csv.Error) as e: 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.log = log
self.ignored = ignored self.ignored = ignored
self.close() self.close()

View file

@ -7,7 +7,6 @@ from typing import cast
from anki.db import DB from anki.db import DB
from anki.importing.noteimp import ForeignCard, ForeignNote, NoteImporter from anki.importing.noteimp import ForeignCard, ForeignNote, NoteImporter
from anki.lang import TR
from anki.stdmodels import addBasicModel, addClozeModel from anki.stdmodels import addBasicModel, addClozeModel
@ -103,7 +102,7 @@ acq_reps+ret_reps, lapses, card_type_id from cards"""
self.total += total self.total += total
self._addCloze(cloze) self._addCloze(cloze)
self.total += total 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): def fields(self):
return self._fields return self._fields

View file

@ -152,16 +152,14 @@ class NoteImporter(Importer):
# first field must exist # first field must exist
if not fld0: if not fld0:
self.log.append( 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 continue
csum = fieldChecksum(fld0) csum = fieldChecksum(fld0)
# earlier in import? # earlier in import?
if fld0 in firsts and self.importMode != ADD_MODE: if fld0 in firsts and self.importMode != ADD_MODE:
# duplicates in source file; log and ignore # duplicates in source file; log and ignore
self.log.append( self.log.append(self.col.tr.importing_appeared_twice_in_file(val=fld0))
self.col.tr(TR.IMPORTING_APPEARED_TWICE_IN_FILE, val=fld0)
)
continue continue
firsts[fld0] = True firsts[fld0] = True
# already exists? # already exists?
@ -221,15 +219,15 @@ class NoteImporter(Importer):
if conf["new"]["order"] == NEW_CARDS_RANDOM: if conf["new"]["order"] == NEW_CARDS_RANDOM:
self.col.sched.randomizeCards(did) self.col.sched.randomizeCards(did)
part1 = self.col.tr(TR.IMPORTING_NOTE_ADDED, count=len(new)) part1 = self.col.tr.importing_note_added(count=len(new))
part2 = self.col.tr(TR.IMPORTING_NOTE_UPDATED, count=self.updateCount) part2 = self.col.tr.importing_note_updated(count=self.updateCount)
if self.importMode == UPDATE_MODE: if self.importMode == UPDATE_MODE:
unchanged = dupeCount - self.updateCount unchanged = dupeCount - self.updateCount
elif self.importMode == IGNORE_MODE: elif self.importMode == IGNORE_MODE:
unchanged = dupeCount unchanged = dupeCount
else: else:
unchanged = 0 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.append(f"{part1}, {part2}, {part3}.")
self.log.extend(updateLog) self.log.extend(updateLog)
self.total = len(self._ids) self.total = len(self._ids)

View file

@ -12,7 +12,6 @@ from typing import Any, List, Optional, Tuple
import anki import anki
import anki._backend.backend_pb2 as _pb import anki._backend.backend_pb2 as _pb
from anki import hooks from anki import hooks
from anki.lang import TR
from anki.models import NoteType from anki.models import NoteType
from anki.template import TemplateRenderContext, TemplateRenderOutput from anki.template import TemplateRenderContext, TemplateRenderOutput
from anki.utils import call, isMac, namedtmp, tmpdir 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 # don't mind if the sequence is only part of a command
bad_re = f"\\{bad}[^a-zA-Z]" bad_re = f"\\{bad}[^a-zA-Z]"
if re.search(bad_re, tmplatex): 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 # commands to use
if svg: if svg:
@ -165,8 +164,8 @@ def _save_latex_image(
def _errMsg(col: anki.collection.Collection, type: str, texpath: str) -> Any: def _errMsg(col: anki.collection.Collection, type: str, texpath: str) -> Any:
msg = f"{col.tr(TR.MEDIA_ERROR_EXECUTING, val=type)}<br>" msg = f"{col.tr.media_error_executing(val=type)}<br>"
msg += f"{col.tr(TR.MEDIA_GENERATED_FILE, val=texpath)}<br>" msg += f"{col.tr.media_generated_file(val=texpath)}<br>"
try: try:
with open(namedtmp("latex_log.txt", rm=False)) as f: with open(namedtmp("latex_log.txt", rm=False)) as f:
log = f.read() log = f.read()

View file

@ -14,7 +14,7 @@ import anki # pylint: disable=unused-import
import anki._backend.backend_pb2 as _pb import anki._backend.backend_pb2 as _pb
from anki.consts import * from anki.consts import *
from anki.errors import NotFoundError 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.stdmodels import StockNotetypeKind
from anki.utils import ( from anki.utils import (
checksum, checksum,
@ -276,7 +276,7 @@ class ModelManager:
"Copy, save and return." "Copy, save and return."
m2 = copy.deepcopy(m) m2 = copy.deepcopy(m)
m2["name"] = without_unicode_isolation( 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 m2["id"] = 0
self.add(m2) self.add(m2)

View file

@ -246,7 +246,7 @@ from revlog where id > ? """
self._line( self._line(
i, i,
"Total", "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")) self._line(i, "Average", self._avgDay(tot, num, "reviews"))
tomorrow = self.col.db.scalar( tomorrow = self.col.db.scalar(

View file

@ -154,8 +154,8 @@ def test_translate():
col.tr.card_template_rendering_front_side_problem() col.tr.card_template_rendering_front_side_problem()
== "Front template has a problem:" == "Front template has a problem:"
) )
assert no_uni(col.tr(TR.STATISTICS_REVIEWS, reviews=1)) == "1 review" assert no_uni(col.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=2)) == "2 reviews"
def test_db_named_args(capsys): def test_db_named_args(capsys):

View file

@ -9,12 +9,13 @@ from re import Match
import stringcase import stringcase
TR_REF = re.compile(r"tr\(TR.([^,)]+)\)") TR_REF = re.compile(r"tr\(TR.([^,) ]+),\s*([^)]+)\)")
def repl(m: Match) -> str: def repl(m: Match) -> str:
name = m.group(1).lower() name = m.group(1).lower()
return f"tr.{name}()" args = m.group(2)
return f"tr.{name}({args})"
def update_py(path: str) -> None: def update_py(path: str) -> None:

View file

@ -95,14 +95,14 @@ def show(mw: aqt.AnkiQt) -> QDialog:
abouttext = "<center><img src='/_anki/imgs/anki-logo-thin.png'></center>" abouttext = "<center><img src='/_anki/imgs/anki-logo-thin.png'></center>"
abouttext += f"<p>{tr.about_anki_is_a_friendly_intelligent_spaced()}" abouttext += f"<p>{tr.about_anki_is_a_friendly_intelligent_spaced()}"
abouttext += f"<p>{tr.about_anki_is_licensed_under_the_agpl3()}" abouttext += f"<p>{tr.about_anki_is_licensed_under_the_agpl3()}"
abouttext += f"<p>{tr(TR.ABOUT_VERSION, val=versionWithBuild())}<br>" abouttext += f"<p>{tr.about_version(val=versionWithBuild())}<br>"
abouttext += ("Python %s Qt %s PyQt %s<br>") % ( abouttext += ("Python %s Qt %s PyQt %s<br>") % (
platform.python_version(), platform.python_version(),
QT_VERSION_STR, QT_VERSION_STR,
PYQT_VERSION_STR, PYQT_VERSION_STR,
) )
abouttext += ( abouttext += (
without_unicode_isolation(tr(TR.ABOUT_VISIT_WEBSITE, val=aqt.appWebsite)) without_unicode_isolation(tr.about_visit_website(val=aqt.appWebsite))
+ "</span>" + "</span>"
) )

View file

@ -18,7 +18,6 @@ from aqt.notetypechooser import NoteTypeChooser
from aqt.qt import * from aqt.qt import *
from aqt.sound import av_player from aqt.sound import av_player
from aqt.utils import ( from aqt.utils import (
TR,
HelpPage, HelpPage,
addCloseShortcut, addCloseShortcut,
askUser, askUser,
@ -100,7 +99,7 @@ class AddCards(QDialog):
else: else:
sc = "Ctrl+H" sc = "Ctrl+H"
b.setShortcut(QKeySequence(sc)) 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) qconnect(b.clicked, self.onHistory)
b.setEnabled(False) b.setEnabled(False)
self.historyButton = b self.historyButton = b
@ -170,7 +169,7 @@ class AddCards(QDialog):
txt = htmlToTextLine(", ".join(fields)) txt = htmlToTextLine(", ".join(fields))
if len(txt) > 30: if len(txt) > 30:
txt = f"{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) line = gui_hooks.addcards_will_add_history_entry(line, note)
a = m.addAction(line) a = m.addAction(line)
qconnect(a.triggered, lambda b, nid=nid: self.editHistory(nid)) qconnect(a.triggered, lambda b, nid=nid: self.editHistory(nid))

View file

@ -433,7 +433,7 @@ class AddonManager:
return True return True
except OSError as e: except OSError as e:
showWarning( 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", textFormat="plain",
) )
return False return False
@ -479,14 +479,12 @@ class AddonManager:
"manifest": tr.addons_invalid_addon_manifest(), "manifest": tr.addons_invalid_addon_manifest(),
} }
msg = messages.get( msg = messages.get(result.errmsg, tr.addons_unknown_error(val=result.errmsg))
result.errmsg, tr(TR.ADDONS_UNKNOWN_ERROR, val=result.errmsg)
)
if mode == "download": 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: 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] return [template]
@ -496,9 +494,9 @@ class AddonManager:
name = result.name or base name = result.name or base
if mode == "download": if mode == "download":
template = tr(TR.ADDONS_DOWNLOADED_FNAMES, fname=name) template = tr.addons_downloaded_fnames(fname=name)
else: else:
template = tr(TR.ADDONS_INSTALLED_NAMES, name=name) template = tr.addons_installed_names(name=name)
strings = [template] strings = [template]
@ -754,7 +752,7 @@ class AddonsDialog(QDialog):
if not addon.enabled: if not addon.enabled:
return f"{name} {tr.addons_disabled2()}" return f"{name} {tr.addons_disabled2()}"
elif not addon.compatible(): 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 return name
@ -849,9 +847,7 @@ class AddonsDialog(QDialog):
selected = self.selectedAddons() selected = self.selectedAddons()
if not selected: if not selected:
return return
if not askUser( if not askUser(tr.addons_delete_the_numd_selected_addon(count=len(selected))):
tr(TR.ADDONS_DELETE_THE_NUMD_SELECTED_ADDON, count=len(selected))
):
return return
for dir in selected: for dir in selected:
if not self.mgr.deleteAddon(dir): 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): if entry.status_code in (403, 404):
buf += tr.addons_invalid_code_or_addon_not_available() buf += tr.addons_invalid_code_or_addon_not_available()
else: 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: else:
buf += ( buf += (
tr.addons_please_check_your_internet_connection() tr.addons_please_check_your_internet_connection()

View file

@ -739,7 +739,7 @@ class Browser(QMainWindow):
cur = len(self.model.cards) cur = len(self.model.cards)
self.setWindowTitle( self.setWindowTitle(
without_unicode_isolation( without_unicode_isolation(
tr(TR.BROWSING_WINDOW_TITLE, total=cur, selected=selected) tr.browsing_window_title(total=cur, selected=selected)
) )
) )
return selected return selected
@ -1162,7 +1162,7 @@ where id in %s"""
remove_notes( remove_notes(
mw=self.mw, mw=self.mw,
note_ids=nids, 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 # legacy
@ -1216,7 +1216,7 @@ where id in %s"""
note_ids=self.selected_notes(), note_ids=self.selected_notes(),
space_separated_tags=tags, space_separated_tags=tags,
success=lambda out: tooltip( 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(), note_ids=self.selected_notes(),
space_separated_tags=tags, space_separated_tags=tags,
success=lambda out: tooltip( 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 = "" t = ""
groups = len(res) groups = len(res)
notes = sum(len(r[1]) for r in res) notes = sum(len(r[1]) for r in res)
part1 = tr(TR.BROWSING_GROUP, count=groups) part1 = tr.browsing_group(count=groups)
part2 = tr(TR.BROWSING_NOTE_COUNT, count=notes) part2 = tr.browsing_note_count(count=notes)
t += tr(TR.BROWSING_FOUND_AS_ACROSS_BS, part=part1, whole=part2) t += tr.browsing_found_as_across_bs(part=part1, whole=part2)
t += "<p><ol>" t += "<p><ol>"
for val, nids in res: for val, nids in res:
t += ( t += (
@ -1495,7 +1495,7 @@ where id in %s"""
SearchNode(nids=SearchNode.IdList(ids=nids)) SearchNode(nids=SearchNode.IdList(ids=nids))
) )
), ),
tr(TR.BROWSING_NOTE_COUNT, count=len(nids)), tr.browsing_note_count(count=len(nids)),
html.escape(val), html.escape(val),
) )
) )
@ -1682,7 +1682,7 @@ class ChangeModel(QDialog):
targets = [x["name"] for x in dst] + [tr.browsing_nothing()] targets = [x["name"] for x in dst] + [tr.browsing_nothing()]
indices = {} indices = {}
for i, x in enumerate(src): 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 = QComboBox()
cb.addItems(targets) cb.addItems(targets)
idx = min(i, len(targets) - 1) idx = min(i, len(targets) - 1)

View file

@ -68,7 +68,7 @@ class CardLayout(QDialog):
self.setupShortcuts() self.setupShortcuts()
self.setWindowTitle( self.setWindowTitle(
without_unicode_isolation( 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) disable_help_button(self)
@ -230,7 +230,7 @@ class CardLayout(QDialog):
cnt = self.mw.col.models.useCount(self.model) cnt = self.mw.col.models.useCount(self.model)
self.tform.changes_affect_label.setText( 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) 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) qconnect(widg.returnPressed, self.on_search_next)
def setup_cloze_number_box(self) -> None: 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) self.pform.cloze_number_combo.addItems(names)
try: try:
idx = self.cloze_numbers.index(self.ord + 1) idx = self.cloze_numbers.index(self.ord + 1)
@ -558,7 +558,7 @@ class CardLayout(QDialog):
card_cnt = fut.result() card_cnt = fut.result()
template = self.current_template() 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( msg = tr(
TR.CARD_TEMPLATES_DELETE_THE_AS_CARD_TYPE_AND, TR.CARD_TEMPLATES_DELETE_THE_AS_CARD_TYPE_AND,
template=template["name"], template=template["name"],
@ -600,7 +600,7 @@ class CardLayout(QDialog):
template = self.current_template() template = self.current_template()
current_pos = self.templates.index(template) + 1 current_pos = self.templates.index(template) + 1
pos_txt = getOnlyText( 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), default=str(current_pos),
) )
if not pos_txt: if not pos_txt:
@ -623,7 +623,7 @@ class CardLayout(QDialog):
def _newCardName(self) -> str: def _newCardName(self) -> str:
n = len(self.templates) + 1 n = len(self.templates) + 1
while 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]: if name not in [t["name"] for t in self.templates]:
break break
n += 1 n += 1
@ -631,7 +631,7 @@ class CardLayout(QDialog):
def onAddCard(self) -> None: def onAddCard(self) -> None:
cnt = self.mw.col.models.useCount(self.model) 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): if not askUser(txt):
return return
if not self.change_tracker.mark_schema(): if not self.change_tracker.mark_schema():
@ -728,7 +728,7 @@ class CardLayout(QDialog):
d.setMinimumWidth(400) d.setMinimumWidth(400)
l = QVBoxLayout() l = QVBoxLayout()
lab = QLabel( 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"] % self.current_template()["name"]
) )
lab.setWordWrap(True) lab.setWordWrap(True)

View file

@ -6,7 +6,6 @@ from __future__ import annotations
from typing import Callable, Sequence from typing import Callable, Sequence
from anki.decks import DeckID from anki.decks import DeckID
from anki.lang import TR
from aqt import AnkiQt, QWidget from aqt import AnkiQt, QWidget
from aqt.main import PerformOpOptionalSuccessCallback from aqt.main import PerformOpOptionalSuccessCallback
from aqt.utils import getOnlyText, tooltip, tr from aqt.utils import getOnlyText, tooltip, tr
@ -21,7 +20,7 @@ def remove_decks(
mw.perform_op( mw.perform_op(
lambda: mw.col.decks.remove(deck_ids), lambda: mw.col.decks.remove(deck_ids),
success=lambda out: tooltip( 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( mw.perform_op(
lambda: mw.col.decks.reparent(deck_ids=deck_ids, new_parent=new_parent), lambda: mw.col.decks.reparent(deck_ids=deck_ids, new_parent=new_parent),
success=lambda out: tooltip( success=lambda out: tooltip(
tr(TR.BROWSING_REPARENTED_DECKS, count=out.count), parent=parent tr.browsing_reparented_decks(count=out.count), parent=parent
), ),
) )

View file

@ -16,7 +16,7 @@ from aqt.deck_ops import add_deck_dialog, remove_decks, rename_deck, reparent_de
from aqt.qt import * from aqt.qt import *
from aqt.sound import av_player from aqt.sound import av_player
from aqt.toolbar import BottomBar 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: class DeckBrowserBottomBar:
@ -306,7 +306,7 @@ class DeckBrowser:
drawLinks = deepcopy(self.drawLinks) drawLinks = deepcopy(self.drawLinks)
for b in drawLinks: for b in drawLinks:
if b[0]: 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 += """ buf += """
<button title='%s' onclick='pycmd(\"%s\");'>%s</button>""" % tuple( <button title='%s' onclick='pycmd(\"%s\");'>%s</button>""" % tuple(
b b

View file

@ -12,7 +12,6 @@ from anki.lang import without_unicode_isolation
from aqt import gui_hooks from aqt import gui_hooks
from aqt.qt import * from aqt.qt import *
from aqt.utils import ( from aqt.utils import (
TR,
HelpPage, HelpPage,
askUser, askUser,
disable_help_button, disable_help_button,
@ -50,7 +49,7 @@ class DeckConf(QDialog):
self.onRestore, self.onRestore,
) )
self.setWindowTitle( 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) disable_help_button(self)
# qt doesn't size properly with altered fonts otherwise # qt doesn't size properly with altered fonts otherwise
@ -160,7 +159,7 @@ class DeckConf(QDialog):
self.loadConfs() self.loadConfs()
def setChildren(self) -> None: 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 return
for did in self.childDids: for did in self.childDids:
deck = self.mw.col.decks.get(did) deck = self.mw.col.decks.get(did)
@ -168,7 +167,7 @@ class DeckConf(QDialog):
continue continue
deck["conf"] = self.deck["conf"] deck["conf"] = self.deck["conf"]
self.mw.col.decks.save(deck) 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 # Loading
################################################## ##################################################
@ -194,7 +193,7 @@ class DeckConf(QDialog):
lim = x lim = x
else: else:
lim = min(x, lim) lim = min(x, lim)
return tr(TR.SCHEDULING_PARENT_LIMIT, val=lim) return tr.scheduling_parent_limit(val=lim)
def loadConf(self) -> None: def loadConf(self) -> None:
self.conf = self.mw.col.decks.confForDid(self.deck["id"]) self.conf = self.mw.col.decks.confForDid(self.deck["id"])

View file

@ -965,7 +965,7 @@ class Editor:
filecontents = response.content filecontents = response.content
content_type = response.headers.get("content-type") content_type = response.headers.get("content-type")
except (urllib.error.URLError, requests.exceptions.RequestException) as e: 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 return None
finally: finally:
self.mw.progress.finish() self.mw.progress.finish()

View file

@ -12,7 +12,7 @@ from anki.cards import CardID
from anki.collection import EmptyCardsReport from anki.collection import EmptyCardsReport
from aqt import gui_hooks from aqt import gui_hooks
from aqt.qt import QDialog, QDialogButtonBox, qconnect 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: def show_empty_cards(mw: aqt.main.AnkiQt) -> None:
@ -83,7 +83,7 @@ class EmptyCardsDialog(QDialog):
count = fut.result() count = fut.result()
finally: finally:
self.close() self.close()
tooltip(tr(TR.EMPTY_CARDS_DELETED_COUNT, cards=count)) tooltip(tr.empty_cards_deleted_count(cards=count))
self.mw.reset() self.mw.reset()
self.mw.taskman.run_in_background(delete, on_done) self.mw.taskman.run_in_background(delete, on_done)

View file

@ -11,7 +11,7 @@ from markdown import markdown
from aqt import mw from aqt import mw
from aqt.main import AnkiQt from aqt.main import AnkiQt
from aqt.qt import * 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"): if not os.environ.get("DEBUG"):
@ -115,4 +115,4 @@ class ErrorHandler(QObject):
# highlight importance of first add-on: # highlight importance of first add-on:
addons[0] = f"<b>{addons[0]}</b>" addons[0] = f"<b>{addons[0]}</b>"
addons_str = ", ".join(addons) 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"

View file

@ -16,7 +16,6 @@ from anki.decks import DeckID
from anki.exporting import Exporter, exporters from anki.exporting import Exporter, exporters
from aqt.qt import * from aqt.qt import *
from aqt.utils import ( from aqt.utils import (
TR,
checkInvalidFilename, checkInvalidFilename,
disable_help_button, disable_help_button,
getSaveFile, getSaveFile,
@ -152,7 +151,7 @@ class ExportDialog(QDialog):
f = open(file, "wb") f = open(file, "wb")
f.close() f.close()
except OSError as e: except OSError as e:
showWarning(tr(TR.EXPORTING_COULDNT_SAVE_FILE, val=str(e))) showWarning(tr.exporting_couldnt_save_file(val=str(e)))
else: else:
os.unlink(file) os.unlink(file)
@ -160,7 +159,7 @@ class ExportDialog(QDialog):
def exported_media(cnt: int) -> None: def exported_media(cnt: int) -> None:
self.mw.taskman.run_on_main( self.mw.taskman.run_on_main(
lambda: self.mw.progress.update( 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() self.mw.reopen()
else: else:
if self.isTextNote: if self.isTextNote:
msg = tr(TR.EXPORTING_NOTE_EXPORTED, count=self.exporter.count) msg = tr.exporting_note_exported(count=self.exporter.count)
else: else:
msg = tr(TR.EXPORTING_CARD_EXPORTED, count=self.exporter.count) msg = tr.exporting_card_exported(count=self.exporter.count)
tooltip(msg, period=3000) tooltip(msg, period=3000)
QDialog.reject(self) QDialog.reject(self)

View file

@ -12,7 +12,6 @@ from aqt import AnkiQt, gui_hooks
from aqt.qt import * from aqt.qt import *
from aqt.schema_change_tracker import ChangeTracker from aqt.schema_change_tracker import ChangeTracker
from aqt.utils import ( from aqt.utils import (
TR,
HelpPage, HelpPage,
askUser, askUser,
disable_help_button, disable_help_button,
@ -39,7 +38,7 @@ class FieldDialog(QDialog):
self.form = aqt.forms.fields.Ui_Dialog() self.form = aqt.forms.fields.Ui_Dialog()
self.form.setupUi(self) self.form.setupUi(self)
self.setWindowTitle( 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) disable_help_button(self)
self.form.buttonBox.button(QDialogButtonBox.Help).setAutoDefault(False) self.form.buttonBox.button(QDialogButtonBox.Help).setAutoDefault(False)
@ -150,8 +149,8 @@ class FieldDialog(QDialog):
showWarning(tr.fields_notes_require_at_least_one_field()) showWarning(tr.fields_notes_require_at_least_one_field())
return return
count = self.mm.useCount(self.model) count = self.mm.useCount(self.model)
c = tr(TR.BROWSING_NOTE_COUNT, count=count) c = tr.browsing_note_count(count=count)
if not askUser(tr(TR.FIELDS_DELETE_FIELD_FROM, val=c)): if not askUser(tr.fields_delete_field_from(val=c)):
return return
if not self.change_tracker.mark_schema(): if not self.change_tracker.mark_schema():
return return
@ -165,7 +164,7 @@ class FieldDialog(QDialog):
def onPosition(self, delta: int = -1) -> None: def onPosition(self, delta: int = -1) -> None:
idx = self.currentIdx idx = self.currentIdx
l = len(self.model["flds"]) 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: if not txt:
return return
try: try:

View file

@ -14,7 +14,6 @@ from aqt.qt import *
from aqt.scheduling_ops import add_or_update_filtered_deck from aqt.scheduling_ops import add_or_update_filtered_deck
from aqt.theme import theme_manager from aqt.theme import theme_manager
from aqt.utils import ( from aqt.utils import (
TR,
HelpPage, HelpPage,
disable_help_button, disable_help_button,
openHelp, openHelp,
@ -153,7 +152,7 @@ class FilteredDeckConfigDialog(QDialog):
form.filter2group.setVisible(show_second) form.filter2group.setVisible(show_second)
self.setWindowTitle( 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) gui_hooks.filtered_deck_dialog_did_load_deck(self, deck)

View file

@ -6,7 +6,6 @@ from __future__ import annotations
from typing import List, Optional, Sequence from typing import List, Optional, Sequence
import aqt import aqt
from anki.lang import TR
from anki.notes import NoteID from anki.notes import NoteID
from aqt import AnkiQt, QWidget from aqt import AnkiQt, QWidget
from aqt.qt import QDialog, Qt from aqt.qt import QDialog, Qt
@ -49,7 +48,7 @@ def find_and_replace(
match_case=match_case, match_case=match_case,
), ),
success=lambda out: tooltip( 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, parent=parent,
), ),
) )
@ -74,7 +73,7 @@ def find_and_replace_tag(
match_case=match_case, match_case=match_case,
), ),
success=lambda out: tooltip( 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, parent=parent,
), ),
) )

View file

@ -18,7 +18,6 @@ from anki.importing.apkg import AnkiPackageImporter
from aqt import AnkiQt, gui_hooks from aqt import AnkiQt, gui_hooks
from aqt.qt import * from aqt.qt import *
from aqt.utils import ( from aqt.utils import (
TR,
HelpPage, HelpPage,
askUser, askUser,
disable_help_button, disable_help_button,
@ -44,7 +43,7 @@ class ChangeMap(QDialog):
n = 0 n = 0
setCurrent = False setCurrent = False
for field in self.model["flds"]: 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) self.frm.fields.addItem(item)
if current == field["name"]: if current == field["name"]:
setCurrent = True setCurrent = True
@ -177,7 +176,7 @@ class ImportDialog(QDialog):
d = tr.importing_colon() d = tr.importing_colon()
else: else:
d = repr(d) 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) self.frm.autoDetect.setText(txt)
def accept(self) -> None: def accept(self) -> None:
@ -260,12 +259,12 @@ class ImportDialog(QDialog):
self.grid.setSpacing(6) self.grid.setSpacing(6)
fields = self.importer.fields() fields = self.importer.fields()
for num in range(len(self.mapping)): 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) self.grid.addWidget(QLabel(text), num, 0)
if self.mapping[num] == "_tags": if self.mapping[num] == "_tags":
text = tr.importing_mapped_to_tags() text = tr.importing_mapped_to_tags()
elif self.mapping[num]: elif self.mapping[num]:
text = tr(TR.IMPORTING_MAPPED_TO, val=self.mapping[num]) text = tr.importing_mapped_to(val=self.mapping[num])
else: else:
text = tr.importing_ignored() text = tr.importing_ignored()
self.grid.addWidget(QLabel(text), num, 1) 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( mw.taskman.run_on_main(
lambda n=n: mw.progress.update( # type: ignore 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 size = z.getinfo(cStr).file_size

View file

@ -72,7 +72,6 @@ from aqt.sync import sync_collection, sync_login
from aqt.taskman import TaskManager from aqt.taskman import TaskManager
from aqt.theme import theme_manager from aqt.theme import theme_manager
from aqt.utils import ( from aqt.utils import (
TR,
HelpPage, HelpPage,
KeyboardModifiersPressed, KeyboardModifiersPressed,
askUser, askUser,
@ -151,7 +150,7 @@ class AnkiQt(QMainWindow):
self.setupAddons(args) self.setupAddons(args)
self.finish_ui_setup() self.finish_ui_setup()
except: 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) sys.exit(1)
# must call this after ui set up # must call this after ui set up
if self.safeMode: if self.safeMode:
@ -944,7 +943,7 @@ class AnkiQt(QMainWindow):
) -> str: ) -> str:
class_ = f"but {class_}" class_ = f"but {class_}"
if key: if key:
key = tr(TR.ACTIONS_SHORTCUT_KEY, val=key) key = tr.actions_shortcut_key(val=key)
else: else:
key = "" key = ""
return """ return """
@ -1254,7 +1253,7 @@ title="%s" %s>%s</button>""" % (
# full queue+gui reset required # full queue+gui reset required
self.reset() self.reset()
tooltip(tr(TR.UNDO_ACTION_UNDONE, action=name)) tooltip(tr.undo_action_undone(action=name))
gui_hooks.state_did_revert(name) gui_hooks.state_did_revert(name)
self.update_undo_actions() self.update_undo_actions()
if on_done: if on_done:
@ -1274,7 +1273,7 @@ title="%s" %s>%s</button>""" % (
undo_action = None undo_action = None
if undo_action: 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.setText(undo_action)
self.form.actionUndo.setEnabled(True) self.form.actionUndo.setEnabled(True)
gui_hooks.undo_state_did_change(True) gui_hooks.undo_state_did_change(True)
@ -1289,7 +1288,7 @@ title="%s" %s>%s</button>""" % (
undo_action = status.undo undo_action = status.undo
if undo_action: 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.setText(undo_action)
self.form.actionUndo.setEnabled(True) self.form.actionUndo.setEnabled(True)
gui_hooks.undo_state_did_change(True) gui_hooks.undo_state_did_change(True)
@ -1459,8 +1458,8 @@ title="%s" %s>%s</button>""" % (
if devMode: if devMode:
print("clock is off; ignoring") print("clock is off; ignoring")
return return
diffText = tr(TR.QT_MISC_SECOND, count=diff) diffText = tr.qt_misc_second(count=diff)
warn = tr(TR.QT_MISC_IN_ORDER_TO_ENSURE_YOUR_COLLECTION, val="%s") % diffText warn = tr.qt_misc_in_order_to_ensure_your_collection(val="%s") % diffText
showWarning(warn) showWarning(warn)
self.app.closeAllWindows() self.app.closeAllWindows()

View file

@ -11,7 +11,6 @@ from typing import Iterable, List, Optional, Sequence, TypeVar
import aqt import aqt
from anki.collection import SearchNode from anki.collection import SearchNode
from anki.errors import Interrupted from anki.errors import Interrupted
from anki.lang import TR
from anki.media import CheckMediaOut from anki.media import CheckMediaOut
from aqt.qt import * from aqt.qt import *
from aqt.utils import ( from aqt.utils import (
@ -163,7 +162,7 @@ class MediaChecker:
if self.progress_dialog.wantCancel: if self.progress_dialog.wantCancel:
return False 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 return True
def _on_trash_files(self, fnames: Sequence[str]) -> None: def _on_trash_files(self, fnames: Sequence[str]) -> None:
@ -181,13 +180,13 @@ class MediaChecker:
remaining -= len(chunk) remaining -= len(chunk)
if time.time() - last_progress >= 0.3: if time.time() - last_progress >= 0.3:
self.mw.progress.update( self.mw.progress.update(
tr(TR.MEDIA_CHECK_FILES_REMAINING, count=remaining) tr.media_check_files_remaining(count=remaining)
) )
finally: finally:
self.mw.progress.finish() self.mw.progress.finish()
self.progress_dialog = None 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: def _on_empty_trash(self) -> None:
self.progress_dialog = self.mw.progress.start() self.progress_dialog = self.mw.progress.start()

View file

@ -13,7 +13,6 @@ from anki.notes import Note
from aqt import AnkiQt, gui_hooks from aqt import AnkiQt, gui_hooks
from aqt.qt import * from aqt.qt import *
from aqt.utils import ( from aqt.utils import (
TR,
HelpPage, HelpPage,
askUser, askUser,
disable_help_button, disable_help_button,
@ -127,7 +126,7 @@ class Models(QDialog):
self.models = notetypes self.models = notetypes
for m in self.models: 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}]") item = QListWidgetItem(f"{m.name} [{mUse}]")
self.form.modelsList.addItem(item) self.form.modelsList.addItem(item)
self.form.modelsList.setCurrentRow(row) self.form.modelsList.setCurrentRow(row)
@ -179,7 +178,7 @@ class Models(QDialog):
frm.latexHeader.setText(nt["latexPre"]) frm.latexHeader.setText(nt["latexPre"])
frm.latexFooter.setText(nt["latexPost"]) frm.latexFooter.setText(nt["latexPost"])
d.setWindowTitle( 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)) qconnect(frm.buttonBox.helpRequested, lambda: openHelp(HelpPage.LATEX))
restoreGeom(d, "modelopts") restoreGeom(d, "modelopts")
@ -232,12 +231,12 @@ class AddModel(QDialog):
# standard models # standard models
self.models = [] self.models = []
for (name, func) in stdmodels.get_stock_notetypes(self.col): 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.dialog.models.addItem(item)
self.models.append((True, func)) self.models.append((True, func))
# add copies # add copies
for m in sorted(self.col.models.all(), key=itemgetter("name")): 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.dialog.models.addItem(item)
self.models.append((False, m)) # type: ignore self.models.append((False, m)) # type: ignore
self.dialog.models.setCurrentRow(0) self.dialog.models.setCurrentRow(0)

View file

@ -11,7 +11,7 @@ from aqt import gui_hooks
from aqt.scheduling_ops import empty_filtered_deck, rebuild_filtered_deck from aqt.scheduling_ops import empty_filtered_deck, rebuild_filtered_deck
from aqt.sound import av_player from aqt.sound import av_player
from aqt.toolbar import BottomBar 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: class OverviewBottomBar:
@ -256,7 +256,7 @@ class Overview:
buf = "" buf = ""
for b in links: for b in links:
if b[0]: 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 += """ buf += """
<button title="%s" onclick='pycmd("%s")'>%s</button>""" % tuple( <button title="%s" onclick='pycmd("%s")'>%s</button>""" % tuple(
b b

View file

@ -7,15 +7,7 @@ from anki.consts import newCardSchedulingLabels
from aqt import AnkiQt from aqt import AnkiQt
from aqt.profiles import RecordingDriver, VideoDriver from aqt.profiles import RecordingDriver, VideoDriver
from aqt.qt import * from aqt.qt import *
from aqt.utils import ( from aqt.utils import HelpPage, disable_help_button, openHelp, showInfo, showWarning, tr
TR,
HelpPage,
disable_help_button,
openHelp,
showInfo,
showWarning,
tr,
)
class Preferences(QDialog): 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: def setup_video_driver(self) -> None:
self.video_drivers = VideoDriver.all_for_platform() self.video_drivers = VideoDriver.all_for_platform()
names = [ 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 for d in self.video_drivers
] ]
self.form.video_driver.addItems(names) self.form.video_driver.addItems(names)

View file

@ -30,7 +30,7 @@ from aqt.qt import (
from aqt.reviewer import replay_audio from aqt.reviewer import replay_audio
from aqt.sound import av_player, play_clicked_audio from aqt.sound import av_player, play_clicked_audio
from aqt.theme import theme_manager 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 from aqt.webview import AnkiWebView
LastStateAndMod = Tuple[str, int, int] LastStateAndMod = Tuple[str, int, int]
@ -89,12 +89,12 @@ class Previewer(QDialog):
) )
self._replay.setAutoDefault(False) self._replay.setAutoDefault(False)
self._replay.setShortcut(QKeySequence("R")) 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) qconnect(self._replay.clicked, self._on_replay_audio)
both_sides_button = QCheckBox(tr.qt_misc_back_side_only()) both_sides_button = QCheckBox(tr.qt_misc_back_side_only())
both_sides_button.setShortcut(QKeySequence("B")) 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.bbox.addButton(both_sides_button, QDialogButtonBox.ActionRole)
self._show_both_sides = self.mw.col.get_config_bool( self._show_both_sides = self.mw.col.get_config_bool(
Config.Bool.PREVIEW_BOTH_SIDES Config.Bool.PREVIEW_BOTH_SIDES

View file

@ -347,9 +347,7 @@ class ProfileManager:
os.rename(oldFolder, midFolder) os.rename(oldFolder, midFolder)
oldFolder = midFolder oldFolder = midFolder
else: else:
showWarning( showWarning(tr.profiles_please_remove_the_folder_and(val=midFolder))
tr(TR.PROFILES_PLEASE_REMOVE_THE_FOLDER_AND, val=midFolder)
)
self.name = oldName self.name = oldName
return return
else: else:
@ -552,7 +550,7 @@ create table if not exists profiles
code = obj[1] code = obj[1]
name = obj[0] name = obj[0]
r = QMessageBox.question( 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: if r != QMessageBox.Yes:
return self.setDefaultLang(f.lang.currentRow()) return self.setDefaultLang(f.lang.currentRow())

View file

@ -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.tag_ops import add_tags, remove_tags_for_notes
from aqt.theme import theme_manager from aqt.theme import theme_manager
from aqt.toolbar import BottomBar from aqt.toolbar import BottomBar
from aqt.utils import ( from aqt.utils import askUserDialog, downArrow, qtMenuShortcutWorkaround, tooltip, tr
TR,
askUserDialog,
downArrow,
qtMenuShortcutWorkaround,
tooltip,
tr,
)
from aqt.webview import AnkiWebView from aqt.webview import AnkiWebView
@ -147,9 +140,9 @@ class Reviewer:
elapsed = self.mw.col.timeboxReached() elapsed = self.mw.col.timeboxReached()
if elapsed: if elapsed:
assert not isinstance(elapsed, bool) 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)) mins = int(round(elapsed[0] / 60))
part2 = tr(TR.STUDYING_MINUTE, count=mins) part2 = tr.studying_minute(count=mins)
fin = tr.studying_finish() fin = tr.studying_finish()
diag = askUserDialog(f"{part1} {part2}", [tr.studying_continue(), fin]) diag = askUserDialog(f"{part1} {part2}", [tr.studying_continue(), fin])
diag.setIcon(QMessageBox.Information) diag.setIcon(QMessageBox.Information)
@ -445,7 +438,7 @@ class Reviewer:
if clozeIdx: if clozeIdx:
warn = tr.studying_please_run_toolsempty_cards() warn = tr.studying_please_run_toolsempty_cards()
else: 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) return re.sub(self.typeAnsPat, warn, buf)
else: else:
# empty field, remove type answer pattern # empty field, remove type answer pattern
@ -626,7 +619,7 @@ time = %(time)d;
""" % dict( """ % dict(
rem=self._remaining(), rem=self._remaining(),
edit=tr.studying_edit(), edit=tr.studying_edit(),
editkey=tr(TR.ACTIONS_SHORTCUT_KEY, val="E"), editkey=tr.actions_shortcut_key(val="E"),
more=tr.studying_more(), more=tr.studying_more(),
downArrow=downArrow(), downArrow=downArrow(),
time=self.card.timeTaken() // 1000, time=self.card.timeTaken() // 1000,
@ -637,7 +630,7 @@ time = %(time)d;
<span class=stattxt>%s</span><br> <span class=stattxt>%s</span><br>
<button title="%s" id="ansbut" class="focus" onclick='pycmd("ans");'>%s</button>""" % ( <button title="%s" id="ansbut" class="focus" onclick='pycmd("ans");'>%s</button>""" % (
self._remaining(), self._remaining(),
tr(TR.ACTIONS_SHORTCUT_KEY, val=tr.studying_space()), tr.actions_shortcut_key(val=tr.studying_space()),
tr.studying_show_answer(), tr.studying_show_answer(),
) )
# wrap it in a table so it has the same top margin as the ease buttons # wrap it in a table so it has the same top margin as the ease buttons
@ -717,7 +710,7 @@ time = %(time)d;
%s</button></td>""" % ( %s</button></td>""" % (
due, due,
extra, extra,
tr(TR.ACTIONS_SHORTCUT_KEY, val=i), tr.actions_shortcut_key(val=i),
i, i,
i, i,
label, label,
@ -905,9 +898,7 @@ time = %(time)d;
remove_notes( remove_notes(
mw=self.mw, mw=self.mw,
note_ids=[self.card.nid], note_ids=[self.card.nid],
success=lambda _: tooltip( success=lambda _: tooltip(tr.studying_note_and_its_card_deleted(count=cnt)),
tr(TR.STUDYING_NOTE_AND_ITS_CARD_DELETED, count=cnt)
),
) )
def onRecordVoice(self) -> None: def onRecordVoice(self) -> None:

View file

@ -9,7 +9,6 @@ import aqt
from anki.cards import CardID from anki.cards import CardID
from anki.collection import CARD_TYPE_NEW, Config from anki.collection import CARD_TYPE_NEW, Config
from anki.decks import DeckID from anki.decks import DeckID
from anki.lang import TR
from anki.notes import NoteID from anki.notes import NoteID
from anki.scheduler import FilteredDeckForUpdate from anki.scheduler import FilteredDeckForUpdate
from aqt import AnkiQt from aqt import AnkiQt
@ -33,7 +32,7 @@ def set_due_date_dialog(
) )
prompt = "\n".join( 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(), tr.scheduling_set_due_date_prompt_hint(),
] ]
) )
@ -49,7 +48,7 @@ def set_due_date_dialog(
mw.perform_op( mw.perform_op(
lambda: mw.col.sched.set_due_date(card_ids, days, config_key), lambda: mw.col.sched.set_due_date(card_ids, days, config_key),
success=lambda _: tooltip( 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, parent=parent,
), ),
) )
@ -62,7 +61,7 @@ def forget_cards(*, mw: aqt.AnkiQt, parent: QWidget, card_ids: List[CardID]) ->
mw.perform_op( mw.perform_op(
lambda: mw.col.sched.schedule_cards_as_new(card_ids), lambda: mw.col.sched.schedule_cards_as_new(card_ids),
success=lambda _: tooltip( 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 = aqt.forms.reposition.Ui_Dialog()
frm.setupUi(d) frm.setupUi(d)
txt = tr(TR.BROWSING_QUEUE_TOP, val=min_position) txt = tr.browsing_queue_top(val=min_position)
txt += "\n" + tr(TR.BROWSING_QUEUE_BOTTOM, val=max_position) txt += "\n" + tr.browsing_queue_bottom(val=max_position)
frm.label.setText(txt) frm.label.setText(txt)
frm.start.selectAll() frm.start.selectAll()
@ -128,7 +127,7 @@ def reposition_new_cards(
shift_existing=shift_existing, shift_existing=shift_existing,
), ),
success=lambda out: tooltip( 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
), ),
) )

View file

@ -1235,7 +1235,7 @@ class SidebarTreeView(QTreeView):
if ( if (
not update not update
and name in conf 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 return
conf[name] = search conf[name] = search
@ -1261,7 +1261,7 @@ class SidebarTreeView(QTreeView):
except KeyError: except KeyError:
return return
if new_name in conf and not askUser( 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 return
conf[new_name] = filt conf[new_name] = filt

View file

@ -29,7 +29,6 @@ from aqt.profiles import RecordingDriver
from aqt.qt import * from aqt.qt import *
from aqt.taskman import TaskManager from aqt.taskman import TaskManager
from aqt.utils import ( from aqt.utils import (
TR,
disable_help_button, disable_help_button,
restoreGeom, restoreGeom,
saveGeom, saveGeom,
@ -483,9 +482,9 @@ def _encode_mp3(src_wav: str, dst_mp3: str) -> None:
try: try:
retcode = retryWait(subprocess.Popen(cmd, startupinfo=startup_info(), env=env)) retcode = retryWait(subprocess.Popen(cmd, startupinfo=startup_info(), env=env))
except Exception as e: 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: 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) os.unlink(src_wav)
@ -764,7 +763,7 @@ class RecordDialog(QDialog):
def _on_timer(self) -> None: def _on_timer(self) -> None:
self._recorder.on_timer() self._recorder.on_timer()
duration = self._recorder.duration() 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: def accept(self) -> None:
self._timer.stop() self._timer.stop()

View file

@ -10,7 +10,7 @@ from typing import Callable, Tuple
import aqt import aqt
from anki.errors import Interrupted, SyncError 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.sync import SyncOutput, SyncStatus
from anki.utils import platDesc from anki.utils import platDesc
from aqt.qt import ( from aqt.qt import (
@ -296,7 +296,7 @@ def get_id_and_pass_from_user(
vbox = QVBoxLayout() vbox = QVBoxLayout()
info_label = QLabel( info_label = QLabel(
without_unicode_isolation( 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) info_label.setOpenExternalLinks(True)

View file

@ -6,7 +6,6 @@ from __future__ import annotations
from typing import Callable, Sequence from typing import Callable, Sequence
from anki.collection import OpChangesWithCount from anki.collection import OpChangesWithCount
from anki.lang import TR
from anki.notes import NoteID from anki.notes import NoteID
from aqt import AnkiQt, QWidget from aqt import AnkiQt, QWidget
from aqt.main import PerformOpOptionalSuccessCallback from aqt.main import PerformOpOptionalSuccessCallback
@ -41,7 +40,7 @@ def clear_unused_tags(*, mw: AnkiQt, parent: QWidget) -> None:
mw.perform_op( mw.perform_op(
mw.col.tags.clear_unused_tags, mw.col.tags.clear_unused_tags,
success=lambda out: tooltip( 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: ) -> None:
def success(out: OpChangesWithCount) -> None: def success(out: OpChangesWithCount) -> None:
if out.count: 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: else:
showInfo(tr.browsing_tag_rename_warning_empty(), parent=parent) showInfo(tr.browsing_tag_rename_warning_empty(), parent=parent)
@ -73,7 +72,7 @@ def remove_tags_for_all_notes(
mw.perform_op( mw.perform_op(
lambda: mw.col.tags.remove(space_separated_tags=space_separated_tags), lambda: mw.col.tags.remove(space_separated_tags=space_separated_tags),
success=lambda out: tooltip( 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( mw.perform_op(
lambda: mw.col.tags.reparent(tags=tags, new_parent=new_parent), lambda: mw.col.tags.reparent(tags=tags, new_parent=new_parent),
success=lambda out: tooltip( success=lambda out: tooltip(
tr(TR.BROWSING_NOTES_UPDATED, count=out.count), parent=parent tr.browsing_notes_updated(count=out.count), parent=parent
), ),
) )

View file

@ -9,7 +9,7 @@ from anki.sync import SyncStatus
from aqt import gui_hooks from aqt import gui_hooks
from aqt.qt import * from aqt.qt import *
from aqt.sync import get_sync_status from aqt.sync import get_sync_status
from aqt.utils import TR, tr from aqt.utils import tr
from aqt.webview import AnkiWebView from aqt.webview import AnkiWebView
@ -102,28 +102,28 @@ class Toolbar:
"decks", "decks",
tr.actions_decks(), tr.actions_decks(),
self._deckLinkHandler, self._deckLinkHandler,
tip=tr(TR.ACTIONS_SHORTCUT_KEY, val="D"), tip=tr.actions_shortcut_key(val="D"),
id="decks", id="decks",
), ),
self.create_link( self.create_link(
"add", "add",
tr.actions_add(), tr.actions_add(),
self._addLinkHandler, self._addLinkHandler,
tip=tr(TR.ACTIONS_SHORTCUT_KEY, val="A"), tip=tr.actions_shortcut_key(val="A"),
id="add", id="add",
), ),
self.create_link( self.create_link(
"browse", "browse",
tr.qt_misc_browse(), tr.qt_misc_browse(),
self._browseLinkHandler, self._browseLinkHandler,
tip=tr(TR.ACTIONS_SHORTCUT_KEY, val="B"), tip=tr.actions_shortcut_key(val="B"),
id="browse", id="browse",
), ),
self.create_link( self.create_link(
"stats", "stats",
tr.qt_misc_stats(), tr.qt_misc_stats(),
self._statsLinkHandler, self._statsLinkHandler,
tip=tr(TR.ACTIONS_SHORTCUT_KEY, val="T"), tip=tr.actions_shortcut_key(val="T"),
id="stats", id="stats",
), ),
] ]
@ -139,7 +139,7 @@ class Toolbar:
def _create_sync_link(self) -> str: def _create_sync_link(self) -> str:
name = tr.qt_misc_sync() name = tr.qt_misc_sync()
title = tr(TR.ACTIONS_SHORTCUT_KEY, val="Y") title = tr.actions_shortcut_key(val="Y")
label = "sync" label = "sync"
self.link_handlers[label] = self._syncLinkHandler self.link_handlers[label] = self._syncLinkHandler

View file

@ -10,7 +10,7 @@ import aqt
from anki.utils import platDesc, versionWithBuild from anki.utils import platDesc, versionWithBuild
from aqt.main import AnkiQt from aqt.main import AnkiQt
from aqt.qt import * from aqt.qt import *
from aqt.utils import TR, openLink, showText, tr from aqt.utils import openLink, showText, tr
class LatestVersionFinder(QThread): class LatestVersionFinder(QThread):
@ -57,7 +57,7 @@ class LatestVersionFinder(QThread):
def askAndUpdate(mw: aqt.AnkiQt, ver: str) -> None: 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 = QMessageBox(mw)
msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No) # type: ignore msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No) # type: ignore
msg.setIcon(QMessageBox.Information) msg.setIcon(QMessageBox.Information)

View file

@ -803,7 +803,7 @@ def closeTooltip() -> None:
def checkInvalidFilename(str: str, dirsep: bool = True) -> bool: def checkInvalidFilename(str: str, dirsep: bool = True) -> bool:
bad = invalidFilename(str, dirsep) bad = invalidFilename(str, dirsep)
if bad: 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 True
return False return False