Tłumaczenia¶
Każdy widoczny dla użytkownika string pokazywany przez wtyczkę musi być
tłumaczalny, z katalogami dla wszystkich piętnastu obsługiwanych języków —
en, pl, de, fr, es, pt_PT, pt_BR, nl, sv, nb, da, fi,
it, cs, sk — zanim wtyczkę można uznać za skończoną. To ta sama
poprzeczka co testy.
Katalogi¶
Każda wtyczka mająca jakikolwiek string niesie po jednym katalogu .ts na
język w swoim folderze Translations/:
Podepnij je do builda przez mte_add_plugin:
mte_add_plugin(NAME MyPlugin
SOURCES Src/MyPlugin.cpp
TRANSLATIONS
Translations/MyPlugin_en.ts
Translations/MyPlugin_pl.ts
Translations/MyPlugin_de.ts
Translations/MyPlugin_fr.ts
)
Build uruchamia lrelease, aby przygotować pliki .qm; TranslationManager
ładuje je w czasie działania po nazwie katalogu (katalogi wtyczek pod
Plugins/Translations/<Plugin>/).
Oznaczanie stringów do tłumaczenia¶
- Dla zwykłych stringów UI preferuj
QObject::tr(...)(kontekst = klasa). - Helper
tr_()opakowujeQCoreApplication::translate("<Context>", s)dla stringów pozaQObject.
tr_() jest niewidoczny dla lupdate
lupdate nie potrafi rozwiązać kontekstu wewnątrz tr_(), więc te katalogi
utrzymywane są ręcznie. Utrzymuj tekst <source> bajt w bajt identyczny
ze stringiem w czasie działania, inaczej tłumaczenie po cichu się nie
zastosuje.
Nadążanie za zmianą języka przy otwartej stronie¶
Użytkownik może zmienić język interfejsu w Preferencjach ▸ Ogólne bez
restartu. Qt wysyła wtedy QEvent::LanguageChange do każdego widgetu — ale
drzewo widgetów, którego stringi ustawiono raz, w kodzie budującym je, zostaje
przy starym języku aż do zamknięcia i ponownego otwarcia okna.
PluginApi/Qt/Retranslator.h rozwiązuje to bez pisania każdego stringu dwa
razy. Zapamiętuje, jak powstał każdy string, i odtwarza to nagranie przy
zmianie języka:
#include <PluginApi/Qt/Retranslator.h>
QWidget* MyPage::createWidget(QWidget* parent)
{
auto* page = new QWidget(parent);
auto& rt = MTE::plugin::Retranslator::installOn(page);
m_watch = new QCheckBox(page);
rt.add([this] { m_watch->setText(tr_("Watch open files")); });
m_size = new QSpinBox(page);
rt.row(form, m_size, [] { return tr_("Font size:"); }); // QFormLayout caption
return page;
}
add()uruchamia swoją lambdę od razu, więc miejsce wywołania czyta się dokładnie jak zastępowana linia „ustaw tekst", a każdy string nadal pojawia się w źródle raz.row()robi to samo dla podpisu wQFormLayout, do którego poaddRow()nie da się już inaczej dotrzeć.installOn()jest idempotentne dla danego widgetu; rejestrator jest jego dzieckiem i ginie razem z nim. Jeśli strona może przeżyć przechwycony widget, trzymaj go wQPointer.
Podobnie jak PluginApi/Qt/ISettingsPage.h, jest to opcjonalny nagłówek Qt:
dołączaj go tylko z kodu, który i tak buduje QWidget-y (wymaga
Qt6::Widgets). Część PluginApi wolna od Qt pozostaje nietknięta.
Co nie jest tłumaczone¶
Dwie rzeczy z założenia zostają w języku, w którym napisał je autor:
nameidescriptionTwojej wtyczki zplugin.json, pokazywane w Preferencjach ▸ Wtyczki. Manifest jest czytany zanim wtyczka zostanie załadowana — właśnie dzięki temu strona wymienia także wtyczki wyłączone lub zbudowane dla innej wersji API — więc w tym momencie nie ma katalogu, w którym można by je odszukać.- Etykiety deklaratywnej (pythonowej) strony ustawień lub panelu doku. Są to dane, które Twój worker wysyła do hosta, a nie stringi, które host mógłby dopasować do katalogu.
Wszystko, co wtyczka rejestruje w czasie działania — tytuły poleceń, pozycje menu, tytuły doków, podpisy na stronie ustawień — jest tłumaczone w zwykły sposób, opisany wyżej.
Trzy z tych stringów wyszukuje host, nie Twój kod, we wspólnym kontekście
PluginMenus: każdy segment menuPath, title polecenia i category
polecenia. Wszystkie trzy dostarcz jako wpisy <source> w kontekście
PluginMenus własnych katalogów. Kategorię użytkownik czyta w kolumnie
Kategoria okna Preferencje ▸ Skróty; gdy brakuje jej w katalogu, kolumna
pokazuje surowe angielskie słowo obok przetłumaczonych wierszy rdzenia.
Kategoria, która jest zarazem tytułem menu (Search, Encoding), dzieli z nim
jeden wpis: zostaw w nim mnemonik & dla menu, host zdejmie go w kolumnie.
Definicja ukończenia¶
Lokalizacja wtyczki jest skończona dopiero wtedy, gdy wszystkie piętnaście
plików .ts istnieje, jest podpiętych, a lrelease raportuje 0 unfinished.