From 7ad5ee0dffecb20cd3a5f60fc21c9cddf01a441a Mon Sep 17 00:00:00 2001 From: bflatastic Date: Sun, 1 Nov 2026 00:40:20 +0700 Subject: [PATCH] Fix #4931: native Save As Version is a menu of the versions VectorCraft writes --- crates/ui-egui/src/dialogs/save_options.rs | 62 ++++++++++++++++--- .../ui-egui/src/dialogs/save_options/tests.rs | 24 +++++++ crates/ui-egui/src/i18n/bg.tsv | 1 + crates/ui-egui/src/i18n/bs.tsv | 1 + crates/ui-egui/src/i18n/ca.tsv | 1 + crates/ui-egui/src/i18n/cs.tsv | 1 + crates/ui-egui/src/i18n/da.tsv | 1 + crates/ui-egui/src/i18n/de.tsv | 1 + crates/ui-egui/src/i18n/el.tsv | 1 + crates/ui-egui/src/i18n/es.tsv | 1 + crates/ui-egui/src/i18n/fi.tsv | 1 + crates/ui-egui/src/i18n/fr.tsv | 1 + crates/ui-egui/src/i18n/hu.tsv | 1 + crates/ui-egui/src/i18n/id.tsv | 1 + crates/ui-egui/src/i18n/it.tsv | 1 + crates/ui-egui/src/i18n/ja.tsv | 1 + crates/ui-egui/src/i18n/ka.tsv | 1 + crates/ui-egui/src/i18n/ko.tsv | 1 + crates/ui-egui/src/i18n/nl.tsv | 1 + crates/ui-egui/src/i18n/pl.tsv | 1 + crates/ui-egui/src/i18n/pt-br.tsv | 1 + crates/ui-egui/src/i18n/ru.tsv | 1 + crates/ui-egui/src/i18n/sv.tsv | 1 + crates/ui-egui/src/i18n/tr.tsv | 1 + crates/ui-egui/src/i18n/uk.tsv | 1 + crates/ui-egui/src/i18n/vi.tsv | 1 + crates/ui-egui/src/i18n/zh-hans.tsv | 1 + crates/ui-egui/src/i18n/zh-hant.tsv | 1 + 28 files changed, 105 insertions(+), 7 deletions(-) diff --git a/crates/ui-egui/src/dialogs/save_options.rs b/crates/ui-egui/src/dialogs/save_options.rs index cbf450a6a..8ee5de9c9 100644 --- a/crates/ui-egui/src/dialogs/save_options.rs +++ b/crates/ui-egui/src/dialogs/save_options.rs @@ -7,12 +7,13 @@ //! editable), `path`, `format`, and one field per option (agents set them with `ui.dialog.set`). //! Native and `.ai` files show their save options (VectorCraft Options after Save As): each //! artboard to a separate file, with `all` (true: every artboard) or `range`, Include Linked Files, -//! Embed ICC Profiles, Create PDF-Compatible File and Use Compression. A `.ai` file's Version comes -//! first: PDF-compatible, or legacy version 7 (`aiVersion: "7"`, a file per artboard), which takes -//! only Transparent Images (`transparentImages`), Hidden Objects (`hiddenObjects`: a hidden layer, -//! omitted or made visible), Text (`outlineText`: editable or outlines) and, with several -//! artboards, a picker of the artboards to save (thumbnails to check, field `boards`, saved as -//! `range`). +//! Embed ICC Profiles, Create PDF-Compatible File and Use Compression. A native file's Version is a +//! menu of the versions VectorCraft writes (`version`, named by the releases that read each). A +//! `.ai` file's Version comes first: PDF-compatible, or legacy version 7 (`aiVersion: "7"`, a file +//! per artboard), which takes only Transparent Images (`transparentImages`), Hidden Objects +//! (`hiddenObjects`: a hidden layer, omitted or made visible), Text (`outlineText`: editable or +//! outlines) and, with several artboards, a picker of the artboards to save (thumbnails to check, +//! field `boards`, saved as `range`). use std::sync::OnceLock; @@ -342,6 +343,10 @@ fn option_row(app: &VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog, o: &Forma ui.end_row(); return; } + if o.name == "version" && o.ty == "integer" { + native_version(ui, d, o); + return; + } if o.name == "transparentImages" { ui.label(egui::RichText::new(tl!("Transparent Images:")).color(t.text_dim)).on_hover_text(o.description); let choices = [tl!("Flatten"), tl!("Omit")]; @@ -379,7 +384,9 @@ fn option_row(app: &VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog, o: &Forma if o.ty == "boolean" { ui.label(""); let on = value.as_bool().unwrap_or(false); - if widgets::check_tip(ui, label.trim_end_matches(':'), on, true, o.description) { + // Versions older than compression read only plain files. + let enabled = o.name != "compress" || !uncompressed(d); + if widgets::check_tip(ui, label.trim_end_matches(':'), on && enabled, enabled, o.description) { d.fields.insert(o.name.into(), json!(!on)); } ui.end_row(); @@ -412,6 +419,43 @@ fn option_row(app: &VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog, o: &Forma ui.end_row(); } +/// The native versions VectorCraft writes, newest first, each with the first release that reads +/// it (the format version each release tag writes: 2 in 0.1, 3 from 0.2, 4 from 0.8). +const NATIVE_VERSIONS: [(u32, &str); 4] = [(4, "0.8"), (3, "0.2"), (2, "0.1"), (1, "0.1")]; + +/// A native file's Version (#4931): a menu of the versions VectorCraft writes, named by the +/// releases that read them, so a version it can't write can't be chosen. A version without +/// compression turns Use Compression off. +fn native_version(ui: &mut egui::Ui, d: &mut Dialog, o: &FormatOption) { + let t = Tokens::get(ui.ctx()); + ui.label(egui::RichText::new(tl!("Version:")).color(t.text_dim)).on_hover_text(o.description); + let names: Vec = NATIVE_VERSIONS + .iter() + .map(|(n, release)| crate::i18n::fmt(tl!("VectorCraft {release} and later (version {n})"), &[("release", release), ("n", &n.to_string())])) + .collect(); + let names: Vec<&str> = names.iter().map(String::as_str).collect(); + let at = NATIVE_VERSIONS.iter().position(|(n, _)| *n == native_version_of(d)).unwrap_or(0); + if let Some(i) = widgets::dropdown_names(ui, ("save-option", o.name), names.get(at).copied().unwrap_or_default(), &names, 254.0) + && let Some((n, _)) = NATIVE_VERSIONS.get(i) + { + d.fields.insert(o.name.into(), json!(n)); + if *n < vectorcraft_format::COMPRESSED_SINCE { + d.fields.insert("compress".into(), json!(false)); + } + } + ui.end_row(); +} + +/// The native version the dialog will write (the current one unless chosen). +fn native_version_of(d: &Dialog) -> u32 { + d.fields.get("version").and_then(Value::as_u64).and_then(|v| u32::try_from(v).ok()).unwrap_or(vectorcraft_format::VERSION) +} + +/// Is a native file to be saved in a version that can't be compressed? +fn uncompressed(d: &Dialog) -> bool { + native_version_of(d) < vectorcraft_format::COMPRESSED_SINCE +} + /// Web Save As: another format brings its own options and file extension. fn switch_format(app: &mut VectorcraftApp, d: &mut Dialog, id: &str) { let (Some(old), Some(new)) = (fileio::format(&d.str("format")), fileio::format(id)) else { return }; @@ -444,6 +488,10 @@ fn confirm(app: &mut VectorcraftApp, d: &Dialog) -> DialogResult { .iter() .filter_map(|o| d.fields.get(o.name).filter(|v| !v.is_null() && v.as_str() != Some("")).map(|v| (o.name.to_string(), v.clone()))) .collect(); + if uncompressed(d) { + // Use Compression shows off there, whatever it held before. + options.remove("compress"); + } if legacy_ai(d) { // The artboards checked in the picker (all of them: no range). options.remove("range"); diff --git a/crates/ui-egui/src/dialogs/save_options/tests.rs b/crates/ui-egui/src/dialogs/save_options/tests.rs index fe46331a5..9ec00b494 100644 --- a/crates/ui-egui/src/dialogs/save_options/tests.rs +++ b/crates/ui-egui/src/dialogs/save_options/tests.rs @@ -347,3 +347,27 @@ fn eps_save_as_keeps_page_options_and_writes_eps_without_export_only_switches() assert!(vectorcraft_eps::native(&saved[0].1).is_some()); assert_eq!(app.session.active().unwrap().format, "eps"); } + +/// #4931: a native file's Version is a menu of the versions VectorCraft writes, the current one +/// first and chosen, each named by the releases that read it. An older version without +/// compression saves plain, whatever Use Compression held. +#[test] +fn native_version_is_a_menu_of_the_versions_vectorcraft_writes() { + let listed: Vec = NATIVE_VERSIONS.iter().map(|(n, _)| *n).collect(); + let writable: Vec = (vectorcraft_format::MIN_VERSION..=vectorcraft_format::VERSION).rev().collect(); + assert_eq!(listed, writable, "every version VectorCraft writes, newest first"); + let (mut app, written, _) = desktop("art.vectorcraft"); + assert_eq!(app.run("file.saveAs", json!({})).unwrap()["pending"], KIND); + let text = crate::tests_labels::painted_text(&mut app, |app, ui| super::super::show(app, ui.ctx())); + assert!(text.contains("VectorCraft 0.8 and later (version 4)"), "{text}"); + assert_eq!(native_version_of(dialog(&app)), vectorcraft_format::VERSION); + let d = app.ui.dialog.as_mut().unwrap(); + d.fields.insert("version".into(), json!(2)); + d.fields.insert("compress".into(), json!(true)); + assert!(uncompressed(d)); + frame(&mut app, true); + assert!(app.ui.dialog.is_none(), "saved: {}", app.ui.status); + let (_, bytes) = written.borrow()[0].clone(); + let head = String::from_utf8_lossy(&bytes[..bytes.len().min(200)]).to_string(); + assert!(head.contains("\"version\": 2") || head.contains("\"version\":2"), "{head}"); +} diff --git a/crates/ui-egui/src/i18n/bg.tsv b/crates/ui-egui/src/i18n/bg.tsv index 83697b7f3..59c231102 100644 --- a/crates/ui-egui/src/i18n/bg.tsv +++ b/crates/ui-egui/src/i18n/bg.tsv @@ -5926,3 +5926,4 @@ breakText Glyphs Глифи Set Size of Each Задаване на размер на всеки @msg select exactly two objects изберете точно два обекта @msg give `width` or `height` задайте `width` или `height` + VectorCraft {release} and later (version {n}) VectorCraft {release} и по-нови (версия {n}) diff --git a/crates/ui-egui/src/i18n/bs.tsv b/crates/ui-egui/src/i18n/bs.tsv index 3a737414d..571421965 100644 --- a/crates/ui-egui/src/i18n/bs.tsv +++ b/crates/ui-egui/src/i18n/bs.tsv @@ -5960,3 +5960,4 @@ shape Open Otvoren Set Size of Each Postavi veličinu svakog @msg select exactly two objects odaberite tačno dva objekta @msg give `width` or `height` zadajte `width` ili `height` + VectorCraft {release} and later (version {n}) VectorCraft {release} i novije (verzija {n}) diff --git a/crates/ui-egui/src/i18n/ca.tsv b/crates/ui-egui/src/i18n/ca.tsv index c04ca4698..95c59b92c 100644 --- a/crates/ui-egui/src/i18n/ca.tsv +++ b/crates/ui-egui/src/i18n/ca.tsv @@ -6033,3 +6033,4 @@ breakText Glyphs Glifs Set Size of Each Defineix la mida de cadascun @msg select exactly two objects selecciona exactament dos objectes @msg give `width` or `height` indica `width` o `height` + VectorCraft {release} and later (version {n}) VectorCraft {release} i posteriors (versió {n}) diff --git a/crates/ui-egui/src/i18n/cs.tsv b/crates/ui-egui/src/i18n/cs.tsv index 558384bb2..0768ea6c8 100644 --- a/crates/ui-egui/src/i18n/cs.tsv +++ b/crates/ui-egui/src/i18n/cs.tsv @@ -6042,3 +6042,4 @@ breakText Glyphs Glyfy Set Size of Each Nastavit velikost jednotlivě @msg select exactly two objects vyberte právě dva objekty @msg give `width` or `height` zadejte `width` nebo `height` + VectorCraft {release} and later (version {n}) VectorCraft {release} a novější (verze {n}) diff --git a/crates/ui-egui/src/i18n/da.tsv b/crates/ui-egui/src/i18n/da.tsv index 4914683cc..170f4d4b9 100644 --- a/crates/ui-egui/src/i18n/da.tsv +++ b/crates/ui-egui/src/i18n/da.tsv @@ -5940,3 +5940,4 @@ breakText Glyphs Glyffer Set Size of Each Angiv størrelse for hver @msg select exactly two objects markér præcis to objekter @msg give `width` or `height` angiv `width` eller `height` + VectorCraft {release} and later (version {n}) VectorCraft {release} og nyere (version {n}) diff --git a/crates/ui-egui/src/i18n/de.tsv b/crates/ui-egui/src/i18n/de.tsv index aa374c33b..21734d6b4 100644 --- a/crates/ui-egui/src/i18n/de.tsv +++ b/crates/ui-egui/src/i18n/de.tsv @@ -5628,3 +5628,4 @@ breakText Glyphs Glyphen Set Size of Each Größe einzeln festlegen @msg select exactly two objects wählen Sie genau zwei Objekte aus @msg give `width` or `height` geben Sie `width` oder `height` an + VectorCraft {release} and later (version {n}) VectorCraft {release} und neuer (Version {n}) diff --git a/crates/ui-egui/src/i18n/el.tsv b/crates/ui-egui/src/i18n/el.tsv index f1758e7a4..b3b5e9f97 100644 --- a/crates/ui-egui/src/i18n/el.tsv +++ b/crates/ui-egui/src/i18n/el.tsv @@ -5995,3 +5995,4 @@ breakText Glyphs Γλύφοι Set Size of Each Ορισμός μεγέθους καθενός @msg select exactly two objects επιλέξτε ακριβώς δύο αντικείμενα @msg give `width` or `height` δώστε `width` ή `height` + VectorCraft {release} and later (version {n}) VectorCraft {release} και νεότερες (έκδοση {n}) diff --git a/crates/ui-egui/src/i18n/es.tsv b/crates/ui-egui/src/i18n/es.tsv index bc7ddaf56..1e4a8fd9b 100644 --- a/crates/ui-egui/src/i18n/es.tsv +++ b/crates/ui-egui/src/i18n/es.tsv @@ -5985,3 +5985,4 @@ breakText Glyphs Glifos Set Size of Each Definir el tamaño de cada uno @msg select exactly two objects selecciona exactamente dos objetos @msg give `width` or `height` indica `width` o `height` + VectorCraft {release} and later (version {n}) VectorCraft {release} y posteriores (versión {n}) diff --git a/crates/ui-egui/src/i18n/fi.tsv b/crates/ui-egui/src/i18n/fi.tsv index 1d6fd7c02..540800b58 100644 --- a/crates/ui-egui/src/i18n/fi.tsv +++ b/crates/ui-egui/src/i18n/fi.tsv @@ -6073,3 +6073,4 @@ breakText Glyphs Merkit Set Size of Each Aseta kunkin koko @msg select exactly two objects valitse täsmälleen kaksi objektia @msg give `width` or `height` anna `width` tai `height` + VectorCraft {release} and later (version {n}) VectorCraft {release} ja uudemmat (versio {n}) diff --git a/crates/ui-egui/src/i18n/fr.tsv b/crates/ui-egui/src/i18n/fr.tsv index 3e2342133..f171df8db 100644 --- a/crates/ui-egui/src/i18n/fr.tsv +++ b/crates/ui-egui/src/i18n/fr.tsv @@ -6040,3 +6040,4 @@ breakText Glyphs Glyphes Set Size of Each Définir la taille de chaque objet @msg select exactly two objects sélectionnez exactement deux objets @msg give `width` or `height` indiquez `width` ou `height` + VectorCraft {release} and later (version {n}) VectorCraft {release} et ultérieures (version {n}) diff --git a/crates/ui-egui/src/i18n/hu.tsv b/crates/ui-egui/src/i18n/hu.tsv index 10be9ac87..7070071b0 100644 --- a/crates/ui-egui/src/i18n/hu.tsv +++ b/crates/ui-egui/src/i18n/hu.tsv @@ -6029,3 +6029,4 @@ breakText Glyphs Glifák Set Size of Each Egyenkénti méret beállítása @msg select exactly two objects jelölj ki pontosan két objektumot @msg give `width` or `height` add meg a `width` vagy a `height` értéket + VectorCraft {release} and later (version {n}) VectorCraft {release} és újabb (verzió: {n}) diff --git a/crates/ui-egui/src/i18n/id.tsv b/crates/ui-egui/src/i18n/id.tsv index 53927a020..4276a98f2 100644 --- a/crates/ui-egui/src/i18n/id.tsv +++ b/crates/ui-egui/src/i18n/id.tsv @@ -5940,3 +5940,4 @@ breakText Glyphs Glif Set Size of Each Atur ukuran masing-masing @msg select exactly two objects pilih tepat dua objek @msg give `width` or `height` berikan `width` atau `height` + VectorCraft {release} and later (version {n}) VectorCraft {release} dan yang lebih baru (versi {n}) diff --git a/crates/ui-egui/src/i18n/it.tsv b/crates/ui-egui/src/i18n/it.tsv index d48cb24f5..9daf34aec 100644 --- a/crates/ui-egui/src/i18n/it.tsv +++ b/crates/ui-egui/src/i18n/it.tsv @@ -5662,3 +5662,4 @@ breakText Glyphs Glifi Set Size of Each Imposta dimensione di ciascuno @msg select exactly two objects seleziona esattamente due oggetti @msg give `width` or `height` indica `width` o `height` + VectorCraft {release} and later (version {n}) VectorCraft {release} e successive (versione {n}) diff --git a/crates/ui-egui/src/i18n/ja.tsv b/crates/ui-egui/src/i18n/ja.tsv index cd1d86f4d..008940f12 100644 --- a/crates/ui-egui/src/i18n/ja.tsv +++ b/crates/ui-egui/src/i18n/ja.tsv @@ -5728,3 +5728,4 @@ breakText Glyphs 字形 Set Size of Each 個別にサイズを設定 @msg select exactly two objects オブジェクトをちょうど 2 つ選択してください @msg give `width` or `height` `width` または `height` を指定してください + VectorCraft {release} and later (version {n}) VectorCraft {release} 以降 (バージョン {n}) diff --git a/crates/ui-egui/src/i18n/ka.tsv b/crates/ui-egui/src/i18n/ka.tsv index 798b57b0b..a32250773 100644 --- a/crates/ui-egui/src/i18n/ka.tsv +++ b/crates/ui-egui/src/i18n/ka.tsv @@ -6032,3 +6032,4 @@ breakText Glyphs გლიფები Set Size of Each თითოეულის ზომის დაყენება @msg select exactly two objects მონიშნეთ ზუსტად ორი ობიექტი @msg give `width` or `height` მიუთითეთ `width` ან `height` + VectorCraft {release} and later (version {n}) VectorCraft {release} და უფრო ახალი (ვერსია {n}) diff --git a/crates/ui-egui/src/i18n/ko.tsv b/crates/ui-egui/src/i18n/ko.tsv index 38eb0dad0..a2c3ea0e9 100644 --- a/crates/ui-egui/src/i18n/ko.tsv +++ b/crates/ui-egui/src/i18n/ko.tsv @@ -5625,3 +5625,4 @@ breakText Glyphs 글리프 Set Size of Each 각각 크기 설정 @msg select exactly two objects 개체를 정확히 두 개 선택하세요 @msg give `width` or `height` `width` 또는 `height`를 지정하세요 + VectorCraft {release} and later (version {n}) VectorCraft {release} 이상 (버전 {n}) diff --git a/crates/ui-egui/src/i18n/nl.tsv b/crates/ui-egui/src/i18n/nl.tsv index 2a56400a2..26a3a0c49 100644 --- a/crates/ui-egui/src/i18n/nl.tsv +++ b/crates/ui-egui/src/i18n/nl.tsv @@ -5984,3 +5984,4 @@ breakText Glyphs Glyphs Set Size of Each Formaat van elk instellen @msg select exactly two objects selecteer precies twee objecten @msg give `width` or `height` geef `width` of `height` op + VectorCraft {release} and later (version {n}) VectorCraft {release} en nieuwer (versie {n}) diff --git a/crates/ui-egui/src/i18n/pl.tsv b/crates/ui-egui/src/i18n/pl.tsv index 1b8e322eb..7a71813b0 100644 --- a/crates/ui-egui/src/i18n/pl.tsv +++ b/crates/ui-egui/src/i18n/pl.tsv @@ -5898,3 +5898,4 @@ breakText Glyphs Glify Set Size of Each Ustaw rozmiar każdego @msg select exactly two objects zaznacz dokładnie dwa obiekty @msg give `width` or `height` podaj `width` lub `height` + VectorCraft {release} and later (version {n}) VectorCraft {release} i nowsze (wersja {n}) diff --git a/crates/ui-egui/src/i18n/pt-br.tsv b/crates/ui-egui/src/i18n/pt-br.tsv index f64b2436d..e20611488 100644 --- a/crates/ui-egui/src/i18n/pt-br.tsv +++ b/crates/ui-egui/src/i18n/pt-br.tsv @@ -5962,3 +5962,4 @@ breakText Glyphs Glifos Set Size of Each Definir Tamanho de Cada Um @msg select exactly two objects selecione exatamente dois objetos @msg give `width` or `height` informe `width` ou `height` + VectorCraft {release} and later (version {n}) VectorCraft {release} e posteriores (versão {n}) diff --git a/crates/ui-egui/src/i18n/ru.tsv b/crates/ui-egui/src/i18n/ru.tsv index 816096e51..414f43d29 100644 --- a/crates/ui-egui/src/i18n/ru.tsv +++ b/crates/ui-egui/src/i18n/ru.tsv @@ -6020,3 +6020,4 @@ breakText Glyphs Глифы Set Size of Each Задать размер каждого @msg select exactly two objects выделите ровно два объекта @msg give `width` or `height` укажите `width` или `height` + VectorCraft {release} and later (version {n}) VectorCraft {release} и новее (версия {n}) diff --git a/crates/ui-egui/src/i18n/sv.tsv b/crates/ui-egui/src/i18n/sv.tsv index 46e4bd844..46d0eb226 100644 --- a/crates/ui-egui/src/i18n/sv.tsv +++ b/crates/ui-egui/src/i18n/sv.tsv @@ -6095,3 +6095,4 @@ breakText Glyphs Glyfer Set Size of Each Ange storlek för vart och ett @msg select exactly two objects markera exakt två objekt @msg give `width` or `height` ange `width` eller `height` + VectorCraft {release} and later (version {n}) VectorCraft {release} och senare (version {n}) diff --git a/crates/ui-egui/src/i18n/tr.tsv b/crates/ui-egui/src/i18n/tr.tsv index 1c2feb846..c40b948f1 100644 --- a/crates/ui-egui/src/i18n/tr.tsv +++ b/crates/ui-egui/src/i18n/tr.tsv @@ -6000,3 +6000,4 @@ breakText Glyphs Glifler Set Size of Each Her Birinin Boyutunu Ayarla @msg select exactly two objects tam olarak iki nesne seç @msg give `width` or `height` `width` veya `height` belirt + VectorCraft {release} and later (version {n}) VectorCraft {release} ve sonrası (sürüm {n}) diff --git a/crates/ui-egui/src/i18n/uk.tsv b/crates/ui-egui/src/i18n/uk.tsv index 05f4ffe48..e92094241 100644 --- a/crates/ui-egui/src/i18n/uk.tsv +++ b/crates/ui-egui/src/i18n/uk.tsv @@ -5642,3 +5642,4 @@ breakText Glyphs Гліфи Set Size of Each Задати розмір кожного @msg select exactly two objects виділіть рівно два об’єкти @msg give `width` or `height` укажіть `width` або `height` + VectorCraft {release} and later (version {n}) VectorCraft {release} і новіші (версія {n}) diff --git a/crates/ui-egui/src/i18n/vi.tsv b/crates/ui-egui/src/i18n/vi.tsv index b2744f443..44fffd0ce 100644 --- a/crates/ui-egui/src/i18n/vi.tsv +++ b/crates/ui-egui/src/i18n/vi.tsv @@ -5644,3 +5644,4 @@ breakText Glyphs Glyph Set Size of Each Đặt kích thước từng cái @msg select exactly two objects hãy chọn đúng hai đối tượng @msg give `width` or `height` hãy cho `width` hoặc `height` + VectorCraft {release} and later (version {n}) VectorCraft {release} trở lên (phiên bản {n}) diff --git a/crates/ui-egui/src/i18n/zh-hans.tsv b/crates/ui-egui/src/i18n/zh-hans.tsv index cfea6e224..cb2d7558b 100644 --- a/crates/ui-egui/src/i18n/zh-hans.tsv +++ b/crates/ui-egui/src/i18n/zh-hans.tsv @@ -5884,3 +5884,4 @@ breakText Glyphs 字形 Set Size of Each 分别设置大小 @msg select exactly two objects 请恰好选择两个对象 @msg give `width` or `height` 请提供 `width` 或 `height` + VectorCraft {release} and later (version {n}) VectorCraft {release} 及更高版本 (版本 {n}) diff --git a/crates/ui-egui/src/i18n/zh-hant.tsv b/crates/ui-egui/src/i18n/zh-hant.tsv index 0605652e5..31a2d1dbe 100644 --- a/crates/ui-egui/src/i18n/zh-hant.tsv +++ b/crates/ui-egui/src/i18n/zh-hant.tsv @@ -5681,3 +5681,4 @@ breakText Glyphs 字符 Set Size of Each 個別設定大小 @msg select exactly two objects 請選取正好兩個物件 @msg give `width` or `height` 請提供 `width` 或 `height` + VectorCraft {release} and later (version {n}) VectorCraft {release} 及更新版本 (版本 {n})