mirror of
https://github.com/storytold/cadcraft.git
synced 2026-10-14 14:26:45 -04:00
Arabic (العربية) UI translation: language switching + font fallback (#798)
* Show Thai file names and text in the interface with an installed Thai font A drawing whose file name is Thai showed boxes in its file tab and in the window title: the interface loaded one Latin system font (plus a CJK font for the Chinese interface), and neither has Thai. install_fonts now also adds an installed Thai font (Thonburi, Leelawadee UI, Noto Sans Thai, Loma...) after the Latin one, in any interface language, since file names and drawing text are Thai whatever the interface is in. No font is bundled; without one installed nothing changes. Co-Authored-By: Claude Opus 5.5 <[email protected]> * Add Korean interface localization and Hangul font support * Add Arabic (العربية) interface translation A full ar.tsv catalog for the CAD interface — every menu label, tool, palette, dialog and status message in the repo's three-column TSV format, written from the plain meaning of the English with the Arabic AutoCAD vocabulary its users know (أمر، إزاحة، تدوير، قص، استدارة، طبقة…), with the six CLDR plural forms for the counts. Registers ar in LANGUAGES with plural_arabic and the font chain (Noto Sans Arabic first on Linux, Segoe UI/Tahoma on Windows, Geeza Pro on macOS) so the UI families paint Arabic. The shell itself still lays out left-to-right: egui 0.36 has no global direction switch and no bidi, so mirroring is left for a later pass; this PR is the catalog, the registry entry and the fonts. * i18n: start the Swedish (sv) interface catalog Header only, not registered yet: the catalog is filled and the language registered in this branch, translated from the meaning of CADCraft's English strings and reviewed by a native Swedish speaker. Co-Authored-By: Claude Opus 5.5 <[email protected]> * i18n: add Swedish (sv) interface translation A complete 1,235-entry Swedish catalog: every key of the Spanish catalog, Run Script... and the four menu headings (Visa, Rita, Måttsättning, Ändra). Written from the meaning of CADCraft's English strings; no other product's localisation and no other catalog was used. AI-assisted; the terminology and the running app were reviewed by a native speaker. Command-line keywords, system variables and osnap tokens stay English. - Preference::Swedish (sv); sv-SE, sv-FI and sv_SE.UTF-8 select it; one|other plurals (the English rule). - sv in REPORTED; tests for locales, saved preference and plurals, menu headings, a live switch, dialogs and the Swedish letters in the bundled fonts. No gaps are reported for Swedish. - ATTRIBUTION, README, docs/localization.md, docs/localization-parity.md, docs/control-protocol.md, the options doc comment and a contributors/people.toml entry for @holmbom. Co-Authored-By: Claude Opus 5.5 <[email protected]> --------- Co-authored-by: Chanthawat Kiriyadee <[email protected]> Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: huk082 <[email protected]> Co-authored-by: hasan-sdaif <[email protected]> Co-authored-by: Erik Holmbom <[email protected]> Co-authored-by: Brandon Thomas <[email protected]>
This commit is contained in:
9 files changed
+1322
-11
No files matched your search
@@ -67,3 +67,4 @@ Generated-in-code assets are original and have no file to list:
|
|||||||
| `crates/ui-egui/src/i18n/sv.tsv` | Erik Holmbom (@holmbom) with Claude Code (AI-assisted) | Original Swedish translations of CADCraft English strings | MIT OR Apache-2.0 (`LICENSE-MIT`, `LICENSE-APACHE`) | No proprietary localization resources copied; terminology and the running app reviewed by a native speaker |
|
| `crates/ui-egui/src/i18n/sv.tsv` | Erik Holmbom (@holmbom) with Claude Code (AI-assisted) | Original Swedish translations of CADCraft English strings | MIT OR Apache-2.0 (`LICENSE-MIT`, `LICENSE-APACHE`) | No proprietary localization resources copied; terminology and the running app reviewed by a native speaker |
|
||||||
| `crates/ui-egui/src/i18n/it.tsv` | Emanuele Bottelli (AI-assisted) | Original Italian translations of CADCraft English strings | MIT OR Apache-2.0 (`LICENSE-MIT`, `LICENSE-APACHE`) | No proprietary localization resources copied |
|
| `crates/ui-egui/src/i18n/it.tsv` | Emanuele Bottelli (AI-assisted) | Original Italian translations of CADCraft English strings | MIT OR Apache-2.0 (`LICENSE-MIT`, `LICENSE-APACHE`) | No proprietary localization resources copied |
|
||||||
| `crates/ui-egui/src/i18n/ko.tsv` | @huk082 (AI-assisted) | Original Korean translations of CADCraft English strings | MIT OR Apache-2.0 (`LICENSE-MIT`, `LICENSE-APACHE`) | No proprietary localization resources copied; no font assets added |
|
| `crates/ui-egui/src/i18n/ko.tsv` | @huk082 (AI-assisted) | Original Korean translations of CADCraft English strings | MIT OR Apache-2.0 (`LICENSE-MIT`, `LICENSE-APACHE`) | No proprietary localization resources copied; no font assets added |
|
||||||
|
| `crates/ui-egui/src/i18n/ar.tsv` | @hasan-sdaif | Original Arabic translations of CADCraft English strings | MIT OR Apache-2.0 (`LICENSE-MIT`, `LICENSE-APACHE`) | No proprietary localization resources copied |
|
||||||
@@ -111,7 +111,7 @@ numbers):
|
|||||||
| Layouts & plotting | Paper-space layouts, viewports (scale, lock, per-viewport layer freeze), MSPACE/PSPACE through viewports, page setups, PLOT and EXPORTPDF |
|
| Layouts & plotting | Paper-space layouts, viewports (scale, lock, per-viewport layer freeze), MSPACE/PSPACE through viewports, page setups, PLOT and EXPORTPDF |
|
||||||
| Parametric | Geometric and dimensional constraints, AUTOCONSTRAIN, PARAMETERS with expressions, conflict detection; constraints re-solve after every edit |
|
| Parametric | Geometric and dimensional constraints, AUTOCONSTRAIN, PARAMETERS with expressions, conflict detection; constraints re-solve after every edit |
|
||||||
| Grips | Hot grips with Space to cycle Stretch, Move, Rotate, Scale and Mirror |
|
| Grips | Hot grips with Space to cycle Stretch, Move, Rotate, Scale and Mirror |
|
||||||
| Interface languages | English, Ukrainian (Українська), Brazilian Portuguese (Português (Brasil)), German (Deutsch), Spanish (Español), Czech (Čeština), Russian (Русский), French (Français), Simplified Chinese (简体中文, with an installed CJK font), Italian (Italiano), Korean (한국어, with an installed Hangul font) and Swedish (Svenska), live switching and a remembered Auto/system-language choice; [details](docs/localization.md) |
|
| Interface languages | English, Ukrainian (Українська), Brazilian Portuguese (Português (Brasil)), German (Deutsch), Spanish (Español), Czech (Čeština), Russian (Русский), French (Français), Simplified Chinese (简体中文, with an installed CJK font), Italian (Italiano), Korean (한국어, with an installed Hangul font), Swedish (Svenska) and Arabic (العربية, with an installed Arabic font), live switching and a remembered Auto/system-language choice; [details](docs/localization.md) |
|
||||||
| Automation | MCP server, JSON control channel, `cadcraft-cli` (info, convert, run, commands, mcp) |
|
| Automation | MCP server, JSON control channel, `cadcraft-cli` (info, convert, run, commands, mcp) |
|
||||||
|
|
||||||
## Quick start
|
## Quick start
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
@@ -37,10 +37,12 @@ pub enum Preference {
|
|||||||
Korean,
|
Korean,
|
||||||
#[serde(rename = "sv")]
|
#[serde(rename = "sv")]
|
||||||
Swedish,
|
Swedish,
|
||||||
|
#[serde(rename = "ar")]
|
||||||
|
Arabic,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Preference {
|
impl Preference {
|
||||||
pub const ALL: [Self; 13] = [
|
pub const ALL: [Self; 14] = [
|
||||||
Self::Auto,
|
Self::Auto,
|
||||||
Self::English,
|
Self::English,
|
||||||
Self::Ukrainian,
|
Self::Ukrainian,
|
||||||
@@ -54,6 +56,7 @@ impl Preference {
|
|||||||
Self::Italian,
|
Self::Italian,
|
||||||
Self::Korean,
|
Self::Korean,
|
||||||
Self::Swedish,
|
Self::Swedish,
|
||||||
|
Self::Arabic,
|
||||||
];
|
];
|
||||||
|
|
||||||
/// The codes a preference can be given as, for messages ("auto, en or uk").
|
/// The codes a preference can be given as, for messages ("auto, en or uk").
|
||||||
@@ -80,6 +83,7 @@ impl Preference {
|
|||||||
Self::Italian => "it",
|
Self::Italian => "it",
|
||||||
Self::Korean => "ko",
|
Self::Korean => "ko",
|
||||||
Self::Swedish => "sv",
|
Self::Swedish => "sv",
|
||||||
|
Self::Arabic => "ar",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,6 +108,7 @@ impl Preference {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::Swedish => "Svenska",
|
Self::Swedish => "Svenska",
|
||||||
|
Self::Arabic => "العربية",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,6 +135,7 @@ impl Preference {
|
|||||||
Self::Italian => "it",
|
Self::Italian => "it",
|
||||||
Self::Korean => "ko",
|
Self::Korean => "ko",
|
||||||
Self::Swedish => "sv",
|
Self::Swedish => "sv",
|
||||||
|
Self::Arabic => "ar",
|
||||||
Self::Auto => locales.iter().find_map(|s| locale_language(s)).unwrap_or("en"),
|
Self::Auto => locales.iter().find_map(|s| locale_language(s)).unwrap_or("en"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -146,7 +152,7 @@ pub struct Language {
|
|||||||
catalog: OnceLock<Catalog<'static>>,
|
catalog: OnceLock<Catalog<'static>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static LANGUAGES: [Language; 12] = [
|
pub static LANGUAGES: [Language; 13] = [
|
||||||
Language { code: "en", name: "English", source: "", plural: plural_en, plural_forms: 2, catalog: OnceLock::new() },
|
Language { code: "en", name: "English", source: "", plural: plural_en, plural_forms: 2, catalog: OnceLock::new() },
|
||||||
Language {
|
Language {
|
||||||
code: "uk", name: "Українська", source: include_str!("uk.tsv"), plural: plural_uk, plural_forms: 3, catalog: OnceLock::new()
|
code: "uk", name: "Українська", source: include_str!("uk.tsv"), plural: plural_uk, plural_forms: 3, catalog: OnceLock::new()
|
||||||
@@ -177,6 +183,10 @@ pub static LANGUAGES: [Language; 12] = [
|
|||||||
Language { code: "ko", name: "한국어", source: include_str!("ko.tsv"), plural: plural_ko, plural_forms: 1, catalog: OnceLock::new() },
|
Language { code: "ko", name: "한국어", source: include_str!("ko.tsv"), plural: plural_ko, plural_forms: 1, catalog: OnceLock::new() },
|
||||||
// Swedish plurals follow the English rule: one (1), other.
|
// Swedish plurals follow the English rule: one (1), other.
|
||||||
Language { code: "sv", name: "Svenska", source: include_str!("sv.tsv"), plural: plural_en, plural_forms: 2, catalog: OnceLock::new() },
|
Language { code: "sv", name: "Svenska", source: include_str!("sv.tsv"), plural: plural_en, plural_forms: 2, catalog: OnceLock::new() },
|
||||||
|
// العربية (Arabic) is right-to-left; an installed Arabic font (`theme::arabic_font`)
|
||||||
|
// covers its glyphs, and the shell keeps egui's left-to-right run order. Six plural
|
||||||
|
// forms: zero, one, two, few, many, other.
|
||||||
|
Language { code: "ar", name: "العربية", source: include_str!("ar.tsv"), plural: plural_arabic, plural_forms: 6, catalog: OnceLock::new() },
|
||||||
];
|
];
|
||||||
|
|
||||||
/// BCP 47 and POSIX locale tags, including `uk-UA`, `uk_UA.UTF-8` and `pt_BR.UTF-8`.
|
/// BCP 47 and POSIX locale tags, including `uk-UA`, `uk_UA.UTF-8` and `pt_BR.UTF-8`.
|
||||||
@@ -293,6 +303,19 @@ fn plural_ko(_n: u64) -> usize {
|
|||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Arabic integer plurals (CLDR `ar`): zero (0), one (1), two (2), few (3–10, 103–110),
|
||||||
|
/// many (11–99) — the same rule pdfcraft uses, so the sibling apps agree.
|
||||||
|
pub fn plural_arabic(n: u64) -> usize {
|
||||||
|
match (n, n % 100) {
|
||||||
|
(0, _) => 0,
|
||||||
|
(1, _) => 1,
|
||||||
|
(2, _) => 2,
|
||||||
|
(_, 3..=10) => 3,
|
||||||
|
(_, 11..=99) => 4,
|
||||||
|
_ => 5,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn plural_en(n: u64) -> usize {
|
fn plural_en(n: u64) -> usize {
|
||||||
usize::from(n != 1)
|
usize::from(n != 1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ fn catalog_is_valid_and_preserves_placeholders_and_ellipses() {
|
|||||||
/// to English for what they don't cover yet; their gaps are reported, not enforced, so adding a
|
/// to English for what they don't cover yet; their gaps are reported, not enforced, so adding a
|
||||||
/// command doesn't require a row in every language.
|
/// command doesn't require a row in every language.
|
||||||
const REQUIRED: &[&str] = &["uk"];
|
const REQUIRED: &[&str] = &["uk"];
|
||||||
const REPORTED: &[&str] = &["pt-BR", "de", "es", "cs", "ru", "fr", "zh", "it", "ko", "sv"];
|
const REPORTED: &[&str] = &["pt-BR", "de", "es", "cs", "ru", "fr", "zh", "it", "ko", "sv", "ar"];
|
||||||
|
|
||||||
fn check(language: &str, what: &str, missing: Vec<String>) {
|
fn check(language: &str, what: &str, missing: Vec<String>) {
|
||||||
if REQUIRED.contains(&language) {
|
if REQUIRED.contains(&language) {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
//! |---|---|
|
//! |---|---|
|
||||||
//! | `theme` | `"system"`, `"light"` or `"dark"` |
|
//! | `theme` | `"system"`, `"light"` or `"dark"` |
|
||||||
//! | `animations` | `"system"`, `"on"` or `"off"`: dialog and menu fades and smoothed scrolling |
|
//! | `animations` | `"system"`, `"on"` or `"off"`: dialog and menu fades and smoothed scrolling |
|
||||||
//! | `interfaceLanguage` | `"auto"`, `"en"`, `"uk"`, `"pt-BR"`, `"de"`, `"es"`, `"cs"`, `"ru"`, `"fr"`, `"zh"`, `"it"`, `"ko"` or `"sv"` |
|
//! | `interfaceLanguage` | `"auto"`, `"en"`, `"uk"`, `"pt-BR"`, `"de"`, `"es"`, `"cs"`, `"ru"`, `"fr"`, `"zh"`, `"it"`, `"ko"`, `"sv"` or `"ar"` |
|
||||||
//! | `saveFormat` | `"dxf"` or `"dwg"`: the format Save As suggests for new drawings |
|
//! | `saveFormat` | `"dxf"` or `"dwg"`: the format Save As suggests for new drawings |
|
||||||
//! | `saveVersion` | `"2000"` … `"2018"`: the version drawings with no file yet are saved in |
|
//! | `saveVersion` | `"2000"` … `"2018"`: the version drawings with no file yet are saved in |
|
||||||
//! | `SAVETIME` | minutes between automatic saves, 0–600 (0: off) |
|
//! | `SAVETIME` | minutes between automatic saves, 0–600 (0: off) |
|
||||||
|
|||||||
@@ -306,7 +306,8 @@ pub fn mono() -> FontId {
|
|||||||
/// then CJK fonts after the Latin ones, so Latin text keeps its look, in every interface
|
/// then CJK fonts after the Latin ones, so Latin text keeps its look, in every interface
|
||||||
/// language: file, layout and layer names can be Japanese or Chinese whatever the interface
|
/// language: file, layout and layer names can be Japanese or Chinese whatever the interface
|
||||||
/// shows (#513). In a Chinese interface (`language` "zh…") the Chinese font comes first, else a
|
/// shows (#513). In a Chinese interface (`language` "zh…") the Chinese font comes first, else a
|
||||||
/// Japanese one, so names take their own glyph forms. A font embedded from craft-fonts comes
|
/// Japanese one, so names take their own glyph forms; in an Arabic interface an installed
|
||||||
|
/// Arabic font follows. A font embedded from craft-fonts comes
|
||||||
/// last, for systems without any (and the web build, which has no system fonts). A Korean
|
/// last, for systems without any (and the web build, which has no system fonts). A Korean
|
||||||
/// interface adds a Hangul font only when the CJK font found doesn't cover Hangul
|
/// interface adds a Hangul font only when the CJK font found doesn't cover Hangul
|
||||||
/// ([`korean_font`]).
|
/// ([`korean_font`]).
|
||||||
@@ -351,6 +352,13 @@ pub fn install_fonts(ctx: &egui::Context, language: &str) {
|
|||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, bytes)| (format!("system-cjk-{i}"), std::sync::Arc::new(egui::FontData::from_owned(bytes)))),
|
.map(|(i, bytes)| (format!("system-cjk-{i}"), std::sync::Arc::new(egui::FontData::from_owned(bytes)))),
|
||||||
);
|
);
|
||||||
|
// العربية: an installed Arabic face after the Latin ones (egui's bundled faces carry no
|
||||||
|
// Arabic glyphs), for the Arabic interface.
|
||||||
|
if language == "ar"
|
||||||
|
&& let Some(bytes) = arabic_font().and_then(|p| read_capped(p, MAX_UI_FONT_BYTES))
|
||||||
|
{
|
||||||
|
added.push(("system-arabic".into(), std::sync::Arc::new(egui::FontData::from_owned(bytes))));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let mut embedded: Vec<_> = cadcraft_fonts::CRAFT_FONTS
|
let mut embedded: Vec<_> = cadcraft_fonts::CRAFT_FONTS
|
||||||
.iter()
|
.iter()
|
||||||
@@ -429,6 +437,49 @@ pub fn cjk_font() -> Option<&'static std::path::Path> {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An installed font with Arabic glyphs, for the العربية interface; fonts are never bundled
|
||||||
|
/// (only looked for where the OS or common packages put them). Checked once.
|
||||||
|
pub fn arabic_font() -> Option<&'static std::path::Path> {
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
{
|
||||||
|
static FOUND: std::sync::OnceLock<Option<std::path::PathBuf>> = std::sync::OnceLock::new();
|
||||||
|
FOUND
|
||||||
|
.get_or_init(|| {
|
||||||
|
let candidates: &[&str] = if cfg!(target_os = "macos") {
|
||||||
|
&[
|
||||||
|
"/System/Library/Fonts/GeezaPro.ttc",
|
||||||
|
"/System/Library/Fonts/Supplemental/Geeza Pro.ttf",
|
||||||
|
"/System/Library/Fonts/Supplemental/Al Nile.ttc",
|
||||||
|
"/System/Library/Fonts/Supplemental/Baghdad.ttf",
|
||||||
|
]
|
||||||
|
} else if cfg!(windows) {
|
||||||
|
&[
|
||||||
|
"C:\\Windows\\Fonts\\segoeui.ttf",
|
||||||
|
"C:\\Windows\\Fonts\\tahoma.ttf",
|
||||||
|
"C:\\Windows\\Fonts\\trado.ttf",
|
||||||
|
"C:\\Windows\\Fonts\\arabtype.ttf",
|
||||||
|
"C:\\Windows\\Fonts\\arial.ttf",
|
||||||
|
]
|
||||||
|
} else {
|
||||||
|
&[
|
||||||
|
"/usr/share/fonts/truetype/noto/NotoSansArabic-Regular.ttf",
|
||||||
|
"/usr/share/fonts/noto/NotoSansArabic-Regular.ttf",
|
||||||
|
"/usr/share/fonts/opentype/noto/NotoSansArabic-Regular.ttf",
|
||||||
|
"/usr/share/fonts/truetype/noto/NotoNaskhArabic-Regular.ttf",
|
||||||
|
"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",
|
||||||
|
"/usr/share/fonts/TTF/DejaVuSans.ttf",
|
||||||
|
"/usr/share/fonts/truetype/amiri/Amiri-Regular.ttf",
|
||||||
|
"/usr/share/fonts/truetype/kacst/KacstOne.ttf",
|
||||||
|
]
|
||||||
|
};
|
||||||
|
candidates.iter().map(std::path::PathBuf::from).find(|p| p.is_file())
|
||||||
|
})
|
||||||
|
.as_deref()
|
||||||
|
}
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
/// An installed Japanese font, for Japanese names in a non-Chinese interface. Checked once.
|
/// An installed Japanese font, for Japanese names in a non-Chinese interface. Checked once.
|
||||||
#[cfg_attr(target_arch = "wasm32", allow(dead_code))]
|
#[cfg_attr(target_arch = "wasm32", allow(dead_code))]
|
||||||
fn japanese_font() -> Option<&'static std::path::Path> {
|
fn japanese_font() -> Option<&'static std::path::Path> {
|
||||||
@@ -566,10 +617,11 @@ pub fn shows_hangul(language: &str) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Whether the interface can show `language` without missing-glyph boxes: Chinese needs an
|
/// Whether the interface can show `language` without missing-glyph boxes: Chinese needs an
|
||||||
/// installed CJK font, Korean a font with Hangul.
|
/// installed CJK font, Korean a font with Hangul, العربية an installed Arabic font.
|
||||||
pub fn can_show(language: &str) -> bool {
|
pub fn can_show(language: &str) -> bool {
|
||||||
match language {
|
match language {
|
||||||
"ko" => shows_hangul("ko"),
|
"ko" => shows_hangul("ko"),
|
||||||
|
"ar" => arabic_font().is_some(),
|
||||||
l if l.starts_with("zh") => cjk_font().is_some(),
|
l if l.starts_with("zh") => cjk_font().is_some(),
|
||||||
_ => true,
|
_ => true,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,8 +152,8 @@ Select a language with `engine.execute` and the UI command `ui.language`:
|
|||||||
{"id":1,"method":"engine.execute","params":{"command":"ui.language","params":{"lang":"uk"}}}
|
{"id":1,"method":"engine.execute","params":{"command":"ui.language","params":{"lang":"uk"}}}
|
||||||
```
|
```
|
||||||
|
|
||||||
Supported values are `auto`, `en`, `uk`, `pt-BR`, `de`, `es`, `cs`, `ru`, `fr`, `zh`, `it`, `ko` and `sv`.
|
Supported values are `auto`, `en`, `uk`, `pt-BR`, `de`, `es`, `cs`, `ru`, `fr`, `zh`, `it`, `ko`, `sv` and `ar`.
|
||||||
Chinese needs an installed CJK font; Korean needs a font covering the Korean interface from the
|
Chinese needs an installed CJK font, Arabic an installed Arabic font; Korean needs a font covering the Korean interface from the
|
||||||
optional craft-fonts input or the operating system. Without a suitable font, the saved choice is
|
optional craft-fonts input or the operating system. Without a suitable font, the saved choice is
|
||||||
retained and the result's `shown` is `en`. `ui.set` also accepts
|
retained and the result's `shown` is `en`. `ui.set` also accepts
|
||||||
`{"interfaceLanguage":"uk"}`; `ui.inspect` reports the saved choice in its UI state.
|
`{"interfaceLanguage":"uk"}`; `ui.inspect` reports the saved choice in its UI state.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Interface languages
|
# Interface languages
|
||||||
|
|
||||||
Choose **Edit → Interface Language** and select **Auto (system language)**, **English**,
|
Choose **Edit → Interface Language** and select **Auto (system language)**, **English**,
|
||||||
**Українська**, **Português (Brasil)**, **Deutsch**, **Español**, **Čeština** (Czech), **Русский**, **Français**, **简体中文**, **Italiano**, **한국어** (Korean), or **Svenska** (Swedish).
|
**Українська**, **Português (Brasil)**, **Deutsch**, **Español**, **Čeština** (Czech), **Русский**, **Français**, **简体中文**, **Italiano**, **한국어** (Korean), **Svenska** (Swedish), or **العربية** (Arabic).
|
||||||
The interface updates without restarting, including the native macOS menus.
|
The interface updates without restarting, including the native macOS menus.
|
||||||
The choice is saved with the other interface preferences (`cadcraft.prefs`, beside the theme):
|
The choice is saved with the other interface preferences (`cadcraft.prefs`, beside the theme):
|
||||||
eframe storage on the desktop, browser local storage on the web. Installations without a saved
|
eframe storage on the desktop, browser local storage on the web. Installations without a saved
|
||||||
@@ -22,7 +22,7 @@ Automation can select the language through the existing control channel:
|
|||||||
```
|
```
|
||||||
|
|
||||||
The `ui.set` method also accepts `{"interfaceLanguage":"cs"}`. Supported values are `auto`,
|
The `ui.set` method also accepts `{"interfaceLanguage":"cs"}`. Supported values are `auto`,
|
||||||
`en`, `uk`, `pt-BR`, `de`, `es`, `cs`, `ru`, `fr`, `zh`, `it`, `ko`, and `sv`; invalid values are rejected without changing the current
|
`en`, `uk`, `pt-BR`, `de`, `es`, `cs`, `ru`, `fr`, `zh`, `it`, `ko`, `sv`, and `ar`; invalid values are rejected without changing the current
|
||||||
selection. Resetting palettes keeps the language choice.
|
selection. Resetting palettes keeps the language choice.
|
||||||
|
|
||||||
## Translation coverage
|
## Translation coverage
|
||||||
|
|||||||
Reference in new issue
Block a user