# Translating KCC KCC ships its UI and CLI strings in English by default, with optional translations loaded at runtime. This file documents how to keep those translations up to date when strings are added or changed. ## Why translation files need maintenance Translatable strings are wrapped in `self.tr(...)` or `QT_TRANSLATE_NOOP('KCCGUI', ...)` in the source. The English text lives in the code, but the actual translations live in `translations/*.ts`. If a new string is added to the code and the `.ts` files are not regenerated, the new string has no translation and silently falls back to English. The `.ts` files are the human-editable source of truth. The `.qm` files are the compiled, runtime-format translations. Both are committed to the repository. ## Prerequisites - Python 3 with PySide6 installed in the active environment, which provides the `pyside6-lupdate`, `pyside6-lrelease`, and `pyside6-rcc` tools. - Run all commands from the repository root. ## Updating translations after adding a string The whole flow is wrapped in one script: ```sh ./gen_translation_files.sh # macOS / Linux gen_translation_files.bat # Windows ``` It runs three steps in order: 1. `pyside6-lupdate` scans the source files and updates every `translations/*.ts` in place. 2. `pyside6-lrelease` compiles each `.ts` into its `.qm` runtime file. 3. `pyside6-rcc` re-bundles the `.qm` files into `KCC_rc.py`, because the `.qm` files are loaded from the Qt resource system, not from disk. After running the script, open the `.ts` files and fill in the newly added `` entries. `lupdate` extracts strings but does not translate them. ### Manual equivalent If you prefer to run the steps yourself, the script is equivalent to: ```sh for ts in translations/*.ts; do pyside6-lupdate \ kindlecomicconverter/KCC_gui.py \ kindlecomicconverter/comic2ebook.py \ gui/KCC.ui \ gui/MetaEditor.ui \ -ts "$ts" done for ts in translations/*.ts; do pyside6-lrelease "$ts" -qm "${ts%.ts}.qm" done pyside6-rcc gui/KCC.qrc > kindlecomicconverter/KCC_rc.py ``` The source file list is significant. `comic2ebook.py` contains the CLI-side messages; omitting it drops 20 strings (250 -> 230 extracted). The `.ui` files contribute the `mainWindow` and `editorDialog` contexts. `pyside6-project` is intentionally not used. Its `lupdate` scans the whole project, which would pick up both `gui/KCC.ui` and the generated `kindlecomicconverter/KCC_ui.py` and extract the `mainWindow` context twice. ## Generated files and what to commit | File | Generated by | Commit? | |------|--------------|---------| | `translations/*.ts` | edited by hand (updated by `lupdate`) | yes | | `translations/*.qm` | `pyside6-lrelease` | yes | | `kindlecomicconverter/KCC_rc.py` | `pyside6-rcc` | yes | The `.qm` files are also embedded into `KCC_rc.py` via `gui/KCC.qrc`; both the standalone `.qm` and the resource module are kept in sync by the script. ## Adding a new language 1. Generate the new source file: ```sh pyside6-lupdate \ kindlecomicconverter/KCC_gui.py \ kindlecomicconverter/comic2ebook.py \ gui/KCC.ui \ gui/MetaEditor.ui \ -ts translations/kcc_xx_XX.ts ``` 2. Fill in the `` entries. 3. Register the language in `kindlecomicconverter/i18n.py` in the `LANGUAGES` dict. 4. Add the `.qm` to `gui/KCC.qrc` under the `/i18n` prefix: ```xml ../translations/kcc_xx_XX.qm ``` 5. Run `gen_translation_files` to compile and re-bundle the new language. ## Verifying the result - Run the script twice: the second run should produce no further changes (`git diff` stays empty), confirming the flow is idempotent. - Launch KCC and switch languages via the language button; verify the UI, the metadata editor, and the conversion progress messages all switch. ## Common problems - **`pyside6-lupdate: command not found`** — PySide6 is not installed or the virtual environment is not active. Install with `pip install pyside6`. - **Hundreds of `` lines changed after running `lupdate`** — the `-ts` target was written outside `translations/`. Location paths are relative to the `.ts` file, so always update the files in place. - **`dropping duplicate messages` warnings from `lrelease`** — a `.ts` file has the same `(context, source)` entry twice. Regenerate it with `lupdate`. - **Some strings stay English after switching languages** — the `.qm` was not re-bundled into `KCC_rc.py`. Run `gen_translation_files` (step 3). - **`type="vanished"` entries accumulate** — this is normal: `lupdate` marks entries whose source string is no longer found instead of deleting them. `lrelease` skips them, so they do not affect the runtime translations.