diff --git a/pylib/anki/_backend/__init__.py b/pylib/anki/_backend/__init__.py
index 8a274e403..830440bc1 100644
--- a/pylib/anki/_backend/__init__.py
+++ b/pylib/anki/_backend/__init__.py
@@ -118,7 +118,7 @@ def translate_string_in(
class Translations(GeneratedTranslations):
- def __init__(self, backend: ref[RustBackend]):
+ def __init__(self, backend: Optional[ref[RustBackend]]):
self.backend = backend
def __call__(self, *args: Any, **kwargs: Any) -> str:
diff --git a/pylib/anki/lang.py b/pylib/anki/lang.py
index 537ca5db2..32fdbcdc1 100644
--- a/pylib/anki/lang.py
+++ b/pylib/anki/lang.py
@@ -153,7 +153,7 @@ currentLang = "en"
# instance exists for legacy reasons, and as a convenience for the
# Qt code.
current_i18n: Optional[anki._backend.RustBackend] = None
-tr_legacyglobal: Optional[anki._backend.Translations] = None
+tr_legacyglobal = anki._backend.Translations(None)
def _(str: str) -> str:
@@ -167,10 +167,10 @@ def ngettext(single: str, plural: str, n: int) -> str:
def set_lang(lang: str) -> None:
- global currentLang, current_i18n, tr_legacyglobal
+ global currentLang, current_i18n
currentLang = lang
current_i18n = anki._backend.RustBackend(langs=[lang])
- tr_legacyglobal = anki._backend.Translations(weakref.ref(current_i18n))
+ tr_legacyglobal.backend = weakref.ref(current_i18n)
def get_def_lang(lang: Optional[str] = None) -> Tuple[int, str]:
diff --git a/qt/aqt/__init__.py b/qt/aqt/__init__.py
index b6661c16f..9063ff02d 100644
--- a/qt/aqt/__init__.py
+++ b/qt/aqt/__init__.py
@@ -285,8 +285,8 @@ class AnkiApp(QApplication):
# existing instance running but hung
QMessageBox.warning(
None,
- tr(TR.QT_MISC_ANKI_IS_RUNNING),
- tr(TR.QT_MISC_IF_INSTANCE_IS_NOT_RESPONDING),
+ tr.qt_misc_anki_is_running(),
+ tr.qt_misc_if_instance_is_not_responding(),
)
sys.exit(1)
@@ -379,7 +379,7 @@ def setupGL(pm: aqt.profiles.ProfileManager) -> None:
if "Failed to create OpenGL context" in msg:
QMessageBox.critical(
None,
- tr(TR.QT_MISC_ERROR),
+ tr.qt_misc_error(),
tr(
TR.QT_MISC_ERROR_LOADING_GRAPHICS_DRIVER,
mode=driver.value,
@@ -515,8 +515,8 @@ def _run(argv: Optional[List[str]] = None, exec: bool = True) -> Optional[AnkiAp
if not pm:
QMessageBox.critical(
None,
- tr(TR.QT_MISC_ERROR),
- tr(TR.PROFILES_COULD_NOT_CREATE_DATA_FOLDER),
+ tr.qt_misc_error(),
+ tr.profiles_could_not_create_data_folder(),
)
return None
@@ -555,8 +555,8 @@ def _run(argv: Optional[List[str]] = None, exec: bool = True) -> Optional[AnkiAp
except:
QMessageBox.critical(
None,
- tr(TR.QT_MISC_ERROR),
- tr(TR.QT_MISC_NO_TEMP_FOLDER),
+ tr.qt_misc_error(),
+ tr.qt_misc_no_temp_folder(),
)
return None
@@ -566,8 +566,8 @@ def _run(argv: Optional[List[str]] = None, exec: bool = True) -> Optional[AnkiAp
if pmLoadResult.loadError:
QMessageBox.warning(
None,
- tr(TR.PROFILES_PREFS_CORRUPT_TITLE),
- tr(TR.PROFILES_PREFS_FILE_IS_CORRUPT),
+ tr.profiles_prefs_corrupt_title(),
+ tr.profiles_prefs_file_is_corrupt(),
)
if opts.profile:
@@ -584,8 +584,8 @@ def _run(argv: Optional[List[str]] = None, exec: bool = True) -> Optional[AnkiAp
pm.set_video_driver(driver.next())
QMessageBox.critical(
None,
- tr(TR.QT_MISC_ERROR),
- tr(TR.QT_MISC_INCOMPATIBLE_VIDEO_DRIVER),
+ tr.qt_misc_error(),
+ tr.qt_misc_incompatible_video_driver(),
)
sys.exit(1)
diff --git a/qt/aqt/about.py b/qt/aqt/about.py
index da8efe13b..b286b9d14 100644
--- a/qt/aqt/about.py
+++ b/qt/aqt/about.py
@@ -83,9 +83,9 @@ def show(mw: aqt.AnkiQt) -> QDialog:
"""
info = f" {' '.join(info.splitlines(True))}"
QApplication.clipboard().setText(info)
- tooltip(tr(TR.ABOUT_COPIED_TO_CLIPBOARD), parent=dialog)
+ tooltip(tr.about_copied_to_clipboard(), parent=dialog)
- btn = QPushButton(tr(TR.ABOUT_COPY_DEBUG_INFO))
+ btn = QPushButton(tr.about_copy_debug_info())
qconnect(btn.clicked, onCopy)
abt.buttonBox.addButton(btn, QDialogButtonBox.ActionRole)
abt.buttonBox.button(QDialogButtonBox.Ok).setFocus()
@@ -93,8 +93,8 @@ def show(mw: aqt.AnkiQt) -> QDialog:
# WebView contents
######################################################################
abouttext = "
"
- abouttext += f"{tr(TR.ABOUT_ANKI_IS_A_FRIENDLY_INTELLIGENT_SPACED)}"
- abouttext += f"
{tr(TR.ABOUT_ANKI_IS_LICENSED_UNDER_THE_AGPL3)}"
+ 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 += ("Python %s Qt %s PyQt %s
") % (
platform.python_version(),
@@ -212,8 +212,8 @@ def show(mw: aqt.AnkiQt) -> QDialog:
abouttext += "
" + tr(
TR.ABOUT_WRITTEN_BY_DAMIEN_ELMES_WITH_PATCHES, cont=", ".join(allusers)
)
- abouttext += f"
{tr(TR.ABOUT_IF_YOU_HAVE_CONTRIBUTED_AND_ARE)}"
- abouttext += f"
{tr(TR.ABOUT_A_BIG_THANKS_TO_ALL_THE)}"
+ abouttext += f"
{tr.about_if_you_have_contributed_and_are()}"
+ abouttext += f"
{tr.about_a_big_thanks_to_all_the()}"
abt.label.setMinimumWidth(800)
abt.label.setMinimumHeight(600)
dialog.show()
diff --git a/qt/aqt/addcards.py b/qt/aqt/addcards.py
index c0a878130..0f1231d7d 100644
--- a/qt/aqt/addcards.py
+++ b/qt/aqt/addcards.py
@@ -41,7 +41,7 @@ class AddCards(QDialog):
self.mw = mw
self.form = aqt.forms.addcards.Ui_Dialog()
self.form.setupUi(self)
- self.setWindowTitle(tr(TR.ACTIONS_ADD))
+ self.setWindowTitle(tr.actions_add())
disable_help_button(self)
self.setMinimumHeight(300)
self.setMinimumWidth(400)
@@ -81,20 +81,20 @@ class AddCards(QDialog):
bb = self.form.buttonBox
ar = QDialogButtonBox.ActionRole
# add
- self.addButton = bb.addButton(tr(TR.ACTIONS_ADD), ar)
+ self.addButton = bb.addButton(tr.actions_add(), ar)
qconnect(self.addButton.clicked, self.add_current_note)
self.addButton.setShortcut(QKeySequence("Ctrl+Return"))
- self.addButton.setToolTip(shortcut(tr(TR.ADDING_ADD_SHORTCUT_CTRLANDENTER)))
+ self.addButton.setToolTip(shortcut(tr.adding_add_shortcut_ctrlandenter()))
# close
- self.closeButton = QPushButton(tr(TR.ACTIONS_CLOSE))
+ self.closeButton = QPushButton(tr.actions_close())
self.closeButton.setAutoDefault(False)
bb.addButton(self.closeButton, QDialogButtonBox.RejectRole)
# help
- self.helpButton = QPushButton(tr(TR.ACTIONS_HELP), clicked=self.helpRequested) # type: ignore
+ self.helpButton = QPushButton(tr.actions_help(), clicked=self.helpRequested) # type: ignore
self.helpButton.setAutoDefault(False)
bb.addButton(self.helpButton, QDialogButtonBox.HelpRole)
# history
- b = bb.addButton(f"{tr(TR.ADDING_HISTORY)} {downArrow()}", ar)
+ b = bb.addButton(f"{tr.adding_history()} {downArrow()}", ar)
if isMac:
sc = "Ctrl+Shift+H"
else:
@@ -175,7 +175,7 @@ class AddCards(QDialog):
a = m.addAction(line)
qconnect(a.triggered, lambda b, nid=nid: self.editHistory(nid))
else:
- a = m.addAction(tr(TR.ADDING_NOTE_DELETED))
+ a = m.addAction(tr.adding_note_deleted())
a.setEnabled(False)
gui_hooks.add_cards_will_show_history_menu(self, m)
m.exec_(self.historyButton.mapToGlobal(QPoint(0, 0)))
@@ -203,7 +203,7 @@ class AddCards(QDialog):
# workaround for PyQt focus bug
self.editor.hideCompleters()
- tooltip(tr(TR.ADDING_ADDED), period=500)
+ tooltip(tr.adding_added(), period=500)
av_player.stop_and_clear_queue()
self._load_new_note(sticky_fields_from=note)
gui_hooks.add_cards_did_add_note(note)
@@ -215,7 +215,7 @@ class AddCards(QDialog):
def _note_can_be_added(self, note: Note) -> bool:
result = note.duplicate_or_empty()
if result == DuplicateOrEmptyResult.EMPTY:
- problem = tr(TR.ADDING_THE_FIRST_FIELD_IS_EMPTY)
+ problem = tr.adding_the_first_field_is_empty()
else:
# duplicate entries are allowed these days
problem = None
@@ -229,7 +229,7 @@ class AddCards(QDialog):
# missing cloze deletion?
if note.model()["type"] == MODEL_CLOZE:
if not note.cloze_numbers_in_fields():
- if not askUser(tr(TR.ADDING_YOU_HAVE_A_CLOZE_DELETION_NOTE)):
+ if not askUser(tr.adding_you_have_a_cloze_deletion_note()):
return False
return True
@@ -256,7 +256,7 @@ class AddCards(QDialog):
def ifCanClose(self, onOk: Callable) -> None:
def afterSave() -> None:
ok = self.editor.fieldsAreBlank(self._last_added_note) or askUser(
- tr(TR.ADDING_CLOSE_AND_LOSE_CURRENT_INPUT), defaultno=True
+ tr.adding_close_and_lose_current_input(), defaultno=True
)
if ok:
onOk()
diff --git a/qt/aqt/addons.py b/qt/aqt/addons.py
index 4c35c36f6..607e912fd 100644
--- a/qt/aqt/addons.py
+++ b/qt/aqt/addons.py
@@ -320,7 +320,7 @@ class AddonManager:
meta = self.addon_meta(dir)
name = meta.human_name()
if not meta.enabled:
- name += f" {tr(TR.ADDONS_DISABLED)}"
+ name += f" {tr.addons_disabled()}"
return name
# Conflict resolution
@@ -475,8 +475,8 @@ class AddonManager:
) -> List[str]:
messages = {
- "zip": tr(TR.ADDONS_CORRUPT_ADDON_FILE),
- "manifest": tr(TR.ADDONS_INVALID_ADDON_MANIFEST),
+ "zip": tr.addons_corrupt_addon_file(),
+ "manifest": tr.addons_invalid_addon_manifest(),
}
msg = messages.get(
@@ -504,13 +504,13 @@ class AddonManager:
if result.conflicts:
strings.append(
- tr(TR.ADDONS_THE_FOLLOWING_CONFLICTING_ADDONS_WERE_DISABLED)
+ tr.addons_the_following_conflicting_addons_were_disabled()
+ " "
+ ", ".join(self.addonName(f) for f in result.conflicts)
)
if not result.compatible:
- strings.append(tr(TR.ADDONS_THIS_ADDON_IS_NOT_COMPATIBLE_WITH))
+ strings.append(tr.addons_this_addon_is_not_compatible_with())
return strings
@@ -714,7 +714,7 @@ class AddonsDialog(QDialog):
qconnect(f.config.clicked, self.onConfig)
qconnect(self.form.addonList.itemDoubleClicked, self.onConfig)
qconnect(self.form.addonList.currentRowChanged, self._onAddonItemSelected)
- self.setWindowTitle(tr(TR.ADDONS_WINDOW_TITLE))
+ self.setWindowTitle(tr.addons_window_title())
disable_help_button(self)
self.setAcceptDrops(True)
self.redrawAddons()
@@ -752,7 +752,7 @@ class AddonsDialog(QDialog):
name = addon.human_name()
if not addon.enabled:
- return f"{name} {tr(TR.ADDONS_DISABLED2)}"
+ return f"{name} {tr.addons_disabled2()}"
elif not addon.compatible():
return f"{name} {tr(TR.ADDONS_REQUIRES, val=self.compatible_string(addon))}"
@@ -813,7 +813,7 @@ class AddonsDialog(QDialog):
def onlyOneSelected(self) -> Optional[str]:
dirs = self.selectedAddons()
if len(dirs) != 1:
- showInfo(tr(TR.ADDONS_PLEASE_SELECT_A_SINGLE_ADDON_FIRST))
+ showInfo(tr.addons_please_select_a_single_addon_first())
return None
return dirs[0]
@@ -829,7 +829,7 @@ class AddonsDialog(QDialog):
if re.match(r"^\d+$", addon):
openLink(f"{aqt.appShared}info/{addon}")
else:
- showWarning(tr(TR.ADDONS_ADDON_WAS_NOT_DOWNLOADED_FROM_ANKIWEB))
+ showWarning(tr.addons_addon_was_not_downloaded_from_ankiweb())
def onViewFiles(self) -> None:
# if nothing selected, open top level folder
@@ -869,13 +869,13 @@ class AddonsDialog(QDialog):
if log:
show_log_to_user(self, log)
else:
- tooltip(tr(TR.ADDONS_NO_UPDATES_AVAILABLE))
+ tooltip(tr.addons_no_updates_available())
def onInstallFiles(self, paths: Optional[List[str]] = None) -> Optional[bool]:
if not paths:
- key = f"{tr(TR.ADDONS_PACKAGED_ANKI_ADDON)} (*{self.mgr.ext})"
+ key = f"{tr.addons_packaged_anki_addon()} (*{self.mgr.ext})"
paths_ = getFile(
- self, tr(TR.ADDONS_INSTALL_ADDONS), None, key, key="addons", multi=True
+ self, tr.addons_install_addons(), None, key, key="addons", multi=True
)
paths = paths_ # type: ignore
if not paths:
@@ -887,7 +887,7 @@ class AddonsDialog(QDialog):
return None
def check_for_updates(self) -> None:
- tooltip(tr(TR.ADDONS_CHECKING))
+ tooltip(tr.addons_checking())
check_and_prompt_for_updates(self, self.mgr, self.after_downloading)
def onConfig(self) -> None:
@@ -904,7 +904,7 @@ class AddonsDialog(QDialog):
conf = self.mgr.getConfig(addon)
if conf is None:
- showInfo(tr(TR.ADDONS_ADDON_HAS_NO_CONFIGURATION))
+ showInfo(tr.addons_addon_has_no_configuration())
return
ConfigEditor(self, addon, conf)
@@ -924,7 +924,7 @@ class GetAddons(QDialog):
self.form = aqt.forms.getaddons.Ui_Dialog()
self.form.setupUi(self)
b = self.form.buttonBox.addButton(
- tr(TR.ADDONS_BROWSE_ADDONS), QDialogButtonBox.ActionRole
+ tr.addons_browse_addons(), QDialogButtonBox.ActionRole
)
qconnect(b.clicked, self.onBrowse)
disable_help_button(self)
@@ -940,7 +940,7 @@ class GetAddons(QDialog):
try:
ids = [int(n) for n in self.form.code.text().split()]
except ValueError:
- showWarning(tr(TR.ADDONS_INVALID_CODE))
+ showWarning(tr.addons_invalid_code())
return
self.ids = ids
@@ -1013,19 +1013,19 @@ def describe_log_entry(id_and_entry: DownloadLogEntry) -> str:
if isinstance(entry, DownloadError):
if entry.status_code is not None:
if entry.status_code in (403, 404):
- buf += tr(TR.ADDONS_INVALID_CODE_OR_ADDON_NOT_AVAILABLE)
+ buf += tr.addons_invalid_code_or_addon_not_available()
else:
buf += tr(TR.QT_MISC_UNEXPECTED_RESPONSE_CODE, val=entry.status_code)
else:
buf += (
- tr(TR.ADDONS_PLEASE_CHECK_YOUR_INTERNET_CONNECTION)
+ tr.addons_please_check_your_internet_connection()
+ "\n\n"
+ str(entry.exception)
)
elif isinstance(entry, InstallError):
buf += entry.errmsg
else:
- buf += tr(TR.ADDONS_INSTALLED_SUCCESSFULLY)
+ buf += tr.addons_installed_successfully()
return buf
@@ -1117,9 +1117,9 @@ def show_log_to_user(parent: QWidget, log: List[DownloadLogEntry]) -> None:
have_problem = download_encountered_problem(log)
if have_problem:
- text = tr(TR.ADDONS_ONE_OR_MORE_ERRORS_OCCURRED)
+ text = tr.addons_one_or_more_errors_occurred()
else:
- text = tr(TR.ADDONS_DOWNLOAD_COMPLETE_PLEASE_RESTART_ANKI_TO)
+ text = tr.addons_download_complete_please_restart_anki_to()
text += f"
{download_log_to_html(log)}"
if have_problem:
@@ -1223,7 +1223,7 @@ class ChooseAddonsToUpdateList(QListWidget):
item = self.itemAt(point)
addon_id = item.data(self.ADDON_ID_ROLE)
m = QMenu()
- a = m.addAction(tr(TR.ADDONS_VIEW_ADDON_PAGE))
+ a = m.addAction(tr.addons_view_addon_page())
qconnect(a.triggered, lambda _: openLink(f"{aqt.appShared}info/{addon_id}"))
m.exec_(QCursor.pos())
@@ -1268,7 +1268,7 @@ class ChooseAddonsToUpdateDialog(QDialog):
self, parent: QWidget, mgr: AddonManager, updated_addons: List[UpdateInfo]
) -> None:
QDialog.__init__(self, parent)
- self.setWindowTitle(tr(TR.ADDONS_CHOOSE_UPDATE_WINDOW_TITLE))
+ self.setWindowTitle(tr.addons_choose_update_window_title())
self.setWindowModality(Qt.WindowModal)
self.mgr = mgr
self.updated_addons = updated_addons
@@ -1277,7 +1277,7 @@ class ChooseAddonsToUpdateDialog(QDialog):
def setup(self) -> None:
layout = QVBoxLayout()
- label = QLabel(tr(TR.ADDONS_THE_FOLLOWING_ADDONS_HAVE_UPDATES_AVAILABLE))
+ label = QLabel(tr.addons_the_following_addons_have_updates_available())
layout.addWidget(label)
addons_list_widget = ChooseAddonsToUpdateList(
self, self.mgr, self.updated_addons
@@ -1475,7 +1475,7 @@ class ConfigEditor(QDialog):
def onRestoreDefaults(self) -> None:
default_conf = self.mgr.addonConfigDefaults(self.addon)
self.updateText(default_conf)
- tooltip(tr(TR.ADDONS_RESTORED_DEFAULTS), parent=self)
+ tooltip(tr.addons_restored_defaults(), parent=self)
def setupFonts(self) -> None:
font_mono = QFontDatabase.systemFont(QFontDatabase.FixedFont)
@@ -1541,11 +1541,11 @@ class ConfigEditor(QDialog):
showInfo(msg)
return
except Exception as e:
- showInfo(f"{tr(TR.ADDONS_INVALID_CONFIGURATION)} {repr(e)}")
+ showInfo(f"{tr.addons_invalid_configuration()} {repr(e)}")
return
if not isinstance(new_conf, dict):
- showInfo(tr(TR.ADDONS_INVALID_CONFIGURATION_TOP_LEVEL_OBJECT_MUST))
+ showInfo(tr.addons_invalid_configuration_top_level_object_must())
return
if new_conf != self.conf:
@@ -1574,14 +1574,12 @@ def installAddonPackages(
if warn:
names = ",
".join(f"{os.path.basename(p)}" for p in paths)
- q = tr(TR.ADDONS_IMPORTANT_AS_ADDONS_ARE_PROGRAMS_DOWNLOADED) % dict(
- names=names
- )
+ q = tr.addons_important_as_addons_are_programs_downloaded() % dict(names=names)
if (
not showInfo(
q,
parent=parent,
- title=tr(TR.ADDONS_INSTALL_ANKI_ADDON),
+ title=tr.addons_install_anki_addon(),
type="warning",
customBtns=[QMessageBox.No, QMessageBox.Yes],
)
@@ -1594,7 +1592,7 @@ def installAddonPackages(
if log:
log_html = "
".join(log)
if advise_restart:
- log_html += f"
{tr(TR.ADDONS_PLEASE_RESTART_ANKI_TO_COMPLETE_THE)}"
+ log_html += f"
{tr.addons_please_restart_anki_to_complete_the()}"
if len(log) == 1 and not strictly_modal:
tooltip(log_html, parent=parent)
else:
@@ -1602,15 +1600,15 @@ def installAddonPackages(
log_html,
parent=parent,
textFormat="rich",
- title=tr(TR.ADDONS_INSTALLATION_COMPLETE),
+ title=tr.addons_installation_complete(),
)
if errs:
- msg = tr(TR.ADDONS_PLEASE_REPORT_THIS_TO_THE_RESPECTIVE)
+ msg = tr.addons_please_report_this_to_the_respective()
showWarning(
"
".join(errs + [msg]),
parent=parent,
textFormat="rich",
- title=tr(TR.ADDONS_ADDON_INSTALLATION_ERROR),
+ title=tr.addons_addon_installation_error(),
)
return not errs
diff --git a/qt/aqt/browser.py b/qt/aqt/browser.py
index b000976fe..3560e69d9 100644
--- a/qt/aqt/browser.py
+++ b/qt/aqt/browser.py
@@ -142,7 +142,7 @@ class CellRow:
@staticmethod
def deleted(length: int) -> CellRow:
- return CellRow.generic(length, tr(TR.BROWSING_ROW_DELETED))
+ return CellRow.generic(length, tr.browsing_row_deleted())
def backend_color_to_aqt_color(color: BrowserRow.Color.V) -> Optional[Tuple[str, str]]:
@@ -271,7 +271,7 @@ class DataModel(QAbstractTableModel):
break
# give the user a hint an invalid column was added by an add-on
if not txt:
- txt = tr(TR.BROWSING_ADDON)
+ txt = tr.browsing_addon()
return txt
else:
return None
@@ -632,21 +632,21 @@ class Browser(QMainWindow):
def setupColumns(self) -> None:
self.columns = [
- ("question", tr(TR.BROWSING_QUESTION)),
- ("answer", tr(TR.BROWSING_ANSWER)),
- ("template", tr(TR.BROWSING_CARD)),
- ("deck", tr(TR.DECKS_DECK)),
- ("noteFld", tr(TR.BROWSING_SORT_FIELD)),
- ("noteCrt", tr(TR.BROWSING_CREATED)),
- ("noteMod", tr(TR.SEARCH_NOTE_MODIFIED)),
- ("cardMod", tr(TR.SEARCH_CARD_MODIFIED)),
- ("cardDue", tr(TR.STATISTICS_DUE_DATE)),
- ("cardIvl", tr(TR.BROWSING_INTERVAL)),
- ("cardEase", tr(TR.BROWSING_EASE)),
- ("cardReps", tr(TR.SCHEDULING_REVIEWS)),
- ("cardLapses", tr(TR.SCHEDULING_LAPSES)),
- ("noteTags", tr(TR.EDITING_TAGS)),
- ("note", tr(TR.BROWSING_NOTE)),
+ ("question", tr.browsing_question()),
+ ("answer", tr.browsing_answer()),
+ ("template", tr.browsing_card()),
+ ("deck", tr.decks_deck()),
+ ("noteFld", tr.browsing_sort_field()),
+ ("noteCrt", tr.browsing_created()),
+ ("noteMod", tr.search_note_modified()),
+ ("cardMod", tr.search_card_modified()),
+ ("cardDue", tr.statistics_due_date()),
+ ("cardIvl", tr.browsing_interval()),
+ ("cardEase", tr.browsing_ease()),
+ ("cardReps", tr.scheduling_reviews()),
+ ("cardLapses", tr.scheduling_lapses()),
+ ("noteTags", tr.editing_tags()),
+ ("note", tr.browsing_note()),
]
self.columns.sort(key=itemgetter(1))
@@ -674,7 +674,7 @@ class Browser(QMainWindow):
qconnect(self.form.searchEdit.lineEdit().returnPressed, self.onSearchActivated)
self.form.searchEdit.setCompleter(None)
self.form.searchEdit.lineEdit().setPlaceholderText(
- tr(TR.BROWSING_SEARCH_BAR_HINT)
+ tr.browsing_search_bar_hint()
)
self.form.searchEdit.addItems(self.mw.pm.profile["searchHistory"])
if search is not None:
@@ -805,7 +805,7 @@ QTableView {{ gridline-color: {grid} }}
TR.BROWSING_PREVIEW_SELECTED_CARD,
val=shortcut(preview_shortcut),
),
- tr(TR.ACTIONS_PREVIEW),
+ tr.actions_preview(),
id="previewButton",
keys=preview_shortcut,
disables=False,
@@ -875,7 +875,7 @@ QTableView {{ gridline-color: {grid} }}
type = self.model.activeCols[idx]
noSort = ("question", "answer")
if type in noSort:
- showInfo(tr(TR.BROWSING_SORTING_ON_THIS_COLUMN_IS_NOT))
+ showInfo(tr.browsing_sorting_on_this_column_is_not())
type = self.col.conf["sortType"]
if self.col.conf["sortType"] != type:
self.col.conf["sortType"] = type
@@ -925,7 +925,7 @@ QTableView {{ gridline-color: {grid} }}
if type in self.model.activeCols:
if len(self.model.activeCols) < 2:
self.model.endReset()
- showInfo(tr(TR.BROWSING_YOU_MUST_HAVE_AT_LEAST_ONE))
+ showInfo(tr.browsing_you_must_have_at_least_one())
return
self.model.activeCols.remove(type)
adding = False
@@ -956,7 +956,7 @@ QTableView {{ gridline-color: {grid} }}
self.setColumnSizes()
def setupSidebar(self) -> None:
- dw = self.sidebarDockWidget = QDockWidget(tr(TR.BROWSING_SIDEBAR), self)
+ dw = self.sidebarDockWidget = QDockWidget(tr.browsing_sidebar(), self)
dw.setFeatures(QDockWidget.DockWidgetClosable)
dw.setObjectName("Sidebar")
dw.setAllowedAreas(Qt.LeftDockWidgetArea)
@@ -1085,7 +1085,7 @@ where id in %s"""
% ids2str(sf)
)
if mods > 1:
- showInfo(tr(TR.BROWSING_PLEASE_SELECT_CARDS_FROM_ONLY_ONE))
+ showInfo(tr.browsing_please_select_cards_from_only_one())
return []
return sf
@@ -1185,8 +1185,8 @@ where id in %s"""
ret = StudyDeck(
self.mw,
current=current,
- accept=tr(TR.BROWSING_MOVE_CARDS),
- title=tr(TR.BROWSING_CHANGE_DECK),
+ accept=tr.browsing_move_cards(),
+ title=tr.browsing_change_deck(),
help=HelpPage.BROWSING,
parent=self,
)
@@ -1209,9 +1209,7 @@ where id in %s"""
tags: Optional[str] = None,
) -> None:
"Shows prompt if tags not provided."
- if not (
- tags := tags or self._prompt_for_tags(tr(TR.BROWSING_ENTER_TAGS_TO_ADD))
- ):
+ if not (tags := tags or self._prompt_for_tags(tr.browsing_enter_tags_to_add())):
return
add_tags(
mw=self.mw,
@@ -1226,7 +1224,7 @@ where id in %s"""
def remove_tags_from_selected_notes(self, tags: Optional[str] = None) -> None:
"Shows prompt if tags not provided."
if not (
- tags := tags or self._prompt_for_tags(tr(TR.BROWSING_ENTER_TAGS_TO_DELETE))
+ tags := tags or self._prompt_for_tags(tr.browsing_enter_tags_to_delete())
):
return
remove_tags_for_notes(
@@ -1320,7 +1318,7 @@ where id in %s"""
@ensure_editor_saved_on_trigger
def reposition(self) -> None:
if self.card and self.card.queue != QUEUE_TYPE_NEW:
- showInfo(tr(TR.BROWSING_ONLY_NEW_CARDS_CAN_BE_REPOSITIONED), parent=self)
+ showInfo(tr.browsing_only_new_cards_can_be_repositioned(), parent=self)
return
reposition_new_cards_dialog(
@@ -1456,7 +1454,7 @@ where id in %s"""
self.duplicatesReport(frm.webView, field, search_text, frm, web_context)
search = frm.buttonBox.addButton(
- tr(TR.ACTIONS_SEARCH), QDialogButtonBox.ActionRole
+ tr.actions_search(), QDialogButtonBox.ActionRole
)
qconnect(search.clicked, onClick)
d.show()
@@ -1478,7 +1476,7 @@ where id in %s"""
return
if not self._dupesButton:
self._dupesButton = b = frm.buttonBox.addButton(
- tr(TR.BROWSING_TAG_DUPLICATES), QDialogButtonBox.ActionRole
+ tr.browsing_tag_duplicates(), QDialogButtonBox.ActionRole
)
qconnect(b.clicked, lambda: self._onTagDupes(res))
t = ""
@@ -1509,15 +1507,15 @@ where id in %s"""
if not res:
return
self.model.beginReset()
- self.mw.checkpoint(tr(TR.BROWSING_TAG_DUPLICATES))
+ self.mw.checkpoint(tr.browsing_tag_duplicates())
nids = set()
for _, nidlist in res:
nids.update(nidlist)
- self.col.tags.bulk_add(list(nids), tr(TR.BROWSING_DUPLICATE))
+ self.col.tags.bulk_add(list(nids), tr.browsing_duplicate())
self.mw.progress.finish()
self.model.endReset()
self.mw.requireReset(reason=ResetReason.BrowserTagDupes, context=self)
- tooltip(tr(TR.BROWSING_NOTES_TAGGED))
+ tooltip(tr.browsing_notes_tagged())
def dupeLinkClicked(self, link: str) -> None:
self.search_for(link)
@@ -1681,7 +1679,7 @@ class ChangeModel(QDialog):
map = QWidget()
l = QGridLayout()
combos = []
- targets = [x["name"] for x in dst] + [tr(TR.BROWSING_NOTHING)]
+ 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)
@@ -1767,9 +1765,9 @@ class ChangeModel(QDialog):
fmap = self.getFieldMap()
cmap = self.getTemplateMap()
if any(True for c in list(cmap.values()) if c is None):
- if not askUser(tr(TR.BROWSING_ANY_CARDS_MAPPED_TO_NOTHING_WILL)):
+ if not askUser(tr.browsing_any_cards_mapped_to_nothing_will()):
return
- self.browser.mw.checkpoint(tr(TR.BROWSING_CHANGE_NOTE_TYPE))
+ self.browser.mw.checkpoint(tr.browsing_change_note_type())
b = self.browser
b.mw.col.modSchema(check=True)
b.mw.progress.start()
diff --git a/qt/aqt/clayout.py b/qt/aqt/clayout.py
index 318b942b0..b18abf136 100644
--- a/qt/aqt/clayout.py
+++ b/qt/aqt/clayout.py
@@ -60,7 +60,7 @@ class CardLayout(QDialog):
self.mobile_emulation_enabled = False
self.have_autoplayed = False
self.mm._remove_from_cache(self.model["id"])
- self.mw.checkpoint(tr(TR.CARD_TEMPLATES_CARD_TYPES))
+ self.mw.checkpoint(tr.card_templates_card_types())
self.change_tracker = ChangeTracker(self.mw)
self.setupTopArea()
self.setupMainArea()
@@ -114,14 +114,14 @@ class CardLayout(QDialog):
self.topAreaForm = aqt.forms.clayout_top.Ui_Form()
self.topAreaForm.setupUi(self.topArea)
self.topAreaForm.templateOptions.setText(
- f"{tr(TR.ACTIONS_OPTIONS)} {downArrow()}"
+ f"{tr.actions_options()} {downArrow()}"
)
qconnect(self.topAreaForm.templateOptions.clicked, self.onMore)
qconnect(
self.topAreaForm.templatesBox.currentIndexChanged,
self.update_current_ordinal_and_redraw,
)
- self.topAreaForm.card_type_label.setText(tr(TR.CARD_TEMPLATES_CARD_TYPE))
+ self.topAreaForm.card_type_label.setText(tr.card_templates_card_type())
def updateTopArea(self) -> None:
self.updateCardNames()
@@ -211,9 +211,9 @@ class CardLayout(QDialog):
self.pform = aqt.forms.preview.Ui_Form()
pform = self.pform
pform.setupUi(right)
- pform.preview_front.setText(tr(TR.CARD_TEMPLATES_FRONT_PREVIEW))
- pform.preview_back.setText(tr(TR.CARD_TEMPLATES_BACK_PREVIEW))
- pform.preview_box.setTitle(tr(TR.CARD_TEMPLATES_PREVIEW_BOX))
+ pform.preview_front.setText(tr.card_templates_front_preview())
+ pform.preview_back.setText(tr.card_templates_back_preview())
+ pform.preview_box.setTitle(tr.card_templates_preview_box())
self.setup_edit_area()
self.setup_preview()
@@ -223,10 +223,10 @@ class CardLayout(QDialog):
def setup_edit_area(self) -> None:
tform = self.tform
- tform.front_button.setText(tr(TR.CARD_TEMPLATES_FRONT_TEMPLATE))
- tform.back_button.setText(tr(TR.CARD_TEMPLATES_BACK_TEMPLATE))
- tform.style_button.setText(tr(TR.CARD_TEMPLATES_TEMPLATE_STYLING))
- tform.groupBox.setTitle(tr(TR.CARD_TEMPLATES_TEMPLATE_BOX))
+ tform.front_button.setText(tr.card_templates_front_template())
+ tform.back_button.setText(tr.card_templates_back_template())
+ tform.style_button.setText(tr.card_templates_template_styling())
+ tform.groupBox.setTitle(tr.card_templates_template_box())
cnt = self.mw.col.models.useCount(self.model)
self.tform.changes_affect_label.setText(
@@ -310,7 +310,7 @@ class CardLayout(QDialog):
qconnect(pform.preview_front.clicked, self.on_preview_toggled)
qconnect(pform.preview_back.clicked, self.on_preview_toggled)
pform.preview_settings.setText(
- f"{tr(TR.CARD_TEMPLATES_PREVIEW_SETTINGS)} {downArrow()}"
+ f"{tr.card_templates_preview_settings()} {downArrow()}"
)
qconnect(pform.preview_settings.clicked, self.on_preview_settings)
@@ -355,19 +355,19 @@ class CardLayout(QDialog):
def on_preview_settings(self) -> None:
m = QMenu(self)
- a = m.addAction(tr(TR.CARD_TEMPLATES_FILL_EMPTY))
+ a = m.addAction(tr.card_templates_fill_empty())
a.setCheckable(True)
a.setChecked(self.fill_empty_action_toggled)
qconnect(a.triggered, self.on_fill_empty_action_toggled)
if not self.note_has_empty_field():
a.setVisible(False)
- a = m.addAction(tr(TR.CARD_TEMPLATES_NIGHT_MODE))
+ a = m.addAction(tr.card_templates_night_mode())
a.setCheckable(True)
a.setChecked(self.night_mode_is_enabled)
qconnect(a.triggered, self.on_night_mode_action_toggled)
- a = m.addAction(tr(TR.CARD_TEMPLATES_ADD_MOBILE_CLASS))
+ a = m.addAction(tr.card_templates_add_mobile_class())
a.setCheckable(True)
a.setChecked(self.mobile_emulation_enabled)
qconnect(a.toggled, self.on_mobile_class_action_toggled)
@@ -394,28 +394,28 @@ class CardLayout(QDialog):
def setupButtons(self) -> None:
l = self.buttons = QHBoxLayout()
- help = QPushButton(tr(TR.ACTIONS_HELP))
+ help = QPushButton(tr.actions_help())
help.setAutoDefault(False)
l.addWidget(help)
qconnect(help.clicked, self.onHelp)
l.addStretch()
- self.add_field_button = QPushButton(tr(TR.FIELDS_ADD_FIELD))
+ self.add_field_button = QPushButton(tr.fields_add_field())
self.add_field_button.setAutoDefault(False)
l.addWidget(self.add_field_button)
qconnect(self.add_field_button.clicked, self.onAddField)
if not self._isCloze():
- flip = QPushButton(tr(TR.CARD_TEMPLATES_FLIP))
+ flip = QPushButton(tr.card_templates_flip())
flip.setAutoDefault(False)
l.addWidget(flip)
qconnect(flip.clicked, self.onFlip)
l.addStretch()
- save = QPushButton(tr(TR.ACTIONS_SAVE))
+ save = QPushButton(tr.actions_save())
save.setAutoDefault(False)
save.setShortcut(QKeySequence("Ctrl+Return"))
l.addWidget(save)
qconnect(save.clicked, self.accept)
- close = QPushButton(tr(TR.ACTIONS_CANCEL))
+ close = QPushButton(tr.actions_cancel())
close.setAutoDefault(False)
l.addWidget(close)
qconnect(close.clicked, self.reject)
@@ -548,7 +548,7 @@ class CardLayout(QDialog):
def onRemove(self) -> None:
if len(self.templates) < 2:
- showInfo(tr(TR.CARD_TEMPLATES_AT_LEAST_ONE_CARD_TYPE_IS))
+ showInfo(tr.card_templates_at_least_one_card_type_is())
return
def get_count() -> int:
@@ -586,7 +586,7 @@ class CardLayout(QDialog):
def onRename(self) -> None:
template = self.current_template()
- name = getOnlyText(tr(TR.ACTIONS_NEW_NAME), default=template["name"]).replace(
+ name = getOnlyText(tr.actions_new_name(), default=template["name"]).replace(
'"', ""
)
if not name.strip():
@@ -653,7 +653,7 @@ class CardLayout(QDialog):
def _flipQA(self, src: Dict, dst: Dict) -> None:
m = re.match("(?s)(.+)
(.+)", src["afmt"])
if not m:
- showInfo(tr(TR.CARD_TEMPLATES_ANKI_COULDNT_FIND_THE_LINE_BETWEEN))
+ showInfo(tr.card_templates_anki_couldnt_find_the_line_between())
return
self.change_tracker.mark_basic()
dst["afmt"] = "{{FrontSide}}\n\n
\n\n%s" % src["qfmt"]
@@ -663,29 +663,29 @@ class CardLayout(QDialog):
m = QMenu(self)
if not self._isCloze():
- a = m.addAction(tr(TR.CARD_TEMPLATES_ADD_CARD_TYPE))
+ a = m.addAction(tr.card_templates_add_card_type())
qconnect(a.triggered, self.onAddCard)
- a = m.addAction(tr(TR.CARD_TEMPLATES_REMOVE_CARD_TYPE))
+ a = m.addAction(tr.card_templates_remove_card_type())
qconnect(a.triggered, self.onRemove)
- a = m.addAction(tr(TR.CARD_TEMPLATES_RENAME_CARD_TYPE))
+ a = m.addAction(tr.card_templates_rename_card_type())
qconnect(a.triggered, self.onRename)
- a = m.addAction(tr(TR.CARD_TEMPLATES_REPOSITION_CARD_TYPE))
+ a = m.addAction(tr.card_templates_reposition_card_type())
qconnect(a.triggered, self.onReorder)
m.addSeparator()
t = self.current_template()
if t["did"]:
- s = tr(TR.CARD_TEMPLATES_ON)
+ s = tr.card_templates_on()
else:
- s = tr(TR.CARD_TEMPLATES_OFF)
- a = m.addAction(tr(TR.CARD_TEMPLATES_DECK_OVERRIDE) + s)
+ s = tr.card_templates_off()
+ a = m.addAction(tr.card_templates_deck_override() + s)
qconnect(a.triggered, self.onTargetDeck)
- a = m.addAction(tr(TR.CARD_TEMPLATES_BROWSER_APPEARANCE))
+ a = m.addAction(tr.card_templates_browser_appearance())
qconnect(a.triggered, self.onBrowserDisplay)
m.exec_(self.topAreaForm.templateOptions.mapToGlobal(QPoint(0, 0)))
@@ -795,7 +795,7 @@ class CardLayout(QDialog):
showWarning(str(e))
return
self.mw.reset()
- tooltip(tr(TR.CARD_TEMPLATES_CHANGES_SAVED), parent=self.parentWidget())
+ tooltip(tr.card_templates_changes_saved(), parent=self.parentWidget())
self.cleanup()
gui_hooks.sidebar_should_refresh_notetypes()
return QDialog.accept(self)
@@ -804,7 +804,7 @@ class CardLayout(QDialog):
def reject(self) -> None:
if self.change_tracker.changed():
- if not askUser(tr(TR.CARD_TEMPLATES_DISCARD_CHANGES)):
+ if not askUser(tr.card_templates_discard_changes()):
return
self.cleanup()
return QDialog.reject(self)
diff --git a/qt/aqt/customstudy.py b/qt/aqt/customstudy.py
index 5533b7178..cee0c8c23 100644
--- a/qt/aqt/customstudy.py
+++ b/qt/aqt/customstudy.py
@@ -50,11 +50,11 @@ class CustomStudy(QDialog):
smin = 1
smax = DYN_MAX_SIZE
sval = 1
- post = tr(TR.CUSTOM_STUDY_CARDS)
+ post = tr.custom_study_cards()
tit = ""
spShow = True
typeShow = False
- ok = tr(TR.CUSTOM_STUDY_OK)
+ ok = tr.custom_study_ok()
def plus(num: Union[int, str]) -> str:
if num == 1000:
@@ -71,7 +71,7 @@ class CustomStudy(QDialog):
tit = tr(
TR.CUSTOM_STUDY_NEW_CARDS_IN_DECK_OVER_TODAY, val=plus(newExceeding)
)
- pre = tr(TR.CUSTOM_STUDY_INCREASE_TODAYS_NEW_CARD_LIMIT_BY)
+ pre = tr.custom_study_increase_todays_new_card_limit_by()
sval = min(new, self.deck.get("extendNew", 10))
smin = -DYN_MAX_SIZE
smax = newExceeding
@@ -85,26 +85,26 @@ class CustomStudy(QDialog):
tit = tr(
TR.CUSTOM_STUDY_REVIEWS_DUE_IN_DECK_OVER_TODAY, val=plus(revExceeding)
)
- pre = tr(TR.CUSTOM_STUDY_INCREASE_TODAYS_REVIEW_LIMIT_BY)
+ pre = tr.custom_study_increase_todays_review_limit_by()
sval = min(rev, self.deck.get("extendRev", 10))
smin = -DYN_MAX_SIZE
smax = revExceeding
elif idx == RADIO_FORGOT:
- pre = tr(TR.CUSTOM_STUDY_REVIEW_CARDS_FORGOTTEN_IN_LAST)
- post = tr(TR.SCHEDULING_DAYS)
+ pre = tr.custom_study_review_cards_forgotten_in_last()
+ post = tr.scheduling_days()
smax = 30
elif idx == RADIO_AHEAD:
- pre = tr(TR.CUSTOM_STUDY_REVIEW_AHEAD_BY)
- post = tr(TR.SCHEDULING_DAYS)
+ pre = tr.custom_study_review_ahead_by()
+ post = tr.scheduling_days()
elif idx == RADIO_PREVIEW:
- pre = tr(TR.CUSTOM_STUDY_PREVIEW_NEW_CARDS_ADDED_IN_THE)
- post = tr(TR.SCHEDULING_DAYS)
+ pre = tr.custom_study_preview_new_cards_added_in_the()
+ post = tr.scheduling_days()
sval = 1
elif idx == RADIO_CRAM:
- pre = tr(TR.CUSTOM_STUDY_SELECT)
- post = tr(TR.CUSTOM_STUDY_CARDS_FROM_THE_DECK)
+ pre = tr.custom_study_select()
+ post = tr.custom_study_cards_from_the_deck()
# tit = _("After pressing OK, you can choose which tags to include.")
- ok = tr(TR.CUSTOM_STUDY_CHOOSE_TAGS)
+ ok = tr.custom_study_choose_tags()
sval = 100
typeShow = True
sp.setVisible(spShow)
@@ -144,10 +144,10 @@ class CustomStudy(QDialog):
elif i == RADIO_CRAM:
tags = self._getTags()
# the rest create a filtered deck
- cur = self.mw.col.decks.byName(tr(TR.CUSTOM_STUDY_CUSTOM_STUDY_SESSION))
+ cur = self.mw.col.decks.byName(tr.custom_study_custom_study_session())
if cur:
if not cur["dyn"]:
- showInfo(tr(TR.CUSTOM_STUDY_MUST_RENAME_DECK))
+ showInfo(tr.custom_study_must_rename_deck())
QDialog.accept(self)
return
else:
@@ -157,9 +157,7 @@ class CustomStudy(QDialog):
dyn = cur
self.mw.col.decks.select(cur["id"])
else:
- did = self.mw.col.decks.new_filtered(
- tr(TR.CUSTOM_STUDY_CUSTOM_STUDY_SESSION)
- )
+ did = self.mw.col.decks.new_filtered(tr.custom_study_custom_study_session())
dyn = self.mw.col.decks.get(did)
# and then set various options
if i == RADIO_FORGOT:
@@ -214,7 +212,7 @@ class CustomStudy(QDialog):
# generate cards
self.created_custom_study = True
if not self.mw.col.sched.rebuild_filtered_deck(dyn["id"]):
- showWarning(tr(TR.CUSTOM_STUDY_NO_CARDS_MATCHED_THE_CRITERIA_YOU))
+ showWarning(tr.custom_study_no_cards_matched_the_criteria_you())
return
self.mw.moveToState("overview")
QDialog.accept(self)
diff --git a/qt/aqt/deck_ops.py b/qt/aqt/deck_ops.py
index 1e5cbff15..571b33519 100644
--- a/qt/aqt/deck_ops.py
+++ b/qt/aqt/deck_ops.py
@@ -57,7 +57,7 @@ def add_deck_dialog(
success: PerformOpOptionalSuccessCallback = None,
) -> None:
if name := getOnlyText(
- tr(TR.DECKS_NEW_DECK_NAME), default=default_text, parent=parent
+ tr.decks_new_deck_name(), default=default_text, parent=parent
).strip():
add_deck(mw=mw, name=name, success=success)
diff --git a/qt/aqt/deckbrowser.py b/qt/aqt/deckbrowser.py
index ecb326d00..e20960aa1 100644
--- a/qt/aqt/deckbrowser.py
+++ b/qt/aqt/deckbrowser.py
@@ -169,9 +169,9 @@ class DeckBrowser:
buf = """
%s | %s |
%s | |
""" % (
- tr(TR.DECKS_DECK),
- tr(TR.STATISTICS_DUE_COUNT),
- tr(TR.ACTIONS_NEW),
+ tr.decks_deck(),
+ tr.statistics_due_count(),
+ tr.actions_new(),
)
buf += self._topLevelDragRow()
@@ -250,13 +250,13 @@ class DeckBrowser:
def _showOptions(self, did: str) -> None:
m = QMenu(self.mw)
- a = m.addAction(tr(TR.ACTIONS_RENAME))
+ a = m.addAction(tr.actions_rename())
qconnect(a.triggered, lambda b, did=did: self._rename(DeckID(int(did))))
- a = m.addAction(tr(TR.ACTIONS_OPTIONS))
+ a = m.addAction(tr.actions_options())
qconnect(a.triggered, lambda b, did=did: self._options(DeckID(int(did))))
- a = m.addAction(tr(TR.ACTIONS_EXPORT))
+ a = m.addAction(tr.actions_export())
qconnect(a.triggered, lambda b, did=did: self._export(DeckID(int(did))))
- a = m.addAction(tr(TR.ACTIONS_DELETE))
+ a = m.addAction(tr.actions_delete())
qconnect(a.triggered, lambda b, did=did: self._delete(DeckID(int(did))))
gui_hooks.deck_browser_will_show_options_menu(m, int(did))
m.exec_(QCursor.pos())
@@ -267,7 +267,7 @@ class DeckBrowser:
def _rename(self, did: DeckID) -> None:
deck = self.mw.col.decks.get(did)
current_name = deck["name"]
- new_name = getOnlyText(tr(TR.DECKS_NEW_DECK_NAME), default=current_name)
+ new_name = getOnlyText(tr.decks_new_deck_name(), default=current_name)
if not new_name or new_name == current_name:
return
@@ -296,9 +296,9 @@ class DeckBrowser:
######################################################################
drawLinks = [
- ["", "shared", tr(TR.DECKS_GET_SHARED)],
- ["", "create", tr(TR.DECKS_CREATE_DECK)],
- ["Ctrl+Shift+I", "import", tr(TR.DECKS_IMPORT_FILE)],
+ ["", "shared", tr.decks_get_shared()],
+ ["", "create", tr.decks_create_deck()],
+ ["Ctrl+Shift+I", "import", tr.decks_import_file()],
]
def _drawButtons(self) -> None:
@@ -335,17 +335,17 @@ class DeckBrowser:
- {tr(TR.SCHEDULING_UPDATE_SOON)}
+ {tr.scheduling_update_soon()}
@@ -365,5 +365,5 @@ class DeckBrowser:
prefs.scheduling.new_timezone = False
self.mw.col.set_preferences(prefs)
- showInfo(tr(TR.SCHEDULING_UPDATE_DONE))
+ showInfo(tr.scheduling_update_done())
self.refresh()
diff --git a/qt/aqt/deckchooser.py b/qt/aqt/deckchooser.py
index 7837f38e5..2dae14190 100644
--- a/qt/aqt/deckchooser.py
+++ b/qt/aqt/deckchooser.py
@@ -6,7 +6,7 @@ from typing import Optional
from anki.decks import DEFAULT_DECK_ID, DeckID
from aqt import AnkiQt
from aqt.qt import *
-from aqt.utils import TR, HelpPage, shortcut, tr
+from aqt.utils import HelpPage, shortcut, tr
class DeckChooser(QHBoxLayout):
@@ -34,14 +34,14 @@ class DeckChooser(QHBoxLayout):
# text label before button?
if show_label:
- self.deckLabel = QLabel(tr(TR.DECKS_DECK))
+ self.deckLabel = QLabel(tr.decks_deck())
self.addWidget(self.deckLabel)
# decks box
self.deck = QPushButton()
qconnect(self.deck.clicked, self.choose_deck)
self.deck.setAutoDefault(False)
- self.deck.setToolTip(shortcut(tr(TR.QT_MISC_TARGET_DECK_CTRLANDD)))
+ self.deck.setToolTip(shortcut(tr.qt_misc_target_deck_ctrlandd()))
qconnect(
QShortcut(QKeySequence("Ctrl+D"), self._widget).activated, self.choose_deck
)
@@ -89,8 +89,8 @@ class DeckChooser(QHBoxLayout):
ret = StudyDeck(
self.mw,
current=current,
- accept=tr(TR.ACTIONS_CHOOSE),
- title=tr(TR.QT_MISC_CHOOSE_DECK),
+ accept=tr.actions_choose(),
+ title=tr.qt_misc_choose_deck(),
help=HelpPage.EDITING,
cancel=False,
parent=self._widget,
diff --git a/qt/aqt/deckconf.py b/qt/aqt/deckconf.py
index 428bb6a98..cd8346706 100644
--- a/qt/aqt/deckconf.py
+++ b/qt/aqt/deckconf.py
@@ -37,7 +37,7 @@ class DeckConf(QDialog):
self.form = aqt.forms.dconf.Ui_Dialog()
self.form.setupUi(self)
gui_hooks.deck_conf_did_setup_ui_form(self)
- self.mw.checkpoint(tr(TR.ACTIONS_OPTIONS))
+ self.mw.checkpoint(tr.actions_options())
self.setupCombos()
self.setupConfs()
self.setWindowModality(Qt.WindowModal)
@@ -94,13 +94,13 @@ class DeckConf(QDialog):
def confOpts(self) -> None:
m = QMenu(self.mw)
- a = m.addAction(tr(TR.ACTIONS_ADD))
+ a = m.addAction(tr.actions_add())
qconnect(a.triggered, self.addGroup)
- a = m.addAction(tr(TR.ACTIONS_DELETE))
+ a = m.addAction(tr.actions_delete())
qconnect(a.triggered, self.remGroup)
- a = m.addAction(tr(TR.ACTIONS_RENAME))
+ a = m.addAction(tr.actions_rename())
qconnect(a.triggered, self.renameGroup)
- a = m.addAction(tr(TR.SCHEDULING_SET_FOR_ALL_SUBDECKS))
+ a = m.addAction(tr.scheduling_set_for_all_subdecks())
qconnect(a.triggered, self.setChildren)
if not self.childDids:
a.setEnabled(False)
@@ -117,13 +117,13 @@ class DeckConf(QDialog):
self.loadConf()
cnt = len(self.mw.col.decks.didsForConf(conf))
if cnt > 1:
- txt = tr(TR.SCHEDULING_YOUR_CHANGES_WILL_AFFECT_MULTIPLE_DECKS)
+ txt = tr.scheduling_your_changes_will_affect_multiple_decks()
else:
txt = ""
self.form.count.setText(txt)
def addGroup(self) -> None:
- name = getOnlyText(tr(TR.SCHEDULING_NEW_OPTIONS_GROUP_NAME))
+ name = getOnlyText(tr.scheduling_new_options_group_name())
if not name:
return
@@ -139,7 +139,7 @@ class DeckConf(QDialog):
def remGroup(self) -> None:
if int(self.conf["id"]) == 1:
- showInfo(tr(TR.SCHEDULING_THE_DEFAULT_CONFIGURATION_CANT_BE_REMOVED), self)
+ showInfo(tr.scheduling_the_default_configuration_cant_be_removed(), self)
else:
gui_hooks.deck_conf_will_remove_config(self, self.deck, self.conf)
self.mw.col.modSchema(check=True)
@@ -150,7 +150,7 @@ class DeckConf(QDialog):
def renameGroup(self) -> None:
old = self.conf["name"]
- name = getOnlyText(tr(TR.ACTIONS_NEW_NAME), default=old)
+ name = getOnlyText(tr.actions_new_name(), default=old)
if not name or name == old:
return
@@ -274,10 +274,10 @@ class DeckConf(QDialog):
ret.append(i)
except:
# invalid, don't update
- showWarning(tr(TR.SCHEDULING_STEPS_MUST_BE_NUMBERS))
+ showWarning(tr.scheduling_steps_must_be_numbers())
return
if len(ret) < minSize:
- showWarning(tr(TR.SCHEDULING_AT_LEAST_ONE_STEP_IS_REQUIRED))
+ showWarning(tr.scheduling_at_least_one_step_is_required())
return
conf[key] = ret
diff --git a/qt/aqt/editcurrent.py b/qt/aqt/editcurrent.py
index 79ebd8e83..1d159dcd4 100644
--- a/qt/aqt/editcurrent.py
+++ b/qt/aqt/editcurrent.py
@@ -6,7 +6,7 @@ from anki.collection import OpChanges
from anki.errors import NotFoundError
from aqt import gui_hooks
from aqt.qt import *
-from aqt.utils import TR, disable_help_button, restoreGeom, saveGeom, tr
+from aqt.utils import disable_help_button, restoreGeom, saveGeom, tr
class EditCurrent(QDialog):
@@ -16,7 +16,7 @@ class EditCurrent(QDialog):
self.mw = mw
self.form = aqt.forms.editcurrent.Ui_Dialog()
self.form.setupUi(self)
- self.setWindowTitle(tr(TR.EDITING_EDIT_CURRENT))
+ self.setWindowTitle(tr.editing_edit_current())
disable_help_button(self)
self.setMinimumHeight(400)
self.setMinimumWidth(250)
diff --git a/qt/aqt/editor.py b/qt/aqt/editor.py
index b18e99537..dc9054f0a 100644
--- a/qt/aqt/editor.py
+++ b/qt/aqt/editor.py
@@ -143,16 +143,16 @@ class Editor:
self._addButton(
None,
"fields",
- tr(TR.EDITING_CUSTOMIZE_FIELDS),
- f"{tr(TR.EDITING_FIELDS)}...",
+ tr.editing_customize_fields(),
+ f"{tr.editing_fields()}...",
disables=False,
rightside=False,
),
self._addButton(
None,
"cards",
- tr(TR.EDITING_CUSTOMIZE_CARD_TEMPLATES_CTRLANDL),
- f"{tr(TR.EDITING_CARDS)}...",
+ tr.editing_customize_card_templates_ctrlandl(),
+ f"{tr.editing_cards()}...",
disables=False,
rightside=False,
),
@@ -162,36 +162,36 @@ class Editor:
righttopbtns: List[str] = [
self._addButton(
- "text_bold", "bold", tr(TR.EDITING_BOLD_TEXT_CTRLANDB), id="bold"
+ "text_bold", "bold", tr.editing_bold_text_ctrlandb(), id="bold"
),
self._addButton(
"text_italic",
"italic",
- tr(TR.EDITING_ITALIC_TEXT_CTRLANDI),
+ tr.editing_italic_text_ctrlandi(),
id="italic",
),
self._addButton(
"text_under",
"underline",
- tr(TR.EDITING_UNDERLINE_TEXT_CTRLANDU),
+ tr.editing_underline_text_ctrlandu(),
id="underline",
),
self._addButton(
"text_super",
"super",
- tr(TR.EDITING_SUPERSCRIPT_CTRLANDAND),
+ tr.editing_superscript_ctrlandand(),
id="superscript",
),
self._addButton(
- "text_sub", "sub", tr(TR.EDITING_SUBSCRIPT_CTRLAND), id="subscript"
+ "text_sub", "sub", tr.editing_subscript_ctrland(), id="subscript"
),
self._addButton(
- "text_clear", "clear", tr(TR.EDITING_REMOVE_FORMATTING_CTRLANDR)
+ "text_clear", "clear", tr.editing_remove_formatting_ctrlandr()
),
self._addButton(
None,
"colour",
- tr(TR.EDITING_SET_FOREGROUND_COLOUR_F7),
+ tr.editing_set_foreground_colour_f7(),
"""
""",
@@ -199,18 +199,18 @@ class Editor:
self._addButton(
None,
"changeCol",
- tr(TR.EDITING_CHANGE_COLOUR_F8),
+ tr.editing_change_colour_f8(),
"""
""",
),
self._addButton(
- "text_cloze", "cloze", tr(TR.EDITING_CLOZE_DELETION_CTRLANDSHIFTANDC)
+ "text_cloze", "cloze", tr.editing_cloze_deletion_ctrlandshiftandc()
),
self._addButton(
- "paperclip", "attach", tr(TR.EDITING_ATTACH_PICTURESAUDIOVIDEO_F3)
+ "paperclip", "attach", tr.editing_attach_picturesaudiovideo_f3()
),
- self._addButton("media-record", "record", tr(TR.EDITING_RECORD_AUDIO_F5)),
+ self._addButton("media-record", "record", tr.editing_record_audio_f5()),
self._addButton("more", "more"),
]
@@ -232,7 +232,7 @@ class Editor:
bgcol = self.mw.app.palette().window().color().name() # type: ignore
# then load page
self.web.stdHtml(
- _html % (bgcol, topbuts, tr(TR.EDITING_SHOW_DUPLICATES)),
+ _html % (bgcol, topbuts, tr.editing_show_duplicates()),
css=[
"css/vendor/bootstrap.min.css",
"css/vendor/bootstrap-icons.css",
@@ -696,13 +696,11 @@ class Editor:
tb.setSpacing(12)
tb.setContentsMargins(2, 6, 2, 6)
# tags
- l = QLabel(tr(TR.EDITING_TAGS))
+ l = QLabel(tr.editing_tags())
tb.addWidget(l, 1, 0)
self.tags = aqt.tagedit.TagEdit(self.widget)
qconnect(self.tags.lostFocus, self.on_tag_focus_lost)
- self.tags.setToolTip(
- shortcut(tr(TR.EDITING_JUMP_TO_TAGS_WITH_CTRLANDSHIFTANDT))
- )
+ self.tags.setToolTip(shortcut(tr.editing_jump_to_tags_with_ctrlandshiftandt()))
border = theme_manager.color(colors.BORDER)
self.tags.setStyleSheet(f"border: 1px solid {border}")
tb.addWidget(self.tags, 1, 1)
@@ -768,9 +766,9 @@ class Editor:
# check that the model is set up for cloze deletion
if self.note.model()["type"] != MODEL_CLOZE:
if self.addMode:
- tooltip(tr(TR.EDITING_WARNING_CLOZE_DELETIONS_WILL_NOT_WORK))
+ tooltip(tr.editing_warning_cloze_deletions_will_not_work())
else:
- showInfo(tr(TR.EDITING_TO_MAKE_A_CLOZE_DELETION_ON))
+ showInfo(tr.editing_to_make_a_cloze_deletion_on())
return
# find the highest existing cloze
highest = 0
@@ -828,14 +826,14 @@ class Editor:
extension_filter = " ".join(
f"*.{extension}" for extension in sorted(itertools.chain(pics, audio))
)
- filter = f"{tr(TR.EDITING_MEDIA)} ({extension_filter})"
+ filter = f"{tr.editing_media()} ({extension_filter})"
def accept(file: str) -> None:
self.addMedia(file)
file = getFile(
parent=self.widget,
- title=tr(TR.EDITING_ADD_MEDIA),
+ title=tr.editing_add_media(),
cb=cast(Callable[[Any], None], accept),
filter=filter,
key="media",
@@ -1062,17 +1060,17 @@ class Editor:
m = QMenu(self.mw)
for text, handler, shortcut in (
- (tr(TR.EDITING_MATHJAX_INLINE), self.insertMathjaxInline, "Ctrl+M, M"),
- (tr(TR.EDITING_MATHJAX_BLOCK), self.insertMathjaxBlock, "Ctrl+M, E"),
+ (tr.editing_mathjax_inline(), self.insertMathjaxInline, "Ctrl+M, M"),
+ (tr.editing_mathjax_block(), self.insertMathjaxBlock, "Ctrl+M, E"),
(
- tr(TR.EDITING_MATHJAX_CHEMISTRY),
+ tr.editing_mathjax_chemistry(),
self.insertMathjaxChemistry,
"Ctrl+M, C",
),
- (tr(TR.EDITING_LATEX), self.insertLatex, "Ctrl+T, T"),
- (tr(TR.EDITING_LATEX_EQUATION), self.insertLatexEqn, "Ctrl+T, E"),
- (tr(TR.EDITING_LATEX_MATH_ENV), self.insertLatexMathEnv, "Ctrl+T, M"),
- (tr(TR.EDITING_EDIT_HTML), self.onHtmlEdit, "Ctrl+Shift+X"),
+ (tr.editing_latex(), self.insertLatex, "Ctrl+T, T"),
+ (tr.editing_latex_equation(), self.insertLatexEqn, "Ctrl+T, E"),
+ (tr.editing_latex_math_env(), self.insertLatexMathEnv, "Ctrl+T, M"),
+ (tr.editing_edit_html(), self.onHtmlEdit, "Ctrl+Shift+X"),
):
a = m.addAction(text)
qconnect(a.triggered, handler)
@@ -1323,11 +1321,11 @@ class EditorWebView(AnkiWebView):
def contextMenuEvent(self, evt: QContextMenuEvent) -> None:
m = QMenu(self)
- a = m.addAction(tr(TR.EDITING_CUT))
+ a = m.addAction(tr.editing_cut())
qconnect(a.triggered, self.onCut)
- a = m.addAction(tr(TR.ACTIONS_COPY))
+ a = m.addAction(tr.actions_copy())
qconnect(a.triggered, self.onCopy)
- a = m.addAction(tr(TR.EDITING_PASTE))
+ a = m.addAction(tr.editing_paste())
qconnect(a.triggered, self.onPaste)
gui_hooks.editor_will_show_context_menu(self, m)
m.popup(QCursor.pos())
diff --git a/qt/aqt/emptycards.py b/qt/aqt/emptycards.py
index 9f8ff67f8..3f0d7cedd 100644
--- a/qt/aqt/emptycards.py
+++ b/qt/aqt/emptycards.py
@@ -22,7 +22,7 @@ def show_empty_cards(mw: aqt.main.AnkiQt) -> None:
mw.progress.finish()
report: EmptyCardsReport = fut.result()
if not report.notes:
- tooltip(tr(TR.EMPTY_CARDS_NOT_FOUND))
+ tooltip(tr.empty_cards_not_found())
return
diag = EmptyCardsDialog(mw, report)
diag.show()
@@ -40,9 +40,9 @@ class EmptyCardsDialog(QDialog):
self.form = aqt.forms.emptycards.Ui_Dialog()
self.form.setupUi(self)
restoreGeom(self, "emptycards")
- self.setWindowTitle(tr(TR.EMPTY_CARDS_WINDOW_TITLE))
+ self.setWindowTitle(tr.empty_cards_window_title())
disable_help_button(self)
- self.form.keep_notes.setText(tr(TR.EMPTY_CARDS_PRESERVE_NOTES_CHECKBOX))
+ self.form.keep_notes.setText(tr.empty_cards_preserve_notes_checkbox())
self.form.webview.title = "empty cards"
self.form.webview.set_bridge_command(self._on_note_link_clicked, self)
@@ -63,7 +63,7 @@ class EmptyCardsDialog(QDialog):
qconnect(self.finished, on_finished)
self._delete_button = self.form.buttonBox.addButton(
- tr(TR.EMPTY_CARDS_DELETE_BUTTON), QDialogButtonBox.ActionRole
+ tr.empty_cards_delete_button(), QDialogButtonBox.ActionRole
)
self._delete_button.setAutoDefault(False)
self._delete_button.clicked.connect(self._on_delete)
diff --git a/qt/aqt/errors.py b/qt/aqt/errors.py
index 8ed9e6273..1bae9a867 100644
--- a/qt/aqt/errors.py
+++ b/qt/aqt/errors.py
@@ -65,7 +65,7 @@ class ErrorHandler(QObject):
self.timer.start()
def tempFolderMsg(self) -> str:
- return tr(TR.QT_MISC_UNABLE_TO_ACCESS_ANKI_MEDIA_FOLDER)
+ return tr.qt_misc_unable_to_access_anki_media_folder()
def onTimeout(self) -> None:
error = html.escape(self.pool)
@@ -76,10 +76,10 @@ class ErrorHandler(QObject):
if "DeprecationWarning" in error:
return
if "10013" in error:
- showWarning(tr(TR.QT_MISC_YOUR_FIREWALL_OR_ANTIVIRUS_PROGRAM_IS))
+ showWarning(tr.qt_misc_your_firewall_or_antivirus_program_is())
return
if "no default input" in error.lower():
- showWarning(tr(TR.QT_MISC_PLEASE_CONNECT_A_MICROPHONE_AND_ENSURE))
+ showWarning(tr.qt_misc_please_connect_a_microphone_and_ensure())
return
if "invalidTempFolder" in error:
showWarning(self.tempFolderMsg())
@@ -87,17 +87,17 @@ class ErrorHandler(QObject):
if "Beautiful Soup is not an HTTP client" in error:
return
if "database or disk is full" in error or "Errno 28" in error:
- showWarning(tr(TR.QT_MISC_YOUR_COMPUTERS_STORAGE_MAY_BE_FULL))
+ showWarning(tr.qt_misc_your_computers_storage_may_be_full())
return
if "disk I/O error" in error:
- showWarning(markdown(tr(TR.ERRORS_ACCESSING_DB)))
+ showWarning(markdown(tr.errors_accessing_db()))
return
if self.mw.addonManager.dirty:
- txt = markdown(tr(TR.ERRORS_ADDONS_ACTIVE_POPUP))
+ txt = markdown(tr.errors_addons_active_popup())
error = f"{supportText() + self._addonText(error)}\n{error}"
else:
- txt = markdown(tr(TR.ERRORS_STANDARD_POPUP))
+ txt = markdown(tr.errors_standard_popup())
error = f"{supportText()}\n{error}"
# show dialog
diff --git a/qt/aqt/exporting.py b/qt/aqt/exporting.py
index 45fc0a1b5..347083408 100644
--- a/qt/aqt/exporting.py
+++ b/qt/aqt/exporting.py
@@ -59,13 +59,13 @@ class ExportDialog(QDialog):
self.exporterChanged(idx)
# deck list
if self.cids is None:
- self.decks = [tr(TR.EXPORTING_ALL_DECKS)]
+ self.decks = [tr.exporting_all_decks()]
self.decks.extend(d.name for d in self.col.decks.all_names_and_ids())
else:
- self.decks = [tr(TR.EXPORTING_SELECTED_NOTES)]
+ self.decks = [tr.exporting_selected_notes()]
self.frm.deck.addItems(self.decks)
# save button
- b = QPushButton(tr(TR.EXPORTING_EXPORT))
+ b = QPushButton(tr.exporting_export())
self.frm.buttonBox.addButton(b, QDialogButtonBox.AcceptRole)
# set default option if accessed through deck button
if did:
@@ -117,7 +117,7 @@ class ExportDialog(QDialog):
self.exporter.did = self.col.decks.id(name)
if self.isVerbatim:
name = time.strftime("-%Y-%m-%d@%H-%M-%S", time.localtime(time.time()))
- deck_name = tr(TR.EXPORTING_COLLECTION) + name
+ deck_name = tr.exporting_collection() + name
else:
# Get deck name and remove invalid filename characters
deck_name = self.decks[self.frm.deck.currentIndex()]
@@ -131,7 +131,7 @@ class ExportDialog(QDialog):
while 1:
file = getSaveFile(
self,
- tr(TR.ACTIONS_EXPORT),
+ tr.actions_export(),
"export",
key_str,
self.exporter.ext,
@@ -181,7 +181,7 @@ class ExportDialog(QDialog):
def on_export_finished(self) -> None:
if self.isVerbatim:
- msg = tr(TR.EXPORTING_COLLECTION_EXPORTED)
+ msg = tr.exporting_collection_exported()
self.mw.reopen()
else:
if self.isTextNote:
diff --git a/qt/aqt/fields.py b/qt/aqt/fields.py
index 5fb326351..881b65473 100644
--- a/qt/aqt/fields.py
+++ b/qt/aqt/fields.py
@@ -34,7 +34,7 @@ class FieldDialog(QDialog):
self.mm = self.mw.col.models
self.model = nt
self.mm._remove_from_cache(self.model["id"])
- self.mw.checkpoint(tr(TR.EDITING_FIELDS))
+ self.mw.checkpoint(tr.editing_fields())
self.change_tracker = ChangeTracker(self.mw)
self.form = aqt.forms.fields.Ui_Dialog()
self.form.setupUi(self)
@@ -103,24 +103,24 @@ class FieldDialog(QDialog):
if not txt:
return None
if txt[0] in "#^/":
- showWarning(tr(TR.FIELDS_NAME_FIRST_LETTER_NOT_VALID))
+ showWarning(tr.fields_name_first_letter_not_valid())
return None
for letter in """:{"}""":
if letter in txt:
- showWarning(tr(TR.FIELDS_NAME_INVALID_LETTER))
+ showWarning(tr.fields_name_invalid_letter())
return None
for f in self.model["flds"]:
if ignoreOrd is not None and f["ord"] == ignoreOrd:
continue
if f["name"] == txt:
- showWarning(tr(TR.FIELDS_THAT_FIELD_NAME_IS_ALREADY_USED))
+ showWarning(tr.fields_that_field_name_is_already_used())
return None
return txt
def onRename(self) -> None:
idx = self.currentIdx
f = self.model["flds"][idx]
- name = self._uniqueName(tr(TR.ACTIONS_NEW_NAME), self.currentIdx, f["name"])
+ name = self._uniqueName(tr.actions_new_name(), self.currentIdx, f["name"])
if not name:
return
@@ -134,7 +134,7 @@ class FieldDialog(QDialog):
self.form.fieldList.setCurrentRow(idx)
def onAdd(self) -> None:
- name = self._uniqueName(tr(TR.FIELDS_FIELD_NAME))
+ name = self._uniqueName(tr.fields_field_name())
if not name:
return
if not self.change_tracker.mark_schema():
@@ -147,7 +147,7 @@ class FieldDialog(QDialog):
def onDelete(self) -> None:
if len(self.model["flds"]) < 2:
- showWarning(tr(TR.FIELDS_NOTES_REQUIRE_AT_LEAST_ONE_FIELD))
+ showWarning(tr.fields_notes_require_at_least_one_field())
return
count = self.mm.useCount(self.model)
c = tr(TR.BROWSING_NOTE_COUNT, count=count)
diff --git a/qt/aqt/filtered_deck.py b/qt/aqt/filtered_deck.py
index 5e10b5a51..f2d321d07 100644
--- a/qt/aqt/filtered_deck.py
+++ b/qt/aqt/filtered_deck.py
@@ -115,9 +115,9 @@ class FilteredDeckConfigDialog(QDialog):
existing = deck.id != 0
if existing:
- build_label = tr(TR.ACTIONS_REBUILD)
+ build_label = tr.actions_rebuild()
else:
- build_label = tr(TR.DECKS_BUILD)
+ build_label = tr.decks_build()
self.form.buttonBox.button(QDialogButtonBox.Ok).setText(build_label)
form.resched.setChecked(config.reschedule)
@@ -334,9 +334,9 @@ class FilteredDeckConfigDialog(QDialog):
ret.append(i)
except:
# invalid, don't update
- showWarning(tr(TR.SCHEDULING_STEPS_MUST_BE_NUMBERS))
+ showWarning(tr.scheduling_steps_must_be_numbers())
return None
if len(ret) < minSize:
- showWarning(tr(TR.SCHEDULING_AT_LEAST_ONE_STEP_IS_REQUIRED))
+ showWarning(tr.scheduling_at_least_one_step_is_required())
return None
return ret
diff --git a/qt/aqt/find_and_replace.py b/qt/aqt/find_and_replace.py
index 1c7fc3207..791c54671 100644
--- a/qt/aqt/find_and_replace.py
+++ b/qt/aqt/find_and_replace.py
@@ -100,8 +100,8 @@ class FindAndReplaceDialog(QDialog):
def _show(self, field_names: Sequence[str]) -> None:
# add "all fields" and "tags" to the top of the list
self.field_names = [
- tr(TR.BROWSING_ALL_FIELDS),
- tr(TR.EDITING_TAGS),
+ tr.browsing_all_fields(),
+ tr.editing_tags(),
] + list(field_names)
disable_help_button(self)
diff --git a/qt/aqt/importing.py b/qt/aqt/importing.py
index 3ba98998a..6727c805a 100644
--- a/qt/aqt/importing.py
+++ b/qt/aqt/importing.py
@@ -50,8 +50,8 @@ class ChangeMap(QDialog):
setCurrent = True
self.frm.fields.setCurrentRow(n)
n += 1
- self.frm.fields.addItem(QListWidgetItem(tr(TR.IMPORTING_MAP_TO_TAGS)))
- self.frm.fields.addItem(QListWidgetItem(tr(TR.IMPORTING_IGNORE_FIELD)))
+ self.frm.fields.addItem(QListWidgetItem(tr.importing_map_to_tags()))
+ self.frm.fields.addItem(QListWidgetItem(tr.importing_ignore_field()))
if not setCurrent:
if current == "_tags":
self.frm.fields.setCurrentRow(n)
@@ -107,7 +107,7 @@ class ImportDialog(QDialog):
self.frm.tagModified.setText(self.mw.pm.profile.get("tagModified", ""))
self.frm.tagModified.setCol(self.mw.col)
# import button
- b = QPushButton(tr(TR.ACTIONS_IMPORT))
+ b = QPushButton(tr.actions_import())
self.frm.buttonBox.addButton(b, QDialogButtonBox.AcceptRole)
self.exec_()
@@ -128,7 +128,7 @@ class ImportDialog(QDialog):
# Open a modal dialog to enter an delimiter
# Todo/Idea Constrain the maximum width, so it doesnt take up that much screen space
delim, ok = getText(
- tr(TR.IMPORTING_BY_DEFAULT_ANKI_WILL_DETECT_THE),
+ tr.importing_by_default_anki_will_detect_the(),
self,
help=HelpPage.IMPORTING,
)
@@ -142,7 +142,7 @@ class ImportDialog(QDialog):
delim = delim.replace("\\t", "\t") # un-escape it
if len(delim) > 1:
showWarning(
- tr(TR.IMPORTING_MULTICHARACTER_SEPARATORS_ARE_NOT_SUPPORTED_PLEASE)
+ tr.importing_multicharacter_separators_are_not_supported_please()
)
return
self.hideMapping()
@@ -166,15 +166,15 @@ class ImportDialog(QDialog):
else:
d = self.importer.dialect.delimiter
if d == "\t":
- d = tr(TR.IMPORTING_TAB)
+ d = tr.importing_tab()
elif d == ",":
- d = tr(TR.IMPORTING_COMMA)
+ d = tr.importing_comma()
elif d == " ":
- d = tr(TR.STUDYING_SPACE)
+ d = tr.studying_space()
elif d == ";":
- d = tr(TR.IMPORTING_SEMICOLON)
+ d = tr.importing_semicolon()
elif d == ":":
- d = tr(TR.IMPORTING_COLON)
+ d = tr.importing_colon()
else:
d = repr(d)
txt = tr(TR.IMPORTING_FIELDS_SEPARATED_BY, val=d)
@@ -183,7 +183,7 @@ class ImportDialog(QDialog):
def accept(self) -> None:
self.importer.mapping = self.mapping
if not self.importer.mappingOk():
- showWarning(tr(TR.IMPORTING_THE_FIRST_FIELD_OF_THE_NOTE))
+ showWarning(tr.importing_the_first_field_of_the_note())
return
self.importer.importMode = self.frm.importMode.currentIndex()
self.mw.pm.profile["importMode"] = self.importer.importMode
@@ -196,7 +196,7 @@ class ImportDialog(QDialog):
self.mw.col.models.save(self.importer.model, updateReqs=False)
self.mw.col.decks.select(did)
self.mw.progress.start()
- self.mw.checkpoint(tr(TR.ACTIONS_IMPORT))
+ self.mw.checkpoint(tr.actions_import())
def on_done(future: Future) -> None:
self.mw.progress.finish()
@@ -207,7 +207,7 @@ class ImportDialog(QDialog):
showUnicodeWarning()
return
except Exception as e:
- msg = f"{tr(TR.IMPORTING_FAILED_DEBUG_INFO)}\n"
+ msg = f"{tr.importing_failed_debug_info()}\n"
err = repr(str(e))
if "1-character string" in err:
msg += err
@@ -218,7 +218,7 @@ class ImportDialog(QDialog):
showText(msg)
return
else:
- txt = f"{tr(TR.IMPORTING_IMPORTING_COMPLETE)}\n"
+ txt = f"{tr.importing_importing_complete()}\n"
if self.importer.log:
txt += "\n".join(self.importer.log)
self.close()
@@ -263,13 +263,13 @@ class ImportDialog(QDialog):
text = tr(TR.IMPORTING_FIELD_OF_FILE_IS, val=num + 1)
self.grid.addWidget(QLabel(text), num, 0)
if self.mapping[num] == "_tags":
- text = tr(TR.IMPORTING_MAPPED_TO_TAGS)
+ text = tr.importing_mapped_to_tags()
elif self.mapping[num]:
text = tr(TR.IMPORTING_MAPPED_TO, val=self.mapping[num])
else:
- text = tr(TR.IMPORTING_IGNORED)
+ text = tr.importing_ignored()
self.grid.addWidget(QLabel(text), num, 1)
- button = QPushButton(tr(TR.IMPORTING_CHANGE))
+ button = QPushButton(tr.importing_change())
self.grid.addWidget(button, num, 2)
qconnect(button.clicked, lambda _, s=self, n=num: s.changeMappingNum(n))
@@ -310,12 +310,12 @@ class ImportDialog(QDialog):
def showUnicodeWarning() -> None:
"""Shorthand to show a standard warning."""
- showWarning(tr(TR.IMPORTING_SELECTED_FILE_WAS_NOT_IN_UTF8))
+ showWarning(tr.importing_selected_file_was_not_in_utf8())
def onImport(mw: AnkiQt) -> None:
filt = ";;".join([x[0] for x in importing.importers(mw.col)])
- file = getFile(mw, tr(TR.ACTIONS_IMPORT), None, key="import", filter=filt)
+ file = getFile(mw, tr.actions_import(), None, key="import", filter=filt)
if not file:
return
file = str(file)
@@ -323,10 +323,10 @@ def onImport(mw: AnkiQt) -> None:
head, ext = os.path.splitext(file)
ext = ext.lower()
if ext == ".anki":
- showInfo(tr(TR.IMPORTING_ANKI_FILES_ARE_FROM_A_VERY))
+ showInfo(tr.importing_anki_files_are_from_a_very())
return
elif ext == ".anki2":
- showInfo(tr(TR.IMPORTING_ANKI2_FILES_ARE_NOT_DIRECTLY_IMPORTABLE))
+ showInfo(tr.importing_anki2_files_are_not_directly_importable())
return
importFile(mw, file)
@@ -363,9 +363,9 @@ def importFile(mw: AnkiQt, file: str) -> None:
mw.progress.finish()
msg = repr(str(e))
if msg == "'unknownFormat'":
- showWarning(tr(TR.IMPORTING_UNKNOWN_FILE_FORMAT))
+ showWarning(tr.importing_unknown_file_format())
else:
- msg = f"{tr(TR.IMPORTING_FAILED_DEBUG_INFO)}\n"
+ msg = f"{tr.importing_failed_debug_info()}\n"
msg += str(traceback.format_exc())
showText(msg)
return
@@ -398,14 +398,14 @@ def importFile(mw: AnkiQt, file: str) -> None:
except Exception as e:
err = repr(str(e))
if "invalidFile" in err:
- msg = tr(TR.IMPORTING_INVALID_FILE_PLEASE_RESTORE_FROM_BACKUP)
+ msg = tr.importing_invalid_file_please_restore_from_backup()
showWarning(msg)
elif "invalidTempFolder" in err:
showWarning(mw.errorHandler.tempFolderMsg())
elif "readonly" in err:
- showWarning(tr(TR.IMPORTING_UNABLE_TO_IMPORT_FROM_A_READONLY))
+ showWarning(tr.importing_unable_to_import_from_a_readonly())
else:
- msg = f"{tr(TR.IMPORTING_FAILED_DEBUG_INFO)}\n"
+ msg = f"{tr.importing_failed_debug_info()}\n"
msg += str(traceback.format_exc())
showText(msg)
else:
@@ -421,7 +421,7 @@ def importFile(mw: AnkiQt, file: str) -> None:
def invalidZipMsg() -> str:
- return tr(TR.IMPORTING_THIS_FILE_DOES_NOT_APPEAR_TO)
+ return tr.importing_this_file_does_not_appear_to()
def setupApkgImport(mw: AnkiQt, importer: AnkiPackageImporter) -> bool:
@@ -435,7 +435,7 @@ def setupApkgImport(mw: AnkiQt, importer: AnkiPackageImporter) -> bool:
# adding
return True
if not mw.restoringBackup and not askUser(
- tr(TR.IMPORTING_THIS_WILL_DELETE_YOUR_EXISTING_COLLECTION),
+ tr.importing_this_will_delete_your_existing_collection(),
msgfunc=QMessageBox.warning,
defaultno=True,
):
@@ -494,7 +494,7 @@ def _replaceWithApkg(mw: aqt.AnkiQt, filename: str, backup: bool) -> None:
future.result()
except Exception as e:
print(e)
- showWarning(tr(TR.IMPORTING_THE_PROVIDED_FILE_IS_NOT_A))
+ showWarning(tr.importing_the_provided_file_is_not_a())
return
if not mw.loadCollection():
@@ -502,6 +502,6 @@ def _replaceWithApkg(mw: aqt.AnkiQt, filename: str, backup: bool) -> None:
if backup:
mw.col.modSchema(check=False)
- tooltip(tr(TR.IMPORTING_IMPORTING_COMPLETE))
+ tooltip(tr.importing_importing_complete())
mw.taskman.run_in_background(do_import, on_done)
diff --git a/qt/aqt/main.py b/qt/aqt/main.py
index 944f7f2d8..d993a88db 100644
--- a/qt/aqt/main.py
+++ b/qt/aqt/main.py
@@ -155,7 +155,7 @@ class AnkiQt(QMainWindow):
sys.exit(1)
# must call this after ui set up
if self.safeMode:
- tooltip(tr(TR.QT_MISC_SHIFT_KEY_WAS_HELD_DOWN_SKIPPING))
+ tooltip(tr.qt_misc_shift_key_was_held_down_skipping())
# were we given a file to import?
if args and args[0] and not self._isAddon(args[0]):
self.onAppMsg(args[0])
@@ -282,7 +282,7 @@ class AnkiQt(QMainWindow):
qconnect(f.profiles.currentRowChanged, self.onProfileRowChange)
f.statusbar.setVisible(False)
qconnect(f.downgrade_button.clicked, self._on_downgrade)
- f.downgrade_button.setText(tr(TR.PROFILES_DOWNGRADE_AND_QUIT))
+ f.downgrade_button.setText(tr.profiles_downgrade_and_quit())
# enter key opens profile
QShortcut(QKeySequence("Return"), d, activated=self.onOpenProfile) # type: ignore
self.refreshProfilesList()
@@ -324,10 +324,10 @@ class AnkiQt(QMainWindow):
return not checkInvalidFilename(name) and name != "addons21"
def onAddProfile(self) -> None:
- name = getOnlyText(tr(TR.ACTIONS_NAME)).strip()
+ name = getOnlyText(tr.actions_name()).strip()
if name:
if name in self.pm.profiles():
- showWarning(tr(TR.QT_MISC_NAME_EXISTS))
+ showWarning(tr.qt_misc_name_exists())
return
if not self.profileNameOk(name):
return
@@ -336,13 +336,13 @@ class AnkiQt(QMainWindow):
self.refreshProfilesList()
def onRenameProfile(self) -> None:
- name = getOnlyText(tr(TR.ACTIONS_NEW_NAME), default=self.pm.name).strip()
+ name = getOnlyText(tr.actions_new_name(), default=self.pm.name).strip()
if not name:
return
if name == self.pm.name:
return
if name in self.pm.profiles():
- showWarning(tr(TR.QT_MISC_NAME_EXISTS))
+ showWarning(tr.qt_misc_name_exists())
return
if not self.profileNameOk(name):
return
@@ -352,11 +352,11 @@ class AnkiQt(QMainWindow):
def onRemProfile(self) -> None:
profs = self.pm.profiles()
if len(profs) < 2:
- showWarning(tr(TR.QT_MISC_THERE_MUST_BE_AT_LEAST_ONE))
+ showWarning(tr.qt_misc_there_must_be_at_least_one())
return
# sure?
if not askUser(
- tr(TR.QT_MISC_ALL_CARDS_NOTES_AND_MEDIA_FOR),
+ tr.qt_misc_all_cards_notes_and_media_for(),
msgfunc=QMessageBox.warning,
defaultno=True,
):
@@ -366,7 +366,7 @@ class AnkiQt(QMainWindow):
def onOpenBackup(self) -> None:
if not askUser(
- tr(TR.QT_MISC_REPLACE_YOUR_COLLECTION_WITH_AN_EARLIER),
+ tr.qt_misc_replace_your_collection_with_an_earlier(),
msgfunc=QMessageBox.warning,
defaultno=True,
):
@@ -377,7 +377,7 @@ class AnkiQt(QMainWindow):
getFile(
self.profileDiag,
- tr(TR.QT_MISC_REVERT_TO_BACKUP),
+ tr.qt_misc_revert_to_backup(),
cb=doOpen, # type: ignore
filter="*.colpkg",
dir=self.pm.backupFolder(),
@@ -388,13 +388,13 @@ class AnkiQt(QMainWindow):
# move the existing collection to the trash, as it may not open
self.pm.trashCollection()
except:
- showWarning(tr(TR.QT_MISC_UNABLE_TO_MOVE_EXISTING_FILE_TO))
+ showWarning(tr.qt_misc_unable_to_move_existing_file_to())
return
self.pendingImport = path
self.restoringBackup = True
- showInfo(tr(TR.QT_MISC_AUTOMATIC_SYNCING_AND_BACKUPS_HAVE_BEEN))
+ showInfo(tr.qt_misc_automatic_syncing_and_backups_have_been())
self.onOpenProfile()
@@ -522,7 +522,7 @@ class AnkiQt(QMainWindow):
)
else:
showWarning(
- f"{tr(TR.ERRORS_UNABLE_OPEN_COLLECTION)}\n{traceback.format_exc()}"
+ f"{tr.errors_unable_open_collection()}\n{traceback.format_exc()}"
)
# clean up open collection if possible
try:
@@ -574,9 +574,9 @@ class AnkiQt(QMainWindow):
if not self.col:
return
if self.restoringBackup:
- label = tr(TR.QT_MISC_CLOSING)
+ label = tr.qt_misc_closing()
else:
- label = tr(TR.QT_MISC_BACKING_UP)
+ label = tr.qt_misc_backing_up()
self.progress.start(label=label)
corrupt = False
try:
@@ -594,7 +594,7 @@ class AnkiQt(QMainWindow):
self.col = None
self.progress.finish()
if corrupt:
- showWarning(tr(TR.QT_MISC_YOUR_COLLECTION_FILE_APPEARS_TO_BE))
+ showWarning(tr.qt_misc_your_collection_file_appears_to_be())
if not corrupt and not self.restoringBackup:
self.backup()
@@ -671,7 +671,7 @@ class AnkiQt(QMainWindow):
# have two weeks passed?
if (intTime() - self.pm.profile["lastOptimize"]) < 86400 * 14:
return
- self.progress.start(label=tr(TR.QT_MISC_OPTIMIZING))
+ self.progress.start(label=tr.qt_misc_optimizing())
self.col.optimize()
self.pm.profile["lastOptimize"] = intTime()
self.pm.save()
@@ -702,7 +702,7 @@ class AnkiQt(QMainWindow):
def _selectedDeck(self) -> Optional[DeckDict]:
did = self.col.decks.selected()
if not self.col.decks.name_if_exists(did):
- showInfo(tr(TR.QT_MISC_PLEASE_SELECT_A_DECK))
+ showInfo(tr.qt_misc_please_select_a_deck())
return None
return self.col.decks.get(did)
@@ -1222,7 +1222,7 @@ title="%s" %s>%s""" % (
return
elif isinstance(result, ReviewUndo):
- name = tr(TR.SCHEDULING_REVIEW)
+ name = tr.scheduling_review()
if reviewing:
# push the undone card to the top of the queue
@@ -1279,7 +1279,7 @@ title="%s" %s>%s""" % (
self.form.actionUndo.setEnabled(True)
gui_hooks.undo_state_did_change(True)
else:
- self.form.actionUndo.setText(tr(TR.UNDO_UNDO))
+ self.form.actionUndo.setText(tr.undo_undo())
self.form.actionUndo.setEnabled(False)
gui_hooks.undo_state_did_change(False)
@@ -1294,7 +1294,7 @@ title="%s" %s>%s""" % (
self.form.actionUndo.setEnabled(True)
gui_hooks.undo_state_did_change(True)
else:
- self.form.actionUndo.setText(tr(TR.UNDO_UNDO))
+ self.form.actionUndo.setText(tr.undo_undo())
self.form.actionUndo.setEnabled(False)
gui_hooks.undo_state_did_change(False)
@@ -1371,7 +1371,7 @@ title="%s" %s>%s""" % (
import aqt.importing
if not os.path.exists(path):
- showInfo(tr(TR.QT_MISC_PLEASE_USE_FILEIMPORT_TO_IMPORT_THIS))
+ showInfo(tr.qt_misc_please_use_fileimport_to_import_this())
return None
aqt.importing.importFile(self, path)
@@ -1508,7 +1508,7 @@ title="%s" %s>%s""" % (
self._activeWindowOnPlay: Optional[QWidget] = None
def onOdueInvalid(self) -> None:
- showWarning(tr(TR.QT_MISC_INVALID_PROPERTY_FOUND_ON_CARD_PLEASE))
+ showWarning(tr.qt_misc_invalid_property_found_on_card_please())
def _isVideo(self, tag: AVTag) -> bool:
if isinstance(tag, SoundOrVideoTag):
@@ -1557,7 +1557,7 @@ title="%s" %s>%s""" % (
progress_shown = self.progress.busy()
if progress_shown:
self.progress.finish()
- ret = askUser(tr(TR.QT_MISC_THE_REQUESTED_CHANGE_WILL_REQUIRE_A))
+ ret = askUser(tr.qt_misc_the_requested_change_will_require_a())
if progress_shown:
self.progress.start()
return ret
@@ -1568,7 +1568,7 @@ title="%s" %s>%s""" % (
True if confirmed or already modified."""
if self.col.schemaChanged():
return True
- return askUser(tr(TR.QT_MISC_THE_REQUESTED_CHANGE_WILL_REQUIRE_A))
+ return askUser(tr.qt_misc_the_requested_change_will_require_a())
# Advanced features
##########################################################################
@@ -1739,7 +1739,7 @@ title="%s" %s>%s""" % (
)
frm.log.appendPlainText(to_append)
except UnicodeDecodeError:
- to_append = tr(TR.QT_MISC_NON_UNICODE_TEXT)
+ to_append = tr.qt_misc_non_unicode_text()
to_append = gui_hooks.debug_console_did_evaluate_python(
to_append, text, frm
)
@@ -1804,16 +1804,16 @@ title="%s" %s>%s""" % (
return None
self.pendingImport = buf
if is_addon:
- msg = tr(TR.QT_MISC_ADDON_WILL_BE_INSTALLED_WHEN_A)
+ msg = tr.qt_misc_addon_will_be_installed_when_a()
else:
- msg = tr(TR.QT_MISC_DECK_WILL_BE_IMPORTED_WHEN_A)
+ msg = tr.qt_misc_deck_will_be_imported_when_a()
tooltip(msg)
return
if not self.interactiveState() or self.progress.busy():
# we can't raise the main window while in profile dialog, syncing, etc
if buf != "raise":
showInfo(
- tr(TR.QT_MISC_PLEASE_ENSURE_A_PROFILE_IS_OPEN),
+ tr.qt_misc_please_ensure_a_profile_is_open(),
parent=None,
)
return None
diff --git a/qt/aqt/mediacheck.py b/qt/aqt/mediacheck.py
index 017eb2eab..7e4ffcf31 100644
--- a/qt/aqt/mediacheck.py
+++ b/qt/aqt/mediacheck.py
@@ -99,7 +99,7 @@ class MediaChecker:
# show report and offer to delete
diag = QDialog(self.mw)
- diag.setWindowTitle(tr(TR.MEDIA_CHECK_WINDOW_TITLE))
+ diag.setWindowTitle(tr.media_check_window_title())
disable_help_button(diag)
layout = QVBoxLayout(diag)
diag.setLayout(layout)
@@ -112,25 +112,25 @@ class MediaChecker:
layout.addWidget(box)
if output.unused:
- b = QPushButton(tr(TR.MEDIA_CHECK_DELETE_UNUSED))
+ b = QPushButton(tr.media_check_delete_unused())
b.setAutoDefault(False)
box.addButton(b, QDialogButtonBox.RejectRole)
qconnect(b.clicked, lambda c: self._on_trash_files(output.unused))
if output.missing:
if any(map(lambda x: x.startswith("latex-"), output.missing)):
- b = QPushButton(tr(TR.MEDIA_CHECK_RENDER_LATEX))
+ b = QPushButton(tr.media_check_render_latex())
b.setAutoDefault(False)
box.addButton(b, QDialogButtonBox.RejectRole)
qconnect(b.clicked, self._on_render_latex)
if output.have_trash:
- b = QPushButton(tr(TR.MEDIA_CHECK_EMPTY_TRASH))
+ b = QPushButton(tr.media_check_empty_trash())
b.setAutoDefault(False)
box.addButton(b, QDialogButtonBox.RejectRole)
qconnect(b.clicked, lambda c: self._on_empty_trash())
- b = QPushButton(tr(TR.MEDIA_CHECK_RESTORE_TRASH))
+ b = QPushButton(tr.media_check_restore_trash())
b.setAutoDefault(False)
box.addButton(b, QDialogButtonBox.RejectRole)
qconnect(b.clicked, lambda c: self._on_restore_trash())
@@ -157,7 +157,7 @@ class MediaChecker:
aqt.dialogs.open("Browser", self.mw, search=(SearchNode(nid=nid),))
showText(err, type="html")
else:
- tooltip(tr(TR.MEDIA_CHECK_ALL_LATEX_RENDERED))
+ tooltip(tr.media_check_all_latex_rendered())
def _on_render_latex_progress(self, count: int) -> bool:
if self.progress_dialog.wantCancel:
@@ -167,7 +167,7 @@ class MediaChecker:
return True
def _on_trash_files(self, fnames: Sequence[str]) -> None:
- if not askUser(tr(TR.MEDIA_CHECK_DELETE_UNUSED_CONFIRM)):
+ if not askUser(tr.media_check_delete_unused_confirm()):
return
self.progress_dialog = self.mw.progress.start()
@@ -202,7 +202,7 @@ class MediaChecker:
# check for errors
fut.result()
- tooltip(tr(TR.MEDIA_CHECK_TRASH_EMPTIED))
+ tooltip(tr.media_check_trash_emptied())
self.mw.taskman.run_in_background(empty_trash, on_done)
@@ -219,6 +219,6 @@ class MediaChecker:
# check for errors
fut.result()
- tooltip(tr(TR.MEDIA_CHECK_TRASH_RESTORED))
+ tooltip(tr.media_check_trash_restored())
self.mw.taskman.run_in_background(restore_trash, on_done)
diff --git a/qt/aqt/mediasync.py b/qt/aqt/mediasync.py
index ef573561d..72457be06 100644
--- a/qt/aqt/mediasync.py
+++ b/qt/aqt/mediasync.py
@@ -11,7 +11,6 @@ from typing import Any, Callable, List, Optional, Union
import aqt
from anki.collection import Progress
from anki.errors import Interrupted, NetworkError
-from anki.lang import TR
from anki.types import assert_exhaustive
from anki.utils import intTime
from aqt import gui_hooks
@@ -48,14 +47,14 @@ class MediaSyncer:
return
if not self.mw.pm.media_syncing_enabled():
- self._log_and_notify(tr(TR.SYNC_MEDIA_DISABLED))
+ self._log_and_notify(tr.sync_media_disabled())
return
auth = self.mw.pm.sync_auth()
if auth is None:
return
- self._log_and_notify(tr(TR.SYNC_MEDIA_STARTING))
+ self._log_and_notify(tr.sync_media_starting())
self._syncing = True
self._progress_timer = self.mw.progress.timer(
1000, self._on_progress, True, True
@@ -85,18 +84,18 @@ class MediaSyncer:
if exc is not None:
self._handle_sync_error(exc)
else:
- self._log_and_notify(tr(TR.SYNC_MEDIA_COMPLETE))
+ self._log_and_notify(tr.sync_media_complete())
def _handle_sync_error(self, exc: BaseException) -> None:
if isinstance(exc, Interrupted):
- self._log_and_notify(tr(TR.SYNC_MEDIA_ABORTED))
+ self._log_and_notify(tr.sync_media_aborted())
return
elif isinstance(exc, NetworkError):
# avoid popups for network errors
self._log_and_notify(str(exc))
return
- self._log_and_notify(tr(TR.SYNC_MEDIA_FAILED))
+ self._log_and_notify(tr.sync_media_failed())
showWarning(str(exc))
def entries(self) -> List[LogEntryWithTime]:
@@ -105,7 +104,7 @@ class MediaSyncer:
def abort(self) -> None:
if not self.is_syncing():
return
- self._log_and_notify(tr(TR.SYNC_MEDIA_ABORTING))
+ self._log_and_notify(tr.sync_media_aborting())
self.mw.col.set_wants_abort()
self.mw.col.abort_media_sync()
@@ -158,9 +157,9 @@ class MediaSyncDialog(QDialog):
self._close_when_done = close_when_done
self.form = aqt.forms.synclog.Ui_Dialog()
self.form.setupUi(self)
- self.setWindowTitle(tr(TR.SYNC_MEDIA_LOG_TITLE))
+ self.setWindowTitle(tr.sync_media_log_title())
disable_help_button(self)
- self.abort_button = QPushButton(tr(TR.SYNC_ABORT_BUTTON))
+ self.abort_button = QPushButton(tr.sync_abort_button())
qconnect(self.abort_button.clicked, self._on_abort)
self.abort_button.setAutoDefault(False)
self.form.buttonBox.addButton(self.abort_button, QDialogButtonBox.ActionRole)
diff --git a/qt/aqt/modelchooser.py b/qt/aqt/modelchooser.py
index 0ffe9b34f..4e2d838f1 100644
--- a/qt/aqt/modelchooser.py
+++ b/qt/aqt/modelchooser.py
@@ -4,7 +4,7 @@ from typing import List, Optional
from aqt import AnkiQt, gui_hooks
from aqt.qt import *
-from aqt.utils import TR, HelpPage, shortcut, tr
+from aqt.utils import HelpPage, shortcut, tr
class ModelChooser(QHBoxLayout):
@@ -37,11 +37,11 @@ class ModelChooser(QHBoxLayout):
def setupModels(self) -> None:
if self.label:
- self.modelLabel = QLabel(tr(TR.NOTETYPES_TYPE))
+ self.modelLabel = QLabel(tr.notetypes_type())
self.addWidget(self.modelLabel)
# models box
self.models = QPushButton()
- self.models.setToolTip(shortcut(tr(TR.QT_MISC_CHANGE_NOTE_TYPE_CTRLANDN)))
+ self.models.setToolTip(shortcut(tr.qt_misc_change_note_type_ctrlandn()))
QShortcut(QKeySequence("Ctrl+N"), self._widget, activated=self.on_activated) # type: ignore
self.models.setAutoDefault(False)
self.addWidget(self.models)
@@ -73,7 +73,7 @@ class ModelChooser(QHBoxLayout):
current = self.deck.models.current()["name"]
# edit button
- edit = QPushButton(tr(TR.QT_MISC_MANAGE), clicked=self.onEdit) # type: ignore
+ edit = QPushButton(tr.qt_misc_manage(), clicked=self.onEdit) # type: ignore
def nameFunc() -> List[str]:
return sorted(self.deck.models.allNames())
@@ -81,8 +81,8 @@ class ModelChooser(QHBoxLayout):
ret = StudyDeck(
self.mw,
names=nameFunc,
- accept=tr(TR.ACTIONS_CHOOSE),
- title=tr(TR.QT_MISC_CHOOSE_NOTE_TYPE),
+ accept=tr.actions_choose(),
+ title=tr.qt_misc_choose_note_type(),
help=HelpPage.NOTE_TYPE,
current=current,
parent=self._widget,
diff --git a/qt/aqt/models.py b/qt/aqt/models.py
index 84fcf197a..20711e5f8 100644
--- a/qt/aqt/models.py
+++ b/qt/aqt/models.py
@@ -43,7 +43,7 @@ class Models(QDialog):
self.col = mw.col.weakref()
assert self.col
self.mm = self.col.models
- self.mw.checkpoint(tr(TR.NOTETYPES_NOTE_TYPES))
+ self.mw.checkpoint(tr.notetypes_note_types())
self.form = aqt.forms.models.Ui_Dialog()
self.form.setupUi(self)
qconnect(
@@ -73,20 +73,20 @@ class Models(QDialog):
box = f.buttonBox
default_buttons = [
- (tr(TR.ACTIONS_ADD), self.onAdd),
- (tr(TR.ACTIONS_RENAME), self.onRename),
- (tr(TR.ACTIONS_DELETE), self.onDelete),
+ (tr.actions_add(), self.onAdd),
+ (tr.actions_rename(), self.onRename),
+ (tr.actions_delete(), self.onDelete),
]
if self.fromMain:
default_buttons.extend(
[
- (tr(TR.NOTETYPES_FIELDS), self.onFields),
- (tr(TR.NOTETYPES_CARDS), self.onCards),
+ (tr.notetypes_fields(), self.onFields),
+ (tr.notetypes_cards(), self.onCards),
]
)
- default_buttons.append((tr(TR.NOTETYPES_OPTIONS), self.onAdvanced))
+ default_buttons.append((tr.notetypes_options(), self.onAdvanced))
for label, func in gui_hooks.models_did_init_buttons(default_buttons, self):
button = box.addButton(label, QDialogButtonBox.ActionRole)
@@ -103,7 +103,7 @@ class Models(QDialog):
def onRename(self) -> None:
nt = self.current_notetype()
- txt = getText(tr(TR.ACTIONS_NEW_NAME), default=nt["name"])
+ txt = getText(tr.actions_new_name(), default=nt["name"])
name = txt[0].replace('"', "")
if txt[1] and name:
nt["name"] = name
@@ -139,20 +139,20 @@ class Models(QDialog):
def onAdd(self) -> None:
m = AddModel(self.mw, self).get()
if m:
- txt = getText(tr(TR.ACTIONS_NAME), default=m["name"])[0].replace('"', "")
+ txt = getText(tr.actions_name(), default=m["name"])[0].replace('"', "")
if txt:
m["name"] = txt
self.saveAndRefresh(m)
def onDelete(self) -> None:
if len(self.models) < 2:
- showInfo(tr(TR.NOTETYPES_PLEASE_ADD_ANOTHER_NOTE_TYPE_FIRST), parent=self)
+ showInfo(tr.notetypes_please_add_another_note_type_first(), parent=self)
return
idx = self.form.modelsList.currentRow()
if self.models[idx].use_count:
- msg = tr(TR.NOTETYPES_DELETE_THIS_NOTE_TYPE_AND_ALL)
+ msg = tr.notetypes_delete_this_note_type_and_all()
else:
- msg = tr(TR.NOTETYPES_DELETE_THIS_UNUSED_NOTE_TYPE)
+ msg = tr.notetypes_delete_this_unused_note_type()
if not askUser(msg, parent=self):
return
diff --git a/qt/aqt/notetypechooser.py b/qt/aqt/notetypechooser.py
index 96205f36c..77605f67d 100644
--- a/qt/aqt/notetypechooser.py
+++ b/qt/aqt/notetypechooser.py
@@ -5,7 +5,7 @@ from typing import List, Optional
from anki.models import NoteTypeID
from aqt import AnkiQt, gui_hooks
from aqt.qt import *
-from aqt.utils import TR, HelpPage, shortcut, tr
+from aqt.utils import HelpPage, shortcut, tr
class NoteTypeChooser(QHBoxLayout):
@@ -55,12 +55,12 @@ class NoteTypeChooser(QHBoxLayout):
self.setSpacing(8)
if show_label:
- self.label = QLabel(tr(TR.NOTETYPES_TYPE))
+ self.label = QLabel(tr.notetypes_type())
self.addWidget(self.label)
# button
self.button = QPushButton()
- self.button.setToolTip(shortcut(tr(TR.QT_MISC_CHANGE_NOTE_TYPE_CTRLANDN)))
+ self.button.setToolTip(shortcut(tr.qt_misc_change_note_type_ctrlandn()))
qconnect(
QShortcut(QKeySequence("Ctrl+N"), self._widget).activated,
self.on_button_activated,
@@ -95,7 +95,7 @@ class NoteTypeChooser(QHBoxLayout):
current = self.selected_notetype_name()
# edit button
- edit = QPushButton(tr(TR.QT_MISC_MANAGE))
+ edit = QPushButton(tr.qt_misc_manage())
qconnect(edit.clicked, self.onEdit)
def nameFunc() -> List[str]:
@@ -104,8 +104,8 @@ class NoteTypeChooser(QHBoxLayout):
ret = StudyDeck(
self.mw,
names=nameFunc,
- accept=tr(TR.ACTIONS_CHOOSE),
- title=tr(TR.QT_MISC_CHOOSE_NOTE_TYPE),
+ accept=tr.actions_choose(),
+ title=tr.qt_misc_choose_note_type(),
help=HelpPage.NOTE_TYPE,
current=current,
parent=self._widget,
diff --git a/qt/aqt/overview.py b/qt/aqt/overview.py
index 04a7e081c..db79db38e 100644
--- a/qt/aqt/overview.py
+++ b/qt/aqt/overview.py
@@ -81,7 +81,7 @@ class Overview:
self.mw.col.startTimebox()
self.mw.moveToState("review")
if self.mw.state == "overview":
- tooltip(tr(TR.STUDYING_NO_CARDS_ARE_DUE_YET))
+ tooltip(tr.studying_no_cards_are_due_yet())
elif url == "anki":
print("anki menu")
elif url == "opts":
@@ -137,13 +137,13 @@ class Overview:
info = self.mw.col.sched.congratulations_info()
if info.have_sched_buried and info.have_user_buried:
opts = [
- tr(TR.STUDYING_MANUALLY_BURIED_CARDS),
- tr(TR.STUDYING_BURIED_SIBLINGS),
- tr(TR.STUDYING_ALL_BURIED_CARDS),
- tr(TR.ACTIONS_CANCEL),
+ tr.studying_manually_buried_cards(),
+ tr.studying_buried_siblings(),
+ tr.studying_all_buried_cards(),
+ tr.actions_cancel(),
]
- diag = askUserDialog(tr(TR.STUDYING_WHAT_WOULD_YOU_LIKE_TO_UNBURY), opts)
+ diag = askUserDialog(tr.studying_what_would_you_like_to_unbury(), opts)
diag.setDefault(0)
ret = diag.run()
if ret == opts[0]:
@@ -192,9 +192,9 @@ class Overview:
def _desc(self, deck: Dict[str, Any]) -> str:
if deck["dyn"]:
- desc = tr(TR.STUDYING_THIS_IS_A_SPECIAL_DECK_FOR)
- desc += f" {tr(TR.STUDYING_CARDS_WILL_BE_AUTOMATICALLY_RETURNED_TO)}"
- desc += f" {tr(TR.STUDYING_DELETING_THIS_DECK_FROM_THE_DECK)}"
+ desc = tr.studying_this_is_a_special_deck_for()
+ desc += f" {tr.studying_cards_will_be_automatically_returned_to()}"
+ desc += f" {tr.studying_deleting_this_deck_from_the_deck()}"
else:
desc = deck.get("desc", "")
if deck.get("md", False):
@@ -220,13 +220,13 @@ class Overview:
%s | """ % (
- tr(TR.ACTIONS_NEW),
+ tr.actions_new(),
counts[0],
- tr(TR.SCHEDULING_LEARNING),
+ tr.scheduling_learning(),
counts[1],
- tr(TR.STUDYING_TO_REVIEW),
+ tr.studying_to_review(),
counts[2],
- but("study", tr(TR.STUDYING_STUDY_NOW), id="study", extra=" autofocus"),
+ but("study", tr.studying_study_now(), id="study", extra=" autofocus"),
)
_body = """
@@ -243,16 +243,16 @@ class Overview:
def _renderBottom(self) -> None:
links = [
- ["O", "opts", tr(TR.ACTIONS_OPTIONS)],
+ ["O", "opts", tr.actions_options()],
]
if self.mw.col.decks.current()["dyn"]:
- links.append(["R", "refresh", tr(TR.ACTIONS_REBUILD)])
- links.append(["E", "empty", tr(TR.STUDYING_EMPTY)])
+ links.append(["R", "refresh", tr.actions_rebuild()])
+ links.append(["E", "empty", tr.studying_empty()])
else:
- links.append(["C", "studymore", tr(TR.ACTIONS_CUSTOM_STUDY)])
+ links.append(["C", "studymore", tr.actions_custom_study()])
# links.append(["F", "cram", _("Filter/Cram")])
if self.mw.col.sched.haveBuried():
- links.append(["U", "unbury", tr(TR.STUDYING_UNBURY)])
+ links.append(["U", "unbury", tr.studying_unbury()])
buf = ""
for b in links:
if b[0]:
diff --git a/qt/aqt/preferences.py b/qt/aqt/preferences.py
index 64fe935e9..99ed7777a 100644
--- a/qt/aqt/preferences.py
+++ b/qt/aqt/preferences.py
@@ -162,7 +162,7 @@ for you than the default driver, please let us know on the Anki forums."""
######################################################################
def setup_network(self) -> None:
- self.form.media_log.setText(tr(TR.SYNC_MEDIA_LOG_BUTTON))
+ self.form.media_log.setText(tr.sync_media_log_button())
qconnect(self.form.media_log.clicked, self.on_media_log)
self.form.syncOnProgramOpen.setChecked(self.prof["autoSync"])
self.form.syncMedia.setChecked(self.prof["syncMedia"])
@@ -172,7 +172,7 @@ for you than the default driver, please let us know on the Anki forums."""
else:
self.form.syncUser.setText(self.prof.get("syncUser", ""))
qconnect(self.form.syncDeauth.clicked, self.sync_logout)
- self.form.syncDeauth.setText(tr(TR.SYNC_LOG_OUT_BUTTON))
+ self.form.syncDeauth.setText(tr.sync_log_out_button())
def on_media_log(self) -> None:
self.mw.media_syncer.show_sync_log()
@@ -181,7 +181,7 @@ for you than the default driver, please let us know on the Anki forums."""
self.form.syncDeauth.setVisible(False)
self.form.syncUser.setText("")
self.form.syncLabel.setText(
- tr(TR.PREFERENCES_SYNCHRONIZATIONNOT_CURRENTLY_ENABLED_CLICK_THE_SYNC)
+ tr.preferences_synchronizationnot_currently_enabled_click_the_sync()
)
def sync_logout(self) -> None:
@@ -238,7 +238,7 @@ for you than the default driver, please let us know on the Anki forums."""
restart_required = True
if restart_required:
- showInfo(tr(TR.PREFERENCES_CHANGES_WILL_TAKE_EFFECT_WHEN_YOU))
+ showInfo(tr.preferences_changes_will_take_effect_when_you())
self.updateOptions()
@@ -274,9 +274,7 @@ for you than the default driver, please let us know on the Anki forums."""
def on_language_index_changed(self, idx: int) -> None:
code = anki.lang.langs[idx][1]
self.mw.pm.setLang(code)
- showInfo(
- tr(TR.PREFERENCES_PLEASE_RESTART_ANKI_TO_COMPLETE_LANGUAGE), parent=self
- )
+ showInfo(tr.preferences_please_restart_anki_to_complete_language(), parent=self)
# Global: video driver
######################################################################
@@ -296,19 +294,19 @@ for you than the default driver, please let us know on the Anki forums."""
new_driver = self.video_drivers[self.form.video_driver.currentIndex()]
if new_driver != self.mw.pm.video_driver():
self.mw.pm.set_video_driver(new_driver)
- showInfo(tr(TR.PREFERENCES_CHANGES_WILL_TAKE_EFFECT_WHEN_YOU))
+ showInfo(tr.preferences_changes_will_take_effect_when_you())
def video_driver_name_for_platform(driver: VideoDriver) -> str:
if driver == VideoDriver.ANGLE:
- return tr(TR.PREFERENCES_VIDEO_DRIVER_ANGLE)
+ return tr.preferences_video_driver_angle()
elif driver == VideoDriver.Software:
if isMac:
- return tr(TR.PREFERENCES_VIDEO_DRIVER_SOFTWARE_MAC)
+ return tr.preferences_video_driver_software_mac()
else:
- return tr(TR.PREFERENCES_VIDEO_DRIVER_SOFTWARE_OTHER)
+ return tr.preferences_video_driver_software_other()
else:
if isMac:
- return tr(TR.PREFERENCES_VIDEO_DRIVER_OPENGL_MAC)
+ return tr.preferences_video_driver_opengl_mac()
else:
- return tr(TR.PREFERENCES_VIDEO_DRIVER_OPENGL_OTHER)
+ return tr.preferences_video_driver_opengl_other()
diff --git a/qt/aqt/previewer.py b/qt/aqt/previewer.py
index 9cfaed271..606cd52cd 100644
--- a/qt/aqt/previewer.py
+++ b/qt/aqt/previewer.py
@@ -71,7 +71,7 @@ class Previewer(QDialog):
self.show()
def _create_gui(self) -> None:
- self.setWindowTitle(tr(TR.ACTIONS_PREVIEW))
+ self.setWindowTitle(tr.actions_preview())
self.close_shortcut = QShortcut(QKeySequence("Ctrl+Shift+P"), self)
qconnect(self.close_shortcut.activated, self.close)
@@ -85,14 +85,14 @@ class Previewer(QDialog):
self.bbox = QDialogButtonBox()
self._replay = self.bbox.addButton(
- tr(TR.ACTIONS_REPLAY_AUDIO), QDialogButtonBox.ActionRole
+ tr.actions_replay_audio(), QDialogButtonBox.ActionRole
)
self._replay.setAutoDefault(False)
self._replay.setShortcut(QKeySequence("R"))
self._replay.setToolTip(tr(TR.ACTIONS_SHORTCUT_KEY, val="R"))
qconnect(self._replay.clicked, self._on_replay_audio)
- both_sides_button = QCheckBox(tr(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.setToolTip(tr(TR.ACTIONS_SHORTCUT_KEY, val="B"))
self.bbox.addButton(both_sides_button, QDialogButtonBox.ActionRole)
@@ -173,7 +173,7 @@ class Previewer(QDialog):
c = self.card()
func = "_showQuestion"
if not c:
- txt = tr(TR.QT_MISC_PLEASE_SELECT_1_CARD)
+ txt = tr.qt_misc_please_select_1_card()
bodyclass = ""
self._last_state = None
else:
@@ -253,12 +253,12 @@ class MultiCardPreviewer(Previewer):
self._prev = self.bbox.addButton("<", QDialogButtonBox.ActionRole)
self._prev.setAutoDefault(False)
self._prev.setShortcut(QKeySequence("Left"))
- self._prev.setToolTip(tr(TR.QT_MISC_SHORTCUT_KEY_LEFT_ARROW))
+ self._prev.setToolTip(tr.qt_misc_shortcut_key_left_arrow())
self._next = self.bbox.addButton(">", QDialogButtonBox.ActionRole)
self._next.setAutoDefault(True)
self._next.setShortcut(QKeySequence("Right"))
- self._next.setToolTip(tr(TR.QT_MISC_SHORTCUT_KEY_RIGHT_ARROW_OR_ENTER))
+ self._next.setToolTip(tr.qt_misc_shortcut_key_right_arrow_or_enter())
qconnect(self._prev.clicked, self._on_prev)
qconnect(self._next.clicked, self._on_next)
diff --git a/qt/aqt/profiles.py b/qt/aqt/profiles.py
index ea516becb..02ab81c6a 100644
--- a/qt/aqt/profiles.py
+++ b/qt/aqt/profiles.py
@@ -138,7 +138,7 @@ class ProfileManager:
if profile:
if profile not in self.profiles():
QMessageBox.critical(
- None, tr(TR.QT_MISC_ERROR), tr(TR.PROFILES_PROFILE_DOES_NOT_EXIST)
+ None, tr.qt_misc_error(), tr.profiles_profile_does_not_exist()
)
sys.exit(1)
try:
@@ -299,8 +299,8 @@ class ProfileManager:
except:
QMessageBox.warning(
None,
- tr(TR.PROFILES_PROFILE_CORRUPT),
- tr(TR.PROFILES_ANKI_COULD_NOT_READ_YOUR_PROFILE),
+ tr.profiles_profile_corrupt(),
+ tr.profiles_anki_could_not_read_your_profile(),
)
traceback.print_stack()
print("resetting corrupt profile")
@@ -353,7 +353,7 @@ class ProfileManager:
self.name = oldName
return
else:
- showWarning(tr(TR.PROFILES_FOLDER_ALREADY_EXISTS))
+ showWarning(tr.profiles_folder_already_exists())
self.name = oldName
return
@@ -365,7 +365,7 @@ class ProfileManager:
except Exception as e:
self.db.rollback()
if "WinError 5" in str(e):
- showWarning(tr(TR.PROFILES_ANKI_COULD_NOT_RENAME_YOUR_PROFILE))
+ showWarning(tr.profiles_anki_could_not_rename_your_profile())
else:
raise
except:
@@ -513,7 +513,7 @@ create table if not exists profiles
def _ensureProfile(self) -> None:
"Create a new profile if none exists."
- self.create(tr(TR.PROFILES_USER_1))
+ self.create(tr.profiles_user_1())
p = os.path.join(self.base, "README.txt")
with open(p, "w", encoding="utf8") as file:
file.write(
diff --git a/qt/aqt/progress.py b/qt/aqt/progress.py
index 9f52e26b2..1e11d10f3 100644
--- a/qt/aqt/progress.py
+++ b/qt/aqt/progress.py
@@ -7,7 +7,7 @@ from typing import Callable, Optional
import aqt.forms
from aqt.qt import *
-from aqt.utils import TR, disable_help_button, tr
+from aqt.utils import disable_help_button, tr
# Progress info
##########################################################################
@@ -86,7 +86,7 @@ class ProgressManager:
if not parent and self.mw.isVisible():
parent = self.mw
- label = label or tr(TR.QT_MISC_PROCESSING)
+ label = label or tr.qt_misc_processing()
self._win = ProgressDialog(parent)
self._win.form.progressBar.setMinimum(min)
self._win.form.progressBar.setMaximum(max)
diff --git a/qt/aqt/reviewer.py b/qt/aqt/reviewer.py
index 9fa4fb79d..f3cffdb4b 100644
--- a/qt/aqt/reviewer.py
+++ b/qt/aqt/reviewer.py
@@ -150,8 +150,8 @@ class Reviewer:
part1 = tr(TR.STUDYING_CARD_STUDIED_IN, count=elapsed[1])
mins = int(round(elapsed[0] / 60))
part2 = tr(TR.STUDYING_MINUTE, count=mins)
- fin = tr(TR.STUDYING_FINISH)
- diag = askUserDialog(f"{part1} {part2}", [tr(TR.STUDYING_CONTINUE), fin])
+ fin = tr.studying_finish()
+ diag = askUserDialog(f"{part1} {part2}", [tr.studying_continue(), fin])
diag.setIcon(QMessageBox.Information)
if diag.run() == fin:
return self.mw.moveToState("deckBrowser")
@@ -443,7 +443,7 @@ class Reviewer:
if not self.typeCorrect:
if self.typeCorrect is None:
if clozeIdx:
- warn = tr(TR.STUDYING_PLEASE_RUN_TOOLSEMPTY_CARDS)
+ warn = tr.studying_please_run_toolsempty_cards()
else:
warn = tr(TR.STUDYING_TYPE_ANSWER_UNKNOWN_FIELD, val=fld)
return re.sub(self.typeAnsPat, warn, buf)
@@ -625,9 +625,9 @@ time = %(time)d;
""" % dict(
rem=self._remaining(),
- edit=tr(TR.STUDYING_EDIT),
+ edit=tr.studying_edit(),
editkey=tr(TR.ACTIONS_SHORTCUT_KEY, val="E"),
- more=tr(TR.STUDYING_MORE),
+ more=tr.studying_more(),
downArrow=downArrow(),
time=self.card.timeTaken() // 1000,
)
@@ -637,8 +637,8 @@ time = %(time)d;
%s
""" % (
self._remaining(),
- tr(TR.ACTIONS_SHORTCUT_KEY, val=tr(TR.STUDYING_SPACE)),
- tr(TR.STUDYING_SHOW_ANSWER),
+ tr(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
middle = (
@@ -682,21 +682,21 @@ time = %(time)d;
button_count = self.mw.col.sched.answerButtons(self.card)
if button_count == 2:
buttons_tuple: Tuple[Tuple[int, str], ...] = (
- (1, tr(TR.STUDYING_AGAIN)),
- (2, tr(TR.STUDYING_GOOD)),
+ (1, tr.studying_again()),
+ (2, tr.studying_good()),
)
elif button_count == 3:
buttons_tuple = (
- (1, tr(TR.STUDYING_AGAIN)),
- (2, tr(TR.STUDYING_GOOD)),
- (3, tr(TR.STUDYING_EASY)),
+ (1, tr.studying_again()),
+ (2, tr.studying_good()),
+ (3, tr.studying_easy()),
)
else:
buttons_tuple = (
- (1, tr(TR.STUDYING_AGAIN)),
- (2, tr(TR.STUDYING_HARD)),
- (3, tr(TR.STUDYING_GOOD)),
- (4, tr(TR.STUDYING_EASY)),
+ (1, tr.studying_again()),
+ (2, tr.studying_hard()),
+ (3, tr.studying_good()),
+ (4, tr.studying_easy()),
)
buttons_tuple = gui_hooks.reviewer_will_init_answer_buttons(
buttons_tuple, self, self.card
@@ -742,9 +742,9 @@ time = %(time)d;
def onLeech(self, card: Card) -> None:
# for now
- s = tr(TR.STUDYING_CARD_WAS_A_LEECH)
+ s = tr.studying_card_was_a_leech()
if card.queue < 0:
- s += f" {tr(TR.STUDYING_IT_HAS_BEEN_SUSPENDED)}"
+ s += f" {tr.studying_it_has_been_suspended()}"
tooltip(s)
# Context menu
@@ -755,49 +755,49 @@ time = %(time)d;
currentFlag = self.card and self.card.user_flag()
opts = [
[
- tr(TR.STUDYING_FLAG_CARD),
+ tr.studying_flag_card(),
[
[
- tr(TR.ACTIONS_RED_FLAG),
+ tr.actions_red_flag(),
"Ctrl+1",
lambda: self.set_flag_on_current_card(1),
dict(checked=currentFlag == 1),
],
[
- tr(TR.ACTIONS_ORANGE_FLAG),
+ tr.actions_orange_flag(),
"Ctrl+2",
lambda: self.set_flag_on_current_card(2),
dict(checked=currentFlag == 2),
],
[
- tr(TR.ACTIONS_GREEN_FLAG),
+ tr.actions_green_flag(),
"Ctrl+3",
lambda: self.set_flag_on_current_card(3),
dict(checked=currentFlag == 3),
],
[
- tr(TR.ACTIONS_BLUE_FLAG),
+ tr.actions_blue_flag(),
"Ctrl+4",
lambda: self.set_flag_on_current_card(4),
dict(checked=currentFlag == 4),
],
],
],
- [tr(TR.STUDYING_MARK_NOTE), "*", self.toggle_mark_on_current_note],
- [tr(TR.STUDYING_BURY_CARD), "-", self.bury_current_card],
- [tr(TR.STUDYING_BURY_NOTE), "=", self.bury_current_note],
- [tr(TR.ACTIONS_SET_DUE_DATE), "Ctrl+Shift+D", self.on_set_due],
- [tr(TR.ACTIONS_SUSPEND_CARD), "@", self.suspend_current_card],
- [tr(TR.STUDYING_SUSPEND_NOTE), "!", self.suspend_current_note],
- [tr(TR.STUDYING_DELETE_NOTE), "Ctrl+Delete", self.delete_current_note],
- [tr(TR.ACTIONS_OPTIONS), "O", self.onOptions],
+ [tr.studying_mark_note(), "*", self.toggle_mark_on_current_note],
+ [tr.studying_bury_card(), "-", self.bury_current_card],
+ [tr.studying_bury_note(), "=", self.bury_current_note],
+ [tr.actions_set_due_date(), "Ctrl+Shift+D", self.on_set_due],
+ [tr.actions_suspend_card(), "@", self.suspend_current_card],
+ [tr.studying_suspend_note(), "!", self.suspend_current_note],
+ [tr.studying_delete_note(), "Ctrl+Delete", self.delete_current_note],
+ [tr.actions_options(), "O", self.onOptions],
None,
- [tr(TR.ACTIONS_REPLAY_AUDIO), "R", self.replayAudio],
- [tr(TR.STUDYING_PAUSE_AUDIO), "5", self.on_pause_audio],
- [tr(TR.STUDYING_AUDIO_5S), "6", self.on_seek_backward],
- [tr(TR.STUDYING_AUDIO_AND5S), "7", self.on_seek_forward],
- [tr(TR.STUDYING_RECORD_OWN_VOICE), "Shift+V", self.onRecordVoice],
- [tr(TR.STUDYING_REPLAY_OWN_VOICE), "V", self.onReplayRecorded],
+ [tr.actions_replay_audio(), "R", self.replayAudio],
+ [tr.studying_pause_audio(), "5", self.on_pause_audio],
+ [tr.studying_audio_5s(), "6", self.on_seek_backward],
+ [tr.studying_audio_and5s(), "7", self.on_seek_forward],
+ [tr.studying_record_own_voice(), "Shift+V", self.onRecordVoice],
+ [tr.studying_replay_own_voice(), "V", self.onReplayRecorded],
]
return opts
@@ -869,28 +869,28 @@ time = %(time)d;
suspend_note(
mw=self.mw,
note_id=self.card.nid,
- success=lambda _: tooltip(tr(TR.STUDYING_NOTE_SUSPENDED)),
+ success=lambda _: tooltip(tr.studying_note_suspended()),
)
def suspend_current_card(self) -> None:
suspend_cards(
mw=self.mw,
card_ids=[self.card.id],
- success=lambda _: tooltip(tr(TR.STUDYING_CARD_SUSPENDED)),
+ success=lambda _: tooltip(tr.studying_card_suspended()),
)
def bury_current_note(self) -> None:
bury_note(
mw=self.mw,
note_id=self.card.nid,
- success=lambda _: tooltip(tr(TR.STUDYING_NOTE_BURIED)),
+ success=lambda _: tooltip(tr.studying_note_buried()),
)
def bury_current_card(self) -> None:
bury_cards(
mw=self.mw,
card_ids=[self.card.id],
- success=lambda _: tooltip(tr(TR.STUDYING_CARD_BURIED)),
+ success=lambda _: tooltip(tr.studying_card_buried()),
)
def delete_current_note(self) -> None:
@@ -919,7 +919,7 @@ time = %(time)d;
def onReplayRecorded(self) -> None:
if not self._recordedAudio:
- tooltip(tr(TR.STUDYING_YOU_HAVENT_RECORDED_YOUR_VOICE_YET))
+ tooltip(tr.studying_you_havent_recorded_your_voice_yet())
return
av_player.play_file(self._recordedAudio)
diff --git a/qt/aqt/scheduling_ops.py b/qt/aqt/scheduling_ops.py
index c0c345d2a..053209d92 100644
--- a/qt/aqt/scheduling_ops.py
+++ b/qt/aqt/scheduling_ops.py
@@ -34,14 +34,14 @@ def set_due_date_dialog(
prompt = "\n".join(
[
tr(TR.SCHEDULING_SET_DUE_DATE_PROMPT, cards=len(card_ids)),
- tr(TR.SCHEDULING_SET_DUE_DATE_PROMPT_HINT),
+ tr.scheduling_set_due_date_prompt_hint(),
]
)
(days, success) = getText(
prompt=prompt,
parent=parent,
default=default_text,
- title=tr(TR.ACTIONS_SET_DUE_DATE),
+ title=tr.actions_set_due_date(),
)
if not success or not days.strip():
return
diff --git a/qt/aqt/sidebar.py b/qt/aqt/sidebar.py
index bbf6cd3b1..4ae1cf931 100644
--- a/qt/aqt/sidebar.py
+++ b/qt/aqt/sidebar.py
@@ -957,7 +957,7 @@ class SidebarTreeView(QTreeView):
)
root.search_node = SearchNode(negated=SearchNode(tag="none"))
root.add_simple(
- name=tr(TR.BROWSING_SIDEBAR_UNTAGGED),
+ name=tr.browsing_sidebar_untagged(),
icon=icon,
type=SidebarItemType.TAG_NONE,
search_node=SearchNode(tag="none"),
@@ -1004,7 +1004,7 @@ class SidebarTreeView(QTreeView):
)
root.search_node = SearchNode(deck="*")
current = root.add_simple(
- name=tr(TR.BROWSING_CURRENT_DECK),
+ name=tr.browsing_current_deck(),
icon=icon,
type=SidebarItemType.DECK_CURRENT,
search_node=SearchNode(deck="current"),
@@ -1072,17 +1072,17 @@ class SidebarTreeView(QTreeView):
def _maybe_add_type_specific_actions(self, menu: QMenu, item: SidebarItem) -> None:
if item.item_type in (SidebarItemType.NOTETYPE, SidebarItemType.NOTETYPE_ROOT):
menu.addAction(
- tr(TR.BROWSING_MANAGE_NOTE_TYPES), lambda: self.manage_notetype(item)
+ tr.browsing_manage_note_types(), lambda: self.manage_notetype(item)
)
elif item.item_type == SidebarItemType.NOTETYPE_TEMPLATE:
- menu.addAction(tr(TR.NOTETYPES_CARDS), lambda: self.manage_template(item))
+ menu.addAction(tr.notetypes_cards(), lambda: self.manage_template(item))
elif item.item_type == SidebarItemType.SAVED_SEARCH_ROOT:
menu.addAction(
- tr(TR.BROWSING_SIDEBAR_SAVE_CURRENT_SEARCH), self.save_current_search
+ tr.browsing_sidebar_save_current_search(), self.save_current_search
)
elif item.item_type == SidebarItemType.SAVED_SEARCH:
menu.addAction(
- tr(TR.BROWSING_UPDATE_SAVED_SEARCH),
+ tr.browsing_update_saved_search(),
lambda: self.update_saved_search(item),
)
@@ -1090,13 +1090,13 @@ class SidebarTreeView(QTreeView):
self, menu: QMenu, item: SidebarItem, index: QModelIndex
) -> None:
if self._enable_delete(item):
- menu.addAction(tr(TR.ACTIONS_DELETE), lambda: self._on_delete(item))
+ menu.addAction(tr.actions_delete(), lambda: self._on_delete(item))
def _maybe_add_rename_action(
self, menu: QMenu, item: SidebarItem, index: QModelIndex
) -> None:
if item.item_type.is_editable() and len(self._selected_items()) == 1:
- menu.addAction(tr(TR.ACTIONS_RENAME), lambda: self.edit(index))
+ menu.addAction(tr.actions_rename(), lambda: self.edit(index))
def _maybe_add_search_actions(self, menu: QMenu) -> None:
nodes = [
@@ -1106,14 +1106,14 @@ class SidebarTreeView(QTreeView):
return
menu.addSeparator()
if len(nodes) == 1:
- menu.addAction(tr(TR.ACTIONS_SEARCH), lambda: self.update_search(*nodes))
+ menu.addAction(tr.actions_search(), lambda: self.update_search(*nodes))
return
- sub_menu = menu.addMenu(tr(TR.ACTIONS_SEARCH))
+ sub_menu = menu.addMenu(tr.actions_search())
sub_menu.addAction(
- tr(TR.ACTIONS_ALL_SELECTED), lambda: self.update_search(*nodes)
+ tr.actions_all_selected(), lambda: self.update_search(*nodes)
)
sub_menu.addAction(
- tr(TR.ACTIONS_ANY_SELECTED),
+ tr.actions_any_selected(),
lambda: self.update_search(*nodes, joiner="OR"),
)
@@ -1137,21 +1137,19 @@ class SidebarTreeView(QTreeView):
menu.addSeparator()
if any(not item.expanded for item in selected_items if item.children):
- menu.addAction(tr(TR.BROWSING_SIDEBAR_EXPAND), lambda: set_expanded(True))
+ menu.addAction(tr.browsing_sidebar_expand(), lambda: set_expanded(True))
if any(item.expanded for item in selected_items if item.children):
- menu.addAction(
- tr(TR.BROWSING_SIDEBAR_COLLAPSE), lambda: set_expanded(False)
- )
+ menu.addAction(tr.browsing_sidebar_collapse(), lambda: set_expanded(False))
if any(
not c.expanded for i in selected_items for c in i.children if c.children
):
menu.addAction(
- tr(TR.BROWSING_SIDEBAR_EXPAND_CHILDREN),
+ tr.browsing_sidebar_expand_children(),
lambda: set_children_expanded(True),
)
if any(c.expanded for i in selected_items for c in i.children if c.children):
menu.addAction(
- tr(TR.BROWSING_SIDEBAR_COLLAPSE_CHILDREN),
+ tr.browsing_sidebar_collapse_children(),
lambda: set_children_expanded(False),
)
@@ -1277,7 +1275,7 @@ class SidebarTreeView(QTreeView):
def save_current_search(self) -> None:
if (search := self._get_current_search()) is None:
return
- name = getOnlyText(tr(TR.BROWSING_PLEASE_GIVE_YOUR_FILTER_A_NAME))
+ name = getOnlyText(tr.browsing_please_give_your_filter_a_name())
if not name:
return
self._save_search(name, search)
diff --git a/qt/aqt/sound.py b/qt/aqt/sound.py
index 0e6a24a31..a32a09a5f 100644
--- a/qt/aqt/sound.py
+++ b/qt/aqt/sound.py
@@ -329,7 +329,7 @@ class SimpleProcessPlayer(Player): # pylint: disable=abstract-method
try:
ret.result()
except FileNotFoundError:
- showWarning(tr(TR.MEDIA_SOUND_AND_VIDEO_ON_CARDS_WILL))
+ showWarning(tr.media_sound_and_video_on_cards_will())
# must call cb() here, as we don't currently have another way
# to flag to av_player that we've stopped
cb()
diff --git a/qt/aqt/stats.py b/qt/aqt/stats.py
index a031b9ba2..3d8c94168 100644
--- a/qt/aqt/stats.py
+++ b/qt/aqt/stats.py
@@ -10,7 +10,6 @@ from aqt import gui_hooks
from aqt.qt import *
from aqt.theme import theme_manager
from aqt.utils import (
- TR,
addCloseShortcut,
disable_help_button,
getSaveFile,
@@ -41,9 +40,7 @@ class NewDeckStats(QDialog):
f.groupBox.setVisible(False)
f.groupBox_2.setVisible(False)
restoreGeom(self, self.name)
- b = f.buttonBox.addButton(
- tr(TR.STATISTICS_SAVE_PDF), QDialogButtonBox.ActionRole
- )
+ b = f.buttonBox.addButton(tr.statistics_save_pdf(), QDialogButtonBox.ActionRole)
qconnect(b.clicked, self.saveImage)
b.setAutoDefault(False)
maybeHideClose(self.form.buttonBox)
@@ -66,10 +63,10 @@ class NewDeckStats(QDialog):
def _imagePath(self) -> str:
name = time.strftime("-%Y-%m-%d@%H-%M-%S.pdf", time.localtime(time.time()))
- name = f"anki-{tr(TR.STATISTICS_STATS)}{name}"
+ name = f"anki-{tr.statistics_stats()}{name}"
file = getSaveFile(
self,
- title=tr(TR.STATISTICS_SAVE_PDF),
+ title=tr.statistics_save_pdf(),
dir_description="stats",
key="stats",
ext=".pdf",
@@ -82,7 +79,7 @@ class NewDeckStats(QDialog):
if not path:
return
self.form.web.page().printToPdf(path)
- tooltip(tr(TR.STATISTICS_SAVED))
+ tooltip(tr.statistics_saved())
# legacy add-ons
def changePeriod(self, n: Any) -> None:
@@ -126,9 +123,7 @@ class DeckStats(QDialog):
self.setStyleSheet("QGroupBox { border: 0; }")
f.setupUi(self)
restoreGeom(self, self.name)
- b = f.buttonBox.addButton(
- tr(TR.STATISTICS_SAVE_PDF), QDialogButtonBox.ActionRole
- )
+ b = f.buttonBox.addButton(tr.statistics_save_pdf(), QDialogButtonBox.ActionRole)
qconnect(b.clicked, self.saveImage)
b.setAutoDefault(False)
qconnect(f.groups.clicked, lambda: self.changeScope("deck"))
@@ -156,10 +151,10 @@ class DeckStats(QDialog):
def _imagePath(self) -> str:
name = time.strftime("-%Y-%m-%d@%H-%M-%S.pdf", time.localtime(time.time()))
- name = f"anki-{tr(TR.STATISTICS_STATS)}{name}"
+ name = f"anki-{tr.statistics_stats()}{name}"
file = getSaveFile(
self,
- title=tr(TR.STATISTICS_SAVE_PDF),
+ title=tr.statistics_save_pdf(),
dir_description="stats",
key="stats",
ext=".pdf",
@@ -172,7 +167,7 @@ class DeckStats(QDialog):
if not path:
return
self.form.web.page().printToPdf(path)
- tooltip(tr(TR.STATISTICS_SAVED))
+ tooltip(tr.statistics_saved())
def changePeriod(self, n: int) -> None:
self.period = n
diff --git a/qt/aqt/studydeck.py b/qt/aqt/studydeck.py
index 1156d662c..64fd12601 100644
--- a/qt/aqt/studydeck.py
+++ b/qt/aqt/studydeck.py
@@ -10,7 +10,6 @@ from aqt import gui_hooks
from aqt.deck_ops import add_deck_dialog
from aqt.qt import *
from aqt.utils import (
- TR,
HelpPage,
HelpPageArgument,
disable_help_button,
@@ -58,9 +57,9 @@ class StudyDeck(QDialog):
button_or_label, QDialogButtonBox.ActionRole
)
else:
- b = QPushButton(tr(TR.ACTIONS_ADD))
+ b = QPushButton(tr.actions_add())
b.setShortcut(QKeySequence("Ctrl+N"))
- b.setToolTip(shortcut(tr(TR.DECKS_ADD_NEW_DECK_CTRLANDN)))
+ b.setToolTip(shortcut(tr.decks_add_new_deck_ctrlandn()))
self.form.buttonBox.addButton(b, QDialogButtonBox.ActionRole)
qconnect(b.clicked, self.onAddDeck)
if title:
@@ -79,7 +78,7 @@ class StudyDeck(QDialog):
self.origNames = names()
self.name: Optional[str] = None
self.ok = self.form.buttonBox.addButton(
- accept or tr(TR.DECKS_STUDY), QDialogButtonBox.AcceptRole
+ accept or tr.decks_study(), QDialogButtonBox.AcceptRole
)
self.setWindowModality(Qt.WindowModal)
qconnect(self.form.buttonBox.helpRequested, lambda: openHelp(help))
@@ -150,7 +149,7 @@ class StudyDeck(QDialog):
gui_hooks.state_did_reset.remove(self.onReset)
row = self.form.list.currentRow()
if row < 0:
- showInfo(tr(TR.DECKS_PLEASE_SELECT_SOMETHING))
+ showInfo(tr.decks_please_select_something())
return
self.name = self.names[self.form.list.currentRow()]
QDialog.accept(self)
diff --git a/qt/aqt/sync.py b/qt/aqt/sync.py
index 9e6a10f5a..69a93c477 100644
--- a/qt/aqt/sync.py
+++ b/qt/aqt/sync.py
@@ -119,7 +119,7 @@ def sync_collection(mw: aqt.main.AnkiQt, on_done: Callable[[], None]) -> None:
mw.taskman.with_progress(
lambda: mw.col.sync_collection(auth),
on_future_done,
- label=tr(TR.SYNC_CHECKING),
+ label=tr.sync_checking(),
immediate=True,
)
@@ -144,7 +144,7 @@ def full_sync(
def confirm_full_download(mw: aqt.main.AnkiQt, on_done: Callable[[], None]) -> None:
# confirmation step required, as some users customize their notetypes
# in an empty collection, then want to upload them
- if not askUser(tr(TR.SYNC_CONFIRM_EMPTY_DOWNLOAD)):
+ if not askUser(tr.sync_confirm_empty_download()):
return on_done()
else:
mw.closeAllWindows(lambda: full_download(mw, on_done))
@@ -157,7 +157,7 @@ def on_full_sync_timer(mw: aqt.main.AnkiQt) -> None:
sync_progress = progress.full_sync
if sync_progress.transferred == sync_progress.total:
- label = tr(TR.SYNC_CHECKING)
+ label = tr.sync_checking()
else:
label = None
mw.progress.update(
@@ -197,7 +197,7 @@ def full_download(mw: aqt.main.AnkiQt, on_done: Callable[[], None]) -> None:
mw.taskman.with_progress(
download,
on_future_done,
- label=tr(TR.SYNC_DOWNLOADING_FROM_ANKIWEB),
+ label=tr.sync_downloading_from_ankiweb(),
)
@@ -226,7 +226,7 @@ def full_upload(mw: aqt.main.AnkiQt, on_done: Callable[[], None]) -> None:
mw.taskman.with_progress(
lambda: mw.col.full_upload(mw.pm.sync_auth()),
on_future_done,
- label=tr(TR.SYNC_UPLOADING_TO_ANKIWEB),
+ label=tr.sync_uploading_to_ankiweb(),
)
@@ -271,11 +271,11 @@ def sync_login(
def ask_user_to_decide_direction() -> FullSyncChoice:
button_labels = [
- tr(TR.SYNC_UPLOAD_TO_ANKIWEB),
- tr(TR.SYNC_DOWNLOAD_FROM_ANKIWEB),
- tr(TR.SYNC_CANCEL_BUTTON),
+ tr.sync_upload_to_ankiweb(),
+ tr.sync_download_from_ankiweb(),
+ tr.sync_cancel_button(),
]
- diag = askUserDialog(tr(TR.SYNC_CONFLICT_EXPLANATION), button_labels)
+ diag = askUserDialog(tr.sync_conflict_explanation(), button_labels)
diag.setDefault(2)
ret = diag.run()
if ret == button_labels[0]:
@@ -304,12 +304,12 @@ def get_id_and_pass_from_user(
vbox.addWidget(info_label)
vbox.addSpacing(20)
g = QGridLayout()
- l1 = QLabel(tr(TR.SYNC_ANKIWEB_ID_LABEL))
+ l1 = QLabel(tr.sync_ankiweb_id_label())
g.addWidget(l1, 0, 0)
user = QLineEdit()
user.setText(username)
g.addWidget(user, 0, 1)
- l2 = QLabel(tr(TR.SYNC_PASSWORD_LABEL))
+ l2 = QLabel(tr.sync_password_label())
g.addWidget(l2, 1, 0)
passwd = QLineEdit()
passwd.setText(password)
diff --git a/qt/aqt/tag_ops.py b/qt/aqt/tag_ops.py
index d99ab8d65..5f2d3c66c 100644
--- a/qt/aqt/tag_ops.py
+++ b/qt/aqt/tag_ops.py
@@ -58,7 +58,7 @@ def rename_tag(
if out.count:
tooltip(tr(TR.BROWSING_NOTES_UPDATED, count=out.count), parent=parent)
else:
- showInfo(tr(TR.BROWSING_TAG_RENAME_WARNING_EMPTY), parent=parent)
+ showInfo(tr.browsing_tag_rename_warning_empty(), parent=parent)
mw.perform_op(
lambda: mw.col.tags.rename(old=current_name, new=new_name),
diff --git a/qt/aqt/toolbar.py b/qt/aqt/toolbar.py
index 5e3c7505b..4decea84d 100644
--- a/qt/aqt/toolbar.py
+++ b/qt/aqt/toolbar.py
@@ -100,28 +100,28 @@ class Toolbar:
links = [
self.create_link(
"decks",
- tr(TR.ACTIONS_DECKS),
+ tr.actions_decks(),
self._deckLinkHandler,
tip=tr(TR.ACTIONS_SHORTCUT_KEY, val="D"),
id="decks",
),
self.create_link(
"add",
- tr(TR.ACTIONS_ADD),
+ tr.actions_add(),
self._addLinkHandler,
tip=tr(TR.ACTIONS_SHORTCUT_KEY, val="A"),
id="add",
),
self.create_link(
"browse",
- tr(TR.QT_MISC_BROWSE),
+ tr.qt_misc_browse(),
self._browseLinkHandler,
tip=tr(TR.ACTIONS_SHORTCUT_KEY, val="B"),
id="browse",
),
self.create_link(
"stats",
- tr(TR.QT_MISC_STATS),
+ tr.qt_misc_stats(),
self._statsLinkHandler,
tip=tr(TR.ACTIONS_SHORTCUT_KEY, val="T"),
id="stats",
@@ -138,7 +138,7 @@ class Toolbar:
######################################################################
def _create_sync_link(self) -> str:
- name = tr(TR.QT_MISC_SYNC)
+ name = tr.qt_misc_sync()
title = tr(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 c36fcadd8..5be7f6686 100644
--- a/qt/aqt/update.py
+++ b/qt/aqt/update.py
@@ -61,8 +61,8 @@ def askAndUpdate(mw: aqt.AnkiQt, ver: str) -> None:
msg = QMessageBox(mw)
msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No) # type: ignore
msg.setIcon(QMessageBox.Information)
- msg.setText(baseStr + tr(TR.QT_MISC_WOULD_YOU_LIKE_TO_DOWNLOAD_IT))
- button = QPushButton(tr(TR.QT_MISC_IGNORE_THIS_UPDATE))
+ msg.setText(baseStr + tr.qt_misc_would_you_like_to_download_it())
+ button = QPushButton(tr.qt_misc_ignore_this_update())
msg.addButton(button, QMessageBox.RejectRole)
msg.setDefaultButton(QMessageBox.Yes)
ret = msg.exec_()
diff --git a/qt/aqt/utils.py b/qt/aqt/utils.py
index d77ccf358..2a57f82c2 100644
--- a/qt/aqt/utils.py
+++ b/qt/aqt/utils.py
@@ -33,10 +33,9 @@ from PyQt5.QtWidgets import (
QWidget,
)
-import anki
import aqt
from anki import Collection
-from anki.lang import TR # pylint: disable=unused-import
+from anki.lang import TR, tr_legacyglobal # pylint: disable=unused-import
from anki.utils import invalidFilename, isMac, isWin, noBundledLibs, versionWithBuild
from aqt.qt import *
from aqt.theme import theme_manager
@@ -67,9 +66,8 @@ def locale_dir() -> str:
return os.path.join(aqt_data_folder(), "locale")
-def tr(key: TR, **kwargs: Union[str, int, float]) -> str:
- "Shortcut to access Fluent translations."
- return anki.lang.current_i18n.translate(key, **kwargs)
+# shortcut to access Fluent translations; set as
+tr = tr_legacyglobal
class HelpPage(Enum):
@@ -110,7 +108,7 @@ def openHelp(section: HelpPageArgument) -> None:
def openLink(link: Union[str, QUrl]) -> None:
- tooltip(tr(TR.QT_MISC_LOADING), period=1000)
+ tooltip(tr.qt_misc_loading(), period=1000)
with noBundledLibs():
QDesktopServices.openUrl(QUrl(link))
@@ -226,7 +224,7 @@ def showText(
def onCopy() -> None:
QApplication.clipboard().setText(text.toPlainText())
- btn = QPushButton(tr(TR.QT_MISC_COPY_TO_CLIPBOARD))
+ btn = QPushButton(tr.qt_misc_copy_to_clipboard())
qconnect(btn.clicked, onCopy)
box.addButton(btn, QDialogButtonBox.ActionRole)
@@ -301,8 +299,8 @@ class ButtonedDialog(QMessageBox):
for b in buttons:
self._buttons.append(self.addButton(b, QMessageBox.AcceptRole))
if help:
- self.addButton(tr(TR.ACTIONS_HELP), QMessageBox.HelpRole)
- buttons.append(tr(TR.ACTIONS_HELP))
+ self.addButton(tr.actions_help(), QMessageBox.HelpRole)
+ buttons.append(tr.actions_help())
def run(self) -> str:
self.exec_()
@@ -536,7 +534,7 @@ def getSaveFile(
aqt.mw.pm.profile[config_key] = dir
# check if it exists
if os.path.exists(file):
- if not askUser(tr(TR.QT_MISC_THIS_FILE_EXISTS_ARE_YOU_SURE), parent):
+ if not askUser(tr.qt_misc_this_file_exists_are_you_sure(), parent):
return None
return file
diff --git a/qt/aqt/webview.py b/qt/aqt/webview.py
index 642033976..9c91a3ca6 100644
--- a/qt/aqt/webview.py
+++ b/qt/aqt/webview.py
@@ -13,7 +13,7 @@ from anki.utils import isLin, isMac, isWin
from aqt import colors, gui_hooks
from aqt.qt import *
from aqt.theme import theme_manager
-from aqt.utils import TR, openLink, showInfo, tr
+from aqt.utils import openLink, showInfo, tr
serverbaseurl = re.compile(r"^.+:\/\/[^\/]+")
@@ -305,7 +305,7 @@ class AnkiWebView(QWebEngineView):
def contextMenuEvent(self, evt: QContextMenuEvent) -> None:
m = QMenu(self)
- a = m.addAction(tr(TR.ACTIONS_COPY))
+ a = m.addAction(tr.actions_copy())
qconnect(a.triggered, self.onCopy)
gui_hooks.webview_will_show_context_menu(self, m)
m.popup(QCursor.pos())
@@ -396,7 +396,7 @@ class AnkiWebView(QWebEngineView):
if isWin:
# T: include a font for your language on Windows, eg: "Segoe UI", "MS Mincho"
- family = tr(TR.QT_MISC_SEGOE_UI)
+ family = tr.qt_misc_segoe_ui()
button_style = "button { font-family:%s; }" % family
button_style += "\n:focus { outline: 1px solid %s; }" % color_hl
font = f"font-size:12px;font-family:{family};"