Skip to contentSkip to content

Adding or Changing a Feature

Use this page when you want to add a new feature to Manga Translator — a new setting, a new translator/OCR/renderer option, a new page, or new UI copy — or modify an existing one. It describes the full path from configuration to UI to runtime consumption. It is not an architecture overview (see Architecture and code boundaries), and it does not expand on test methodology, packaging/release, or HTTP API details (see Tests and code quality, Packaging and release, and the pages under developer/http-api/).

Relevant code

  • This guide focuses on how a code change takes effect: config model → settings-page mounting → i18n → persistence → backend consumption → tests and manual verification.
  • The detailed module boundaries of the desktop UI, business logic, services, and backend pipeline live in Architecture and code boundaries; this page lists which files a new feature usually touches at each layer.
  • Adding API credentials, slots, or rotation strategies is not described here (see the API-management pages); adding prompt files, batch schemes, or rich-text rules is covered by the corresponding feature pages.
  • This page contains no real .env, user config.json, API key, token, username, private absolute path, or private prompt; example defaults come only from tracked templates and code.

Development workflow

Adding or changing a feature usually follows the path below. Not every step requires a change: a pure copy change touches only i18n, and a pure backend algorithm change may skip the settings page; but every step below must be checked when adding a user-configurable parameter.

flowchart TD
    A["Define the boundary\n(setting / new option / new page / new copy)"] --> B["Config model\ncore/config_models.py or manga_translator/config.py"]
    B --> C["Release template\nconfig/config-example.json"]
    C --> D["Settings mount\nsettings_tab_layout.json"]
    D --> E["Display mapping\napp_logic.py get_display_mapping / get_options_for_key"]
    E --> F["i18n copy\nlocales/en_US.json and zh_CN.json"]
    F --> G["Persistence\nconfig_service.py deep merge + user-config sync"]
    G --> H["Backend consumption\nMangaTranslator or module implementation"]
    H --> I["Tests and verification\ntest/ scripts + language switch + import/export"]
  1. Define the boundary: decide which module the change belongs to — desktop_qt_ui/ (UI and business logic), manga_translator/ (pipeline and algorithms), config/ (release templates), locales/ (copy).
  2. Change the config model: add a field to the matching AppSettings submodel in desktop_qt_ui/core/config_models.py for user-configurable desktop settings, and to the matching Config submodel in manga_translator/config.py for backend runtime configuration. Field names, types, and defaults should stay in sync.
  3. Update the release template: write the new field and its default into config/config-example.json. The desktop startup priority is user config/config.json > config/config-example.json > Qt model defaults (see config_service.py).
  4. Mount the settings page: append the config key to the items list of the matching tab in desktop_qt_ui/ui/main_page/settings_tab_layout.json; tab titles are themselves i18n keys.
  5. Add display mapping: add a key -> label_* mapping to labels in desktop_qt_ui/app_logic.py#get_display_mapping; for dropdowns, also provide options and display names in get_options_for_key / get_display_mapping.
  6. Add i18n copy: add the label_* label and the desc_* description to locales/en_US.json and locales/zh_CN.json (next section). en_US usually uses the English copy itself as the value.
  7. Confirm persistence: config_service.py deep-merges and validates each key against AppSettings; _sync_user_config adds fields that are new in the release template to the user config, removes fields that no longer exist, and preserves user-modified values.
  8. Wire the backend consumer: after manga_translator/config.py reads the new field, manga_translator/manga_translator.py or the relevant module (detection/OCR/translation/inpainting/typesetting/upscaling/colorization) actually consumes it.
  9. Test and verify: write a pytest-style regression script under test/ (first import _bootstrap) and run it with uv run pytest; then manually verify language switching and config import/export.

Adding i18n copy

UI copy goes through the JSON language packs under desktop_qt_ui/locales/. I18nManager.translate(key) returns the key itself when the current pack has no entry (see i18n_service.py), so a new key shows the key string instead of raising an error until it is translated.

Keys come in three common shapes:

  • English sentence as key: menus, buttons, and hints use the English copy directly as the key, for example Settings or Export Config; en_US.json stores the same value as the key and zh_CN.json stores the Chinese.
  • label_*: setting names, bound to config keys via get_display_mapping('labels'), for example label_context_size.
  • desc_*: description-panel text in the form desc_{full_key} (dots become underscores), for example desc_cli_context_size; when missing, the panel shows "No description available."

The language packs are zh_CN, zh_TW, en_US, ja_JP, ko_KR, and es_ES (six in total); the one-time script scripts/add_batch_edit_locale_keys.py demonstrates the batch pattern "add if missing, never touch existing, en_US uses the key itself".

On the wiki side, the i18n evidence catalog doc/wiki/data/i18n.generated.json is generated from the two language packs by doc/wiki/scripts/build-i18n-catalog.mjs (--check detects stale output), and the settings catalog doc/wiki/data/settings.generated.json is generated by doc/wiki/scripts/build-settings-catalog.py from app_logic.py#get_display_mapping, the release template, and the two packs. After editing a language pack, rerun both scripts; never hand-edit the generated JSON.

Constraints and notes

  • When adding a user-configurable parameter, the field names/types in config_models.py and manga_translator/config.py must match, or the value saved by the desktop app may not line up with what the backend reads.
  • Setting labels come from get_display_mapping('labels'); if the mapping is missing, dynamic_settings.py falls back to showing the raw field name (for example min_box_area_ratio) without an error, but the copy is missing.
  • A missing desc_* key does not raise an error; the description panel shows "No description available." (Settings Desc No Description), so both languages should be filled in.
  • A missing i18n key makes translate() return the key itself: this is invisible in en_US (key equals value) but zh_CN will show the raw English key, so check after switching languages.
  • Editing settings_tab_layout.json changes the visible parameter set and grouping of the settings page; the baseline in doc/wiki/data/settings.generated.json is 109 visible fields, so regenerate and recheck after such a change.
  • Do not modify generated files outside doc/wiki/data/ and doc/wiki/scripts/, and never read or commit real .env, user config.json, keys, tokens, or private absolute paths.

Developer Guide

Option matrix

The following copy is directly relevant to this workflow (key → actual en_US value → actual zh_CN value):

UI call keyEnglish actual valueSimplified Chinese actual value
SettingsSettings设置
Settings Page TitleSettings参数设置
Settings Page SubtitleAdjust translation pipeline parameters. Changes are saved automatically.调整翻译流程的各项参数。修改后将自动保存。
Settings Desc HeaderParameter Description参数说明
Settings Desc KeyParameter Key:参数键:
Settings Desc No DescriptionNo description available.暂无说明。
Settings Desc PlaceholderClick any setting on the left to view details点击左侧任意设置项查看详细说明
Export ConfigExport Config导出配置
Import ConfigImport Config导入配置
GeneralGeneral通用
OCROCR文字识别
DetectionDetection检测
TranslationTranslation翻译
InpaintingInpainting修复
TypesettingTypesetting排版
Mode SpecificMode Specific模式相关
&Language&Language&语言
Language:Language:语言:
ApplyApply应用
SaveSave保存
CancelCancel取消
OKOK确定
label_translatorTranslator翻译器
label_context_sizeContext Pages上下文页数
desc_cli_context_sizeTranslation context page count for multi-page joint translation. Larger values improve quality but consume more tokens.翻译上下文页面数,用于多页联合翻译。值越大翻译质量越好,但 token 消耗越多。
label_batch_concurrentConcurrent Batch Processing并发批量处理

Code locations

LayerFileWhat was checked
Config modelsdesktop_qt_ui/core/config_models.py, manga_translator/config.pyAppSettings / Config submodels and defaults
Release templateconfig/config-example.jsonRelease defaults and get_default_config_path usage
Settings UIdesktop_qt_ui/ui/main_page/settings_tab_layout.json, dynamic_settings.py, pages/settings_page.pyTab grouping, parameter rows, description panel, language refresh
Display mappingdesktop_qt_ui/app_logic.pyget_display_mapping, get_options_for_key, _t
i18ndesktop_qt_ui/services/i18n_service.py, locales/en_US.json, zh_CN.jsonSix-locale loading, missing-key fallback, key/actual-value triples
Persistencedesktop_qt_ui/services/config_service.pyPriority loading, per-key validation, user-config sync
Backend consumptionmanga_translator/manga_translator.py, manga_translator/translators/__init__.pyParameters entering the pipeline, translator registration
Test conventionstest/README.md, pyproject.tomlimport _bootstrap, pytest testpaths / pythonpath
Wiki toolingdoc/wiki/scripts/build-i18n-catalog.mjs, build-settings-catalog.pyi18n and settings catalog generation/checks