update no-arg tr references in qt/

This commit is contained in:
Damien Elmes 2021-03-26 13:48:26 +10:00
parent ebe655975c
commit 0c338bfd53
45 changed files with 494 additions and 515 deletions

View File

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

View File

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

View File

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

View File

@ -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 = "<center><img src='/_anki/imgs/anki-logo-thin.png'></center>"
abouttext += f"<p>{tr(TR.ABOUT_ANKI_IS_A_FRIENDLY_INTELLIGENT_SPACED)}"
abouttext += f"<p>{tr(TR.ABOUT_ANKI_IS_LICENSED_UNDER_THE_AGPL3)}"
abouttext += f"<p>{tr.about_anki_is_a_friendly_intelligent_spaced()}"
abouttext += f"<p>{tr.about_anki_is_licensed_under_the_agpl3()}"
abouttext += f"<p>{tr(TR.ABOUT_VERSION, val=versionWithBuild())}<br>"
abouttext += ("Python %s Qt %s PyQt %s<br>") % (
platform.python_version(),
@ -212,8 +212,8 @@ def show(mw: aqt.AnkiQt) -> QDialog:
abouttext += "<p>" + tr(
TR.ABOUT_WRITTEN_BY_DAMIEN_ELMES_WITH_PATCHES, cont=", ".join(allusers)
)
abouttext += f"<p>{tr(TR.ABOUT_IF_YOU_HAVE_CONTRIBUTED_AND_ARE)}"
abouttext += f"<p>{tr(TR.ABOUT_A_BIG_THANKS_TO_ALL_THE)}"
abouttext += f"<p>{tr.about_if_you_have_contributed_and_are()}"
abouttext += f"<p>{tr.about_a_big_thanks_to_all_the()}"
abt.label.setMinimumWidth(800)
abt.label.setMinimumHeight(600)
dialog.show()

View File

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

View File

@ -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"<br><br>{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 = ",<br>".join(f"<b>{os.path.basename(p)}</b>" 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 = "<br>".join(log)
if advise_restart:
log_html += f"<br><br>{tr(TR.ADDONS_PLEASE_RESTART_ANKI_TO_COMPLETE_THE)}"
log_html += f"<br><br>{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(
"<br><br>".join(errs + [msg]),
parent=parent,
textFormat="rich",
title=tr(TR.ADDONS_ADDON_INSTALLATION_ERROR),
title=tr.addons_addon_installation_error(),
)
return not errs

View File

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

View File

@ -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)(.+)<hr id=answer>(.+)", 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<hr id=answer>\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)

View File

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

View File

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

View File

@ -169,9 +169,9 @@ class DeckBrowser:
buf = """
<tr><th colspan=5 align=start>%s</th><th class=count>%s</th>
<th class=count>%s</th><th class=optscol></th></tr>""" % (
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:
<center>
<div class=callout>
<div>
{tr(TR.SCHEDULING_UPDATE_SOON)}
{tr.scheduling_update_soon()}
</div>
<div>
<button onclick='pycmd("v2upgrade")'>
{tr(TR.SCHEDULING_UPDATE_BUTTON)}
{tr.scheduling_update_button()}
</button>
<button onclick='pycmd("v2upgradeinfo")'>
{tr(TR.SCHEDULING_UPDATE_MORE_INFO_BUTTON)}
{tr.scheduling_update_more_info_button()}
</button>
<button onclick='pycmd("v2upgradelater")'>
{tr(TR.SCHEDULING_UPDATE_LATER_BUTTON)}
{tr.scheduling_update_later_button()}
</button>
</div>
</div>
@ -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()

View File

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

View File

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

View File

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

View File

@ -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(),
"""
<span id="forecolor" class="topbut rounded" style="background: #000"></span>
""",
@ -199,18 +199,18 @@ class Editor:
self._addButton(
None,
"changeCol",
tr(TR.EDITING_CHANGE_COLOUR_F8),
tr.editing_change_colour_f8(),
"""
<span class="topbut rounded rainbow"></span>
""",
),
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())

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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</button>""" % (
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</button>""" % (
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</button>""" % (
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</button>""" % (
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</button>""" % (
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</button>""" % (
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</button>""" % (
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</button>""" % (
)
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</button>""" % (
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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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:
</table>
</td><td align=center>
%s</td></tr></table>""" % (
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]:

View File

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

View File

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

View File

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

View File

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

View File

@ -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;
</script>
""" % 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;
<span class=stattxt>%s</span><br>
<button title="%s" id="ansbut" class="focus" onclick='pycmd("ans");'>%s</button>""" % (
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)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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