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};"