Factorizer/Cluster ERP WikiCluster ERP Türkçe
Home / Desktop client

Reference

Languages, themes, and accessibility

Reference of the desktop translator, language files, theme engine and tokens, accessibility manager, preferences dialog, and local settings.

This reference describes how the desktop client chooses its language, colours, fonts, and accessibility adjustments, and where it keeps these choices. It covers i18n/translator.py, i18n/en.json, i18n/tr.json, themes/theme_engine.py, themes/style.qss, core/accessibility_manager.py, core/settings_store.py, widgets/preferences_dialog.py, and widgets/accessibility_dialog.py under src/cluster_erp/desktop/. The web client's equivalents are on internationalisation and languages and themes, tokens, and accessibility.

Scope and source

  • Defined in: Translator (src/cluster_erp/desktop/i18n/translator.py:32), ThemeEngine and THEMES (src/cluster_erp/desktop/themes/theme_engine.py:661-881), AccessibilityManager (src/cluster_erp/desktop/core/accessibility_manager.py:207), SettingsStore (src/cluster_erp/desktop/core/settings_store.py:8).
  • Counts: language keys were counted as the top-level keys of each JSON file; theme tokens as the keys of each THEMES palette; stylesheet tokens as the distinct @name placeholders in style.qss, excluding the word in its header comment; icons as the keys of _ICON_PATHS; settings keys by searching for calls of get, set, and remove on the settings store and QSettings.

Language files

File Keys _meta.name Source
en.json 2,077 English src/cluster_erp/desktop/i18n/en.json key _meta.name
tr.json 2,077 Türkçe src/cluster_erp/desktop/i18n/tr.json key _meta.name

Both files have the same key set. The keys are flat strings with a dotted prefix. The largest prefixes are procurement (269 keys), error (177), bom_explorer (174), chat (123), nesting_job (74), resource (58), product (56), purq (54), logs (54), and common (48). The folder also holds an empty file en_keys.txt.

Translator

Member Behaviour Source
constructor Reads the setting language, default tr, loads en.json as the fallback and the chosen file as the main table src/cluster_erp/desktop/i18n/translator.py:35-55
t(key, fallback, **kwargs) Looks up the main table, then metadata labels in the current language or English, then en.json, then the given fallback, then the key itself; fills {name} placeholders src/cluster_erp/desktop/i18n/translator.py:57-67
register_meta(key, translations) Stores a metadata label for t src/cluster_erp/desktop/i18n/translator.py:69-70
set_language(locale) Saves the setting, reloads the table, and emits language_changed src/cluster_erp/desktop/i18n/translator.py:76-80
upper, title Use Turkish dotted and dotless i rules when the language is tr src/cluster_erp/desktop/i18n/translator.py:12-29, src/cluster_erp/desktop/i18n/translator.py:82-90
available_languages() Returns code and _meta.name for every *.json file in the folder src/cluster_erp/desktop/i18n/translator.py:92-99

A new desktop language is a new JSON file in src/cluster_erp/desktop/i18n/. The language selectors of the sign-in dialog and the preferences dialog list every file that available_languages finds (src/cluster_erp/desktop/widgets/login_dialog.py:214-226, src/cluster_erp/desktop/widgets/preferences_dialog.py:62-69). The desktop folder has no languages.json. The API client sends the current language as Accept-Language and follows every change (src/cluster_erp/desktop/main.py:169-172).

Widgets that show translated text connect to Translator.language_changed and set their texts again. For example MainWindow._retranslate_ui renames section tabs (src/cluster_erp/desktop/widgets/main_window.py:64, src/cluster_erp/desktop/widgets/main_window.py:628-648).

Theme engine

ThemeEngine reads the setting theme, default dark, and applies it at once (src/cluster_erp/desktop/themes/theme_engine.py:717-726). Applying a theme does four things (src/cluster_erp/desktop/themes/theme_engine.py:798-848):

  1. It merges the palette with the current overrides from accessibility.
  2. It sets a QPalette for the application from the merged values.
  3. It writes the icon SVG files in the icon colour and the check-box SVG files, only when their colours changed.
  4. It reads style.qss, replaces each @token with its value, longest token name first, sets the stylesheet, and repolishes every widget.

set_overrides waits 150 ms before it applies, so several changes in a row cause one repaint (src/cluster_erp/desktop/themes/theme_engine.py:777-790). toggle switches between light and dark (src/cluster_erp/desktop/themes/theme_engine.py:880-881). current_colors returns the merged palette for widgets that paint themselves (src/cluster_erp/desktop/themes/theme_engine.py:875-878).

Theme tokens

Each palette has 24 keys (src/cluster_erp/desktop/themes/theme_engine.py:661-714). style.qss uses 20 of them plus cb-dir, the folder of the generated check-box images (src/cluster_erp/desktop/themes/theme_engine.py:844).

Token Dark Light In style.qss
window #111113 #FBFBFC yes
base #19191C #FFFFFF yes
alternate-base #232327 #EDEDF0 yes
text #ECECEF #1C1C1E yes
dimmed #87878F #87878F yes
muted #55555C #B0B0B8 yes
accent #4C8EF7 #3E7BFA yes
accent-hover #6BA1F8 #2E6AE6 yes
highlight #2B4A7C #D5E4FD yes
border #2A2A2E #E6E6E9 yes
input #19191C #FFFFFF yes
sidebar #111113 #F0F0F2 no
sidebar-hover #1E1E21 #E6E6E9 no
sidebar-active #252528 #DDDDE0 no
danger #E5484D #E5484D yes
warning #F5A623 #F5A623 yes
success #30A46C #30A46C no
button-gradient #2C2C31 #F4F4F7 yes
button-shadow #18181B #C8C8CC yes
primary-shadow #1E3560 #B0C4E0 yes
font-family "Segoe UI" "Segoe UI" yes
font-size 9pt 9pt yes
font-size-small 8pt 8pt yes
font-size-large 13pt 13pt yes

The four keys marked no are read by widgets through current_colors, for example the sidebar (src/cluster_erp/desktop/widgets/sidebar.py:321-334) and the status bar (src/cluster_erp/desktop/widgets/status_bar.py:76-88).

Icons

_ICON_PATHS holds 123 icon glyphs as SVG path fragments (src/cluster_erp/desktop/themes/theme_engine.py:23-649). The engine writes them as files in a temporary folder in the dimmed colour, and icon(name) loads a file, or returns an empty icon for an unknown name (src/cluster_erp/desktop/themes/theme_engine.py:14, src/cluster_erp/desktop/themes/theme_engine.py:652-654, src/cluster_erp/desktop/themes/theme_engine.py:728-734). Metadata sections and actions name icons by these keys (src/cluster_erp/desktop/widgets/sidebar.py:202-205).

Accessibility settings

AccessibilityManager reads its settings under the prefix accessibility/, computes theme overrides, and emits settings_changed after every change (src/cluster_erp/desktop/core/accessibility_manager.py:195, src/cluster_erp/desktop/core/accessibility_manager.py:207-237). main() applies them before the sign-in dialog (src/cluster_erp/desktop/main.py:164-165).

Setting Values Effect Source
font_scale small, default, large, xlarge Multiplies the 9 pt base font by 0.87, 1.0, 1.13, or 1.27 and scales the three font-size tokens src/cluster_erp/desktop/core/accessibility_manager.py:12-17, src/cluster_erp/desktop/core/accessibility_manager.py:390-397
high_contrast off, light Replaces the palette with a high-contrast light palette src/cluster_erp/desktop/core/accessibility_manager.py:19-39, src/cluster_erp/desktop/core/accessibility_manager.py:406-407
color_blind_mode off, protanopia, deuteranopia, tritanopia Replaces accent, highlight, danger, warning, and success colours src/cluster_erp/desktop/core/accessibility_manager.py:41-66, src/cluster_erp/desktop/core/accessibility_manager.py:409-410
reading_bg off, peach, orange, yellow Tints background colours, with a light and a dark variant each src/cluster_erp/desktop/core/accessibility_manager.py:68-158, src/cluster_erp/desktop/core/accessibility_manager.py:412-415
brightness 50 to 150, default 100 Lightens or darkens nine background keys src/cluster_erp/desktop/core/accessibility_manager.py:161-189, src/cluster_erp/desktop/core/accessibility_manager.py:323-328, src/cluster_erp/desktop/core/accessibility_manager.py:417-423
dyslexia_font true or false Switches to the first installed font of a list, with wider letter and word spacing src/cluster_erp/desktop/core/accessibility_manager.py:192, src/cluster_erp/desktop/core/accessibility_manager.py:360-388
reduced_motion true or false Stored and shown in the dialog src/cluster_erp/desktop/core/accessibility_manager.py:295-298
welcomed set once Hides the welcome banner of the accessibility dialog after the first visit src/cluster_erp/desktop/core/accessibility_manager.py:269-274, src/cluster_erp/desktop/widgets/accessibility_dialog.py:233-234

A stored high-contrast value dark is migrated to light; any other unknown value becomes off (src/cluster_erp/desktop/core/accessibility_manager.py:221-229). reset_all removes the seven adjustable settings and applies the defaults (src/cluster_erp/desktop/core/accessibility_manager.py:330-352). When the theme changes, the overrides are computed again if any adjustment is active (src/cluster_erp/desktop/core/accessibility_manager.py:431-446).

The Accessibility dialog (key accessibility.title) offers segmented controls for font size, high contrast, colour-blind mode, and reading background, a brightness slider from 50 to 150, check boxes for reduced motion and the dyslexia font, and Reset All Settings (key accessibility.reset_all) with a confirmation (src/cluster_erp/desktop/widgets/accessibility_dialog.py:216-400, src/cluster_erp/desktop/widgets/accessibility_dialog.py:477-489). It opens from the sidebar, from the sign-in dialog, and through MainWindow._show_accessibility (src/cluster_erp/desktop/widgets/sidebar.py:129, src/cluster_erp/desktop/widgets/login_dialog.py:230-240, src/cluster_erp/desktop/widgets/main_window.py:614-624).

Preferences dialog

The Preferences dialog (key settings.title) applies each change at once and saves it (src/cluster_erp/desktop/widgets/preferences_dialog.py:37-133):

Control Setting Source
Theme (key settings.theme) theme, through ThemeEngine.apply src/cluster_erp/desktop/widgets/preferences_dialog.py:53-60, src/cluster_erp/desktop/widgets/preferences_dialog.py:102-105
Language (key settings.language) language, through Translator.set_language src/cluster_erp/desktop/widgets/preferences_dialog.py:62-69, src/cluster_erp/desktop/widgets/preferences_dialog.py:107-110
Timezone (key settings.timezone) timezone; an editable list of 16 common zones that exist on the system src/cluster_erp/desktop/widgets/preferences_dialog.py:71-82, src/cluster_erp/desktop/core/timezone_utils.py:8-30
Server URL (key settings.api_url) api_url; a change asks for a restart src/cluster_erp/desktop/widgets/preferences_dialog.py:84-89, src/cluster_erp/desktop/widgets/preferences_dialog.py:117-133

Local settings

SettingsStore wraps QSettings with the organisation ClusterERP and the application DesktopClient, and writes through at once (src/cluster_erp/desktop/core/settings_store.py:8-21). The client uses 16 keys:

Key Written by Source
api_url sign-in dialog, preferences dialog src/cluster_erp/desktop/widgets/login_dialog.py:283, src/cluster_erp/desktop/widgets/preferences_dialog.py:123
server_urls sign-in dialog src/cluster_erp/desktop/widgets/login_dialog.py:282
language Translator.set_language src/cluster_erp/desktop/i18n/translator.py:78
theme ThemeEngine.apply src/cluster_erp/desktop/themes/theme_engine.py:794
timezone preferences dialog src/cluster_erp/desktop/widgets/preferences_dialog.py:112-126
window/geometry, window/state MainWindow.closeEvent src/cluster_erp/desktop/widgets/main_window.py:698-699
panes/layout PaneContainer.save_state src/cluster_erp/desktop/widgets/pane_container.py:28, src/cluster_erp/desktop/widgets/pane_container.py:270
accessibility/font_scale, high_contrast, reduced_motion, dyslexia_font, color_blind_mode, reading_bg, brightness, welcomed AccessibilityManager src/cluster_erp/desktop/core/accessibility_manager.py:207-352

get_user_timezone and BomExplorer read the same store through their own QSettings objects (src/cluster_erp/desktop/core/timezone_utils.py:37-43, src/cluster_erp/desktop/modules/bom/bom_explorer.py:1412-1419).

Constraints and validation

  • Setters ignore values outside their lists, and brightness is clamped to 50 to 150 (src/cluster_erp/desktop/core/accessibility_manager.py:278-328).
  • An unknown time zone name falls back to UTC (src/cluster_erp/desktop/core/timezone_utils.py:37-43).
  • No code outside AccessibilityManager and the accessibility dialog reads reduced_motion, found by searching src/cluster_erp/desktop/ for the name.
  • Desktop language files are also checked by tests outside the desktop folder, for example for the presence of error keys (tests/test_bom_bugfix_batch_2026_10_08.py:123-130).

Discrepancies

Terms introduced

Term Code identifier Definition Turkish term Source
translator Translator The desktop object that loads a language file and resolves keys and metadata labels. çevirmen src/cluster_erp/desktop/i18n/translator.py:32
theme engine ThemeEngine The desktop object that applies a palette, the stylesheet with tokens, and generated icons. tema motoru src/cluster_erp/desktop/themes/theme_engine.py:717
theme token @token A placeholder in style.qss that the theme engine replaces with a palette value. tema belirteci src/cluster_erp/desktop/themes/theme_engine.py:844-846
accessibility manager AccessibilityManager The desktop object that stores accessibility choices and turns them into font changes and theme overrides. erişilebilirlik yöneticisi src/cluster_erp/desktop/core/accessibility_manager.py:207
settings store SettingsStore The wrapper around the local QSettings store of the desktop client. ayar deposu src/cluster_erp/desktop/core/settings_store.py:8

Verified against commit 92f8051 on 2026-11-13.

Verified against commit 92f8051 · 2026-11-13