use new i18n infrastructure for more media check / media sync strings
This commit is contained in:
parent
0217cff099
commit
67a741958c
@ -10,10 +10,15 @@ from typing import Iterable, List, Optional, TypeVar
|
||||
|
||||
import aqt
|
||||
from anki import hooks
|
||||
from anki.lang import _, ngettext
|
||||
from anki.rsbackend import Interrupted, MediaCheckOutput, Progress, ProgressKind
|
||||
from anki.rsbackend import (
|
||||
Interrupted,
|
||||
MediaCheckOutput,
|
||||
Progress,
|
||||
ProgressKind,
|
||||
StringsGroup,
|
||||
)
|
||||
from aqt.qt import *
|
||||
from aqt.utils import askUser, restoreGeom, saveGeom, showText, tooltip
|
||||
from aqt.utils import askUser, restoreGeom, saveGeom, showText, tooltip, tr
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
@ -84,14 +89,14 @@ class MediaChecker:
|
||||
layout.addWidget(box)
|
||||
|
||||
if output.unused:
|
||||
b = QPushButton(_("Delete Unused Files"))
|
||||
b = QPushButton(tr(StringsGroup.MEDIA_CHECK, "delete-unused"))
|
||||
b.setAutoDefault(False)
|
||||
box.addButton(b, QDialogButtonBox.RejectRole)
|
||||
b.clicked.connect(lambda c: self._on_trash_files(output.unused)) # type: ignore
|
||||
|
||||
if output.missing:
|
||||
if any(map(lambda x: x.startswith("latex-"), output.missing)):
|
||||
b = QPushButton(_("Render LaTeX"))
|
||||
b = QPushButton(tr(StringsGroup.MEDIA_CHECK, "render-latex"))
|
||||
b.setAutoDefault(False)
|
||||
box.addButton(b, QDialogButtonBox.RejectRole)
|
||||
b.clicked.connect(self._on_render_latex) # type: ignore
|
||||
@ -120,37 +125,34 @@ class MediaChecker:
|
||||
browser.onSearchActivated()
|
||||
showText(err, type="html")
|
||||
else:
|
||||
tooltip(_("All LaTeX rendered."))
|
||||
tooltip(tr(StringsGroup.MEDIA_CHECK, "all-latex-rendered"))
|
||||
|
||||
def _on_render_latex_progress(self, count: int) -> bool:
|
||||
if self.progress_dialog.wantCancel:
|
||||
return False
|
||||
|
||||
self.mw.progress.update(_("Checked {}...").format(count))
|
||||
self.mw.progress.update(tr(StringsGroup.MEDIA_CHECK, "checked", count=count))
|
||||
return True
|
||||
|
||||
def _on_trash_files(self, fnames: List[str]):
|
||||
if not askUser(_("Delete unused media?")):
|
||||
if not askUser(tr(StringsGroup.MEDIA_CHECK, "delete-unused-confirm")):
|
||||
return
|
||||
|
||||
self.progress_dialog = self.mw.progress.start()
|
||||
|
||||
last_progress = time.time()
|
||||
remaining = len(fnames)
|
||||
total = len(fnames)
|
||||
try:
|
||||
for chunk in chunked_list(fnames, 25):
|
||||
self.mw.col.media.trash_files(chunk)
|
||||
remaining -= len(chunk)
|
||||
if time.time() - last_progress >= 0.3:
|
||||
label = (
|
||||
ngettext(
|
||||
"%d file remaining...", "%d files remaining...", remaining,
|
||||
)
|
||||
% remaining
|
||||
self.mw.progress.update(
|
||||
tr(StringsGroup.MEDIA_CHECK, "files-remaining", count=remaining)
|
||||
)
|
||||
self.mw.progress.update(label)
|
||||
finally:
|
||||
self.mw.progress.finish()
|
||||
self.progress_dialog = None
|
||||
|
||||
tooltip(_("Files moved to trash."))
|
||||
tooltip(tr(StringsGroup.MEDIA_CHECK, "delete-unused-complete", count=total))
|
||||
|
@ -19,6 +19,7 @@ from anki.rsbackend import (
|
||||
NetworkErrorKind,
|
||||
Progress,
|
||||
ProgressKind,
|
||||
StringsGroup,
|
||||
SyncError,
|
||||
SyncErrorKind,
|
||||
)
|
||||
@ -26,7 +27,7 @@ from anki.types import assert_impossible
|
||||
from anki.utils import intTime
|
||||
from aqt import gui_hooks
|
||||
from aqt.qt import QDialog, QDialogButtonBox, QPushButton
|
||||
from aqt.utils import showWarning
|
||||
from aqt.utils import showWarning, tr
|
||||
|
||||
LogEntry = Union[MediaSyncProgress, str]
|
||||
|
||||
@ -68,10 +69,10 @@ class MediaSyncer:
|
||||
return
|
||||
|
||||
if not self.mw.pm.media_syncing_enabled():
|
||||
self._log_and_notify(_("Media syncing disabled."))
|
||||
self._log_and_notify(tr(StringsGroup.SYNC, "media-disabled"))
|
||||
return
|
||||
|
||||
self._log_and_notify(_("Media sync starting..."))
|
||||
self._log_and_notify(tr(StringsGroup.SYNC, "media-starting"))
|
||||
self._syncing = True
|
||||
self._want_stop = False
|
||||
gui_hooks.media_sync_did_start_or_stop(True)
|
||||
@ -104,14 +105,14 @@ class MediaSyncer:
|
||||
if exc is not None:
|
||||
self._handle_sync_error(exc)
|
||||
else:
|
||||
self._log_and_notify(_("Media sync complete."))
|
||||
self._log_and_notify(tr(StringsGroup.SYNC, "media-complete"))
|
||||
|
||||
def _handle_sync_error(self, exc: BaseException):
|
||||
if isinstance(exc, Interrupted):
|
||||
self._log_and_notify(_("Media sync aborted."))
|
||||
self._log_and_notify(tr(StringsGroup.SYNC, "media-aborted"))
|
||||
return
|
||||
|
||||
self._log_and_notify(_("Media sync failed."))
|
||||
self._log_and_notify(tr(StringsGroup.SYNC, "media-failed"))
|
||||
if isinstance(exc, SyncError):
|
||||
kind = exc.kind()
|
||||
if kind == SyncErrorKind.AUTH_FAILED:
|
||||
@ -156,7 +157,7 @@ class MediaSyncer:
|
||||
def abort(self) -> None:
|
||||
if not self.is_syncing():
|
||||
return
|
||||
self._log_and_notify(_("Media sync aborting..."))
|
||||
self._log_and_notify(tr(StringsGroup.SYNC, "media-aborting"))
|
||||
self._want_stop = True
|
||||
|
||||
def is_syncing(self) -> bool:
|
||||
@ -199,7 +200,7 @@ class MediaSyncDialog(QDialog):
|
||||
self._close_when_done = close_when_done
|
||||
self.form = aqt.forms.synclog.Ui_Dialog()
|
||||
self.form.setupUi(self)
|
||||
self.abort_button = QPushButton(_("Abort"))
|
||||
self.abort_button = QPushButton(tr(StringsGroup.SYNC, "abort"))
|
||||
self.abort_button.clicked.connect(self._on_abort) # type: ignore
|
||||
self.abort_button.setAutoDefault(False)
|
||||
self.form.buttonBox.addButton(self.abort_button, QDialogButtonBox.ActionRole)
|
||||
|
@ -1,14 +1,18 @@
|
||||
# Copyright: Ankitects Pty Ltd and contributors
|
||||
# -*- coding: utf-8 -*-
|
||||
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from typing import Any, Optional
|
||||
from typing import Any, Optional, Union
|
||||
|
||||
import aqt
|
||||
from anki.lang import _
|
||||
from anki.rsbackend import StringsGroup
|
||||
from anki.utils import invalidFilename, isMac, isWin, noBundledLibs, versionWithBuild
|
||||
from aqt.qt import *
|
||||
from aqt.theme import theme_manager
|
||||
@ -27,6 +31,12 @@ def locale_dir() -> str:
|
||||
return os.path.join(aqt_data_folder(), "locale")
|
||||
|
||||
|
||||
def tr(group: StringsGroup, key: str, **kwargs: Union[str, int, float]) -> str:
|
||||
"""Shortcut to access translations from the backend.
|
||||
(Currently) requires an open collection."""
|
||||
return aqt.mw.col.backend.translate(group, key, **kwargs)
|
||||
|
||||
|
||||
def openHelp(section):
|
||||
link = aqt.appHelpSite
|
||||
if section:
|
||||
|
@ -19,3 +19,17 @@ missing-file = Missing: {$filename}
|
||||
unused-file = Unused: {$filename}
|
||||
|
||||
checked = Checked {$count}...
|
||||
|
||||
delete-unused = Delete Unused
|
||||
delete-unused-confirm = Delete unused media?
|
||||
files-remaining = {$count ->
|
||||
[one] 1 file
|
||||
*[other] {$count} files
|
||||
} remaining.
|
||||
delete-unused-complete = {$count ->
|
||||
[one] 1 file
|
||||
*[other] {$count} files
|
||||
} moved to the trash.
|
||||
|
||||
render-latex = Render LaTeX
|
||||
all-latex-rendered = All LaTeX rendered.
|
||||
|
@ -1,3 +1,16 @@
|
||||
### Messages shown when synchronizing with AnkiWeb.
|
||||
|
||||
## Media synchronization
|
||||
|
||||
media-added-count = Added: {$up}↑ {$down}↓
|
||||
media-removed-count = Removed: {$up}↑ {$down}↓
|
||||
media-checked-count = Checked: {$count}
|
||||
|
||||
media-starting = Media sync starting...
|
||||
media-complete = Media sync complete.
|
||||
media-failed = Media sync failed.
|
||||
media-aborting = Media sync aborting...
|
||||
media-aborted = Media sync aborted.
|
||||
media-disabled = Media sync disabled.
|
||||
|
||||
abort-button = Abort
|
||||
|
Loading…
Reference in New Issue
Block a user