From 1be658c88cd6cedd4e0bf685b976451a2e7cd0da Mon Sep 17 00:00:00 2001 From: dotCooCoo Date: Sun, 1 Nov 2026 06:58:18 -0800 Subject: [PATCH] Variables: Export Data Sets refuses more data sets or variables than Import Data Sets reads dataset.export checked only the 1 MiB size, so a document with more than 1000 data sets or 256 variables exported a CSV that dataset.import then refused. Export now refuses such a document with a message naming the limit, and the messages have rows in every complete-message catalog. --- crates/engine/src/cmd/variablecmds.rs | 2 +- crates/engine/src/cmd/variablecmds/csv.rs | 8 ++++++ crates/engine/src/tests/variables.rs | 27 +++++++++++++++++++ crates/ui-egui/src/i18n/ca.tsv | 2 ++ crates/ui-egui/src/i18n/cs.tsv | 2 ++ crates/ui-egui/src/i18n/de.tsv | 2 ++ crates/ui-egui/src/i18n/el.tsv | 2 ++ crates/ui-egui/src/i18n/es.tsv | 2 ++ crates/ui-egui/src/i18n/fi.tsv | 2 ++ crates/ui-egui/src/i18n/fr.tsv | 2 ++ crates/ui-egui/src/i18n/hu.tsv | 2 ++ crates/ui-egui/src/i18n/it.tsv | 2 ++ crates/ui-egui/src/i18n/ja.tsv | 2 ++ crates/ui-egui/src/i18n/ka.tsv | 2 ++ crates/ui-egui/src/i18n/ko.tsv | 2 ++ crates/ui-egui/src/i18n/pl.tsv | 2 ++ crates/ui-egui/src/i18n/pt-br.tsv | 2 ++ crates/ui-egui/src/i18n/ru.tsv | 2 ++ crates/ui-egui/src/i18n/sv.tsv | 2 ++ crates/ui-egui/src/i18n/tests.rs | 33 +++++++++++++++++++++++ crates/ui-egui/src/i18n/tr.tsv | 2 ++ crates/ui-egui/src/i18n/uk.tsv | 2 ++ crates/ui-egui/src/i18n/vi.tsv | 2 ++ crates/ui-egui/src/i18n/zh-hans.tsv | 2 ++ crates/ui-egui/src/i18n/zh-hant.tsv | 2 ++ 25 files changed, 111 insertions(+), 1 deletion(-) diff --git a/crates/engine/src/cmd/variablecmds.rs b/crates/engine/src/cmd/variablecmds.rs index 33799bc85..6416c8eb1 100644 --- a/crates/engine/src/cmd/variablecmds.rs +++ b/crates/engine/src/cmd/variablecmds.rs @@ -740,7 +740,7 @@ pub fn specs() -> Vec { "Export Data Sets…", ["Window", "Variables"], None, - "{path?} write every dataset as CSV (header: name, then variables); without path → {csv, datasets}", + "{path?} write every dataset as CSV (header: name, then variables); without path → {csv, datasets}. Refused when the document has more than 1000 data sets or 256 variables, the most dataset.import reads", has_doc, dataset_export ), diff --git a/crates/engine/src/cmd/variablecmds/csv.rs b/crates/engine/src/cmd/variablecmds/csv.rs index bf60c9508..65388fb16 100644 --- a/crates/engine/src/cmd/variablecmds/csv.rs +++ b/crates/engine/src/cmd/variablecmds/csv.rs @@ -341,12 +341,20 @@ pub(super) fn dataset_import(s: &mut Session, p: &Value) -> Result { } /// Export every dataset as CSV (`name` then variables). With `path`, write the file; else return `{csv}`. +/// A document with more data sets or variables than [`dataset_import`] reads is refused. pub(super) fn dataset_export(s: &mut Session, p: &Value) -> Result { const C: &str = "dataset.export"; let st = s.doc()?; if st.doc.variables.variables.is_empty() { return Err(bad(C, "define a variable first")); } + if st.doc.variables.datasets.len() > MAX_CSV_ROWS { + return Err(bad(C, format!("more than {MAX_CSV_ROWS} data sets: Import Data Sets reads at most {MAX_CSV_ROWS}"))); + } + // The name column comes first, so the import's column cap leaves room for this many variables. + if st.doc.variables.variables.len() > MAX_CSV_COLS { + return Err(bad(C, format!("more than {MAX_CSV_COLS} variables: Import Data Sets reads at most {MAX_CSV_COLS}"))); + } let csv = datasets_to_csv(&st.doc.variables); if csv.len() > MAX_CSV_BYTES { return Err(bad(C, format!("CSV would be larger than {MAX_CSV_BYTES} bytes"))); diff --git a/crates/engine/src/tests/variables.rs b/crates/engine/src/tests/variables.rs index 5e0176f70..f57f8a597 100644 --- a/crates/engine/src/tests/variables.rs +++ b/crates/engine/src/tests/variables.rs @@ -1325,6 +1325,33 @@ fn datasets_csv_keeps_spaces_in_quoted_cells() { assert_eq!(value("C"), text_value(" quoted ")); } +/// Export refuses a document with more data sets or variables than `dataset.import` reads, so +/// every file it writes imports back: 1,000 data sets and 256 variables export and import, and +/// one more of either is refused. +#[test] +fn datasets_export_refuses_more_than_import_reads() { + let mut s = session(); + let header: Vec = (1..=256).map(|i| format!("V{i}")).collect(); + let rows: String = (1..=1000).map(|i| format!("Set {i},x\n")).collect(); + s.execute("dataset.import", &json!({"csv": format!("name,{}\n{rows}", header.join(","))})).unwrap(); + let csv = s.execute("dataset.export", &json!({})).unwrap()["csv"].as_str().unwrap().to_string(); + s.execute("dataset.import", &json!({"csv": csv})).unwrap(); + + s.execute("dataset.new", &json!({"name": "Set 1001"})).unwrap(); + let err = s.execute("dataset.export", &json!({})).unwrap_err().to_string(); + assert!(err.contains("more than 1000 data sets"), "{err}"); + s.execute("dataset.delete", &json!({"names": ["Set 1001"]})).unwrap(); + s.execute("dataset.export", &json!({})).unwrap(); + + s.execute("variable.define", &json!({"name": "V257", "kind": "text"})).unwrap(); + let err = s.execute("dataset.export", &json!({})).unwrap_err().to_string(); + assert!(err.contains("more than 256 variables"), "{err}"); + let dir = Folder::new("vars-csv-caps"); + let out = dir.file("sets.csv"); + assert!(s.execute("dataset.export", &json!({"path": out})).is_err()); + assert!(!std::path::Path::new(&out).exists(), "no file is written"); +} + /// A header row with a tab and no comma outside quotes makes tabs the separator; a quoted cell /// may then hold tabs and commas. A header row with a comma outside quotes keeps commas, even /// when a cell holds a tab. A tab-separated header with an unclosed quote fails with the reason. diff --git a/crates/ui-egui/src/i18n/ca.tsv b/crates/ui-egui/src/i18n/ca.tsv index cd6172d6a..21b2ff53f 100644 --- a/crates/ui-egui/src/i18n/ca.tsv +++ b/crates/ui-egui/src/i18n/ca.tsv @@ -5597,6 +5597,8 @@ digits Malayalam Malaiàlam @msg unsupported native docking operation operació d’acoblament nadiua no compatible @msg unsupported: {0} no compatible: {0} @msg variables are locked les variables estan blocades +@msg more than {MAX_CSV_ROWS} data sets: Import Data Sets reads at most {MAX_CSV_ROWS} més de {MAX_CSV_ROWS} conjunts de dades: Importa conjunts de dades en llegeix com a màxim {MAX_CSV_ROWS} +@msg more than {MAX_CSV_COLS} variables: Import Data Sets reads at most {MAX_CSV_COLS} més de {MAX_CSV_COLS} variables: Importa conjunts de dades en llegeix com a màxim {MAX_CSV_COLS} @msg variables that aren't text were left out: {kinds} les variables que no són text s’han omès: {kinds} @msg VectorCraft doesn't search other apps' or the system's folders: {path} VectorCraft no cerca a les carpetes d’altres aplicacions ni del sistema: {path} @msg VectorCraft doesn't search the Shared or Public folder in Users: {path} VectorCraft no cerca a la carpeta Shared o Public d’Usuaris: {path} diff --git a/crates/ui-egui/src/i18n/cs.tsv b/crates/ui-egui/src/i18n/cs.tsv index 34c7f4e03..b1742b59b 100644 --- a/crates/ui-egui/src/i18n/cs.tsv +++ b/crates/ui-egui/src/i18n/cs.tsv @@ -4786,6 +4786,8 @@ imageTrace Outline Obrys @msg unknown workspace (one of {_1}) neznámý pracovní prostor (jeden z {_1}) @msg unsupported: {0} nepodporováno: {0} @msg variables are locked proměnné jsou zamčené +@msg more than {MAX_CSV_ROWS} data sets: Import Data Sets reads at most {MAX_CSV_ROWS} více než {MAX_CSV_ROWS} sad dat: Importovat sady dat načte nejvýše {MAX_CSV_ROWS} +@msg more than {MAX_CSV_COLS} variables: Import Data Sets reads at most {MAX_CSV_COLS} více než {MAX_CSV_COLS} proměnných: Importovat sady dat načte nejvýše {MAX_CSV_COLS} @msg variables that aren't text were left out: {kinds} proměnné, které nejsou textové, byly vynechány: {kinds} @msg `{key}: {top}` and `options.{key}: {inner}` disagree: give the option once `{key}: {top}` a `options.{key}: {inner}` si odporují: zadejte volbu jen jednou @msg version {0} files can't be compressed: only version {COMPRESSED_SINCE} and later open compressed files soubory verze {0} nelze komprimovat: komprimované soubory otevírá až verze {COMPRESSED_SINCE} a novější diff --git a/crates/ui-egui/src/i18n/de.tsv b/crates/ui-egui/src/i18n/de.tsv index 101bbefac..d850991b1 100644 --- a/crates/ui-egui/src/i18n/de.tsv +++ b/crates/ui-egui/src/i18n/de.tsv @@ -4395,6 +4395,8 @@ theme Appearance Erscheinungsbild @msg unknown workspace (one of {_1}) unbekannter Arbeitsbereich (einer von {_1}) @msg unsupported: {0} nicht unterstützt: {0} @msg variables are locked die Variablen sind gesperrt +@msg more than {MAX_CSV_ROWS} data sets: Import Data Sets reads at most {MAX_CSV_ROWS} mehr als {MAX_CSV_ROWS} Datensätze: „Datensätze importieren“ liest höchstens {MAX_CSV_ROWS} +@msg more than {MAX_CSV_COLS} variables: Import Data Sets reads at most {MAX_CSV_COLS} mehr als {MAX_CSV_COLS} Variablen: „Datensätze importieren“ liest höchstens {MAX_CSV_COLS} @msg variables that aren't text were left out: {kinds} die Variablen, die kein Text sind, wurden ausgelassen: {kinds} @msg `{key}: {top}` and `options.{key}: {inner}` disagree: give the option once `{key}: {top}` und `options.{key}: {inner}` widersprechen sich: Option nur einmal angeben @msg version {0} files can't be compressed: only version {COMPRESSED_SINCE} and later open compressed files Dateien der Version {0} können nicht komprimiert werden: Erst Version {COMPRESSED_SINCE} und neuer öffnen komprimierte Dateien diff --git a/crates/ui-egui/src/i18n/el.tsv b/crates/ui-egui/src/i18n/el.tsv index e704faade..ca944e5e9 100644 --- a/crates/ui-egui/src/i18n/el.tsv +++ b/crates/ui-egui/src/i18n/el.tsv @@ -4428,6 +4428,8 @@ digits Malayalam Μαλαγιάλαμ @msg unknown workspace (one of {_1}) άγνωστος χώρος εργασίας (ένας από τους {_1}) @msg unsupported: {0} δεν υποστηρίζεται: {0} @msg variables are locked οι μεταβλητές είναι κλειδωμένες +@msg more than {MAX_CSV_ROWS} data sets: Import Data Sets reads at most {MAX_CSV_ROWS} περισσότερα από {MAX_CSV_ROWS} σύνολα δεδομένων: η Εισαγωγή συνόλων δεδομένων διαβάζει έως {MAX_CSV_ROWS} +@msg more than {MAX_CSV_COLS} variables: Import Data Sets reads at most {MAX_CSV_COLS} περισσότερες από {MAX_CSV_COLS} μεταβλητές: η Εισαγωγή συνόλων δεδομένων διαβάζει έως {MAX_CSV_COLS} @msg variables that aren't text were left out: {kinds} οι μεταβλητές που δεν είναι κειμένου παραλείφθηκαν: {kinds} @msg `{key}: {top}` and `options.{key}: {inner}` disagree: give the option once τα `{key}: {top}` και `options.{key}: {inner}` διαφέρουν: δώστε την επιλογή μόνο μία φορά @msg version {0} files can't be compressed: only version {COMPRESSED_SINCE} and later open compressed files τα αρχεία έκδοσης {0} δεν μπορούν να συμπιεστούν: μόνο η έκδοση {COMPRESSED_SINCE} και νεότερες ανοίγουν συμπιεσμένα αρχεία diff --git a/crates/ui-egui/src/i18n/es.tsv b/crates/ui-egui/src/i18n/es.tsv index 4ebddbe9a..bc2b918aa 100644 --- a/crates/ui-egui/src/i18n/es.tsv +++ b/crates/ui-egui/src/i18n/es.tsv @@ -4480,6 +4480,8 @@ axis Both Ambos @msg unknown workspace (one of {_1}) espacio de trabajo desconocido (uno de estos: {_1}) @msg unsupported: {0} no compatible: {0} @msg variables are locked las variables están bloqueadas +@msg more than {MAX_CSV_ROWS} data sets: Import Data Sets reads at most {MAX_CSV_ROWS} más de {MAX_CSV_ROWS} conjuntos de datos: Importar conjuntos de datos lee como máximo {MAX_CSV_ROWS} +@msg more than {MAX_CSV_COLS} variables: Import Data Sets reads at most {MAX_CSV_COLS} más de {MAX_CSV_COLS} variables: Importar conjuntos de datos lee como máximo {MAX_CSV_COLS} @msg variables that aren't text were left out: {kinds} se omitieron las variables que no son de texto: {kinds} @msg `{key}: {top}` and `options.{key}: {inner}` disagree: give the option once `{key}: {top}` y `options.{key}: {inner}` no coinciden: indique la opción una sola vez @msg version {0} files can't be compressed: only version {COMPRESSED_SINCE} and later open compressed files los archivos de la versión {0} no se pueden comprimir: solo la versión {COMPRESSED_SINCE} y posteriores abren archivos comprimidos diff --git a/crates/ui-egui/src/i18n/fi.tsv b/crates/ui-egui/src/i18n/fi.tsv index 7042b21f2..3d75fc5d7 100644 --- a/crates/ui-egui/src/i18n/fi.tsv +++ b/crates/ui-egui/src/i18n/fi.tsv @@ -4688,6 +4688,8 @@ imageTrace Outline Ääriviiva @msg unknown workspace (one of {_1}) tuntematon työtila (jokin seuraavista: {_1}) @msg unsupported: {0} ei tuettu: {0} @msg variables are locked muuttujat on lukittu +@msg more than {MAX_CSV_ROWS} data sets: Import Data Sets reads at most {MAX_CSV_ROWS} yli {MAX_CSV_ROWS} tietojoukkoa: Tuo tietojoukot lukee enintään {MAX_CSV_ROWS} +@msg more than {MAX_CSV_COLS} variables: Import Data Sets reads at most {MAX_CSV_COLS} yli {MAX_CSV_COLS} muuttujaa: Tuo tietojoukot lukee enintään {MAX_CSV_COLS} @msg variables that aren't text were left out: {kinds} muut kuin tekstimuuttujat jätettiin pois: {kinds} @msg `{key}: {top}` and `options.{key}: {inner}` disagree: give the option once `{key}: {top}` ja `options.{key}: {inner}` ovat ristiriidassa: anna asetus vain kerran @msg version {0} files can't be compressed: only version {COMPRESSED_SINCE} and later open compressed files version {0} tiedostoja ei voi pakata: pakattuja tiedostoja voi avata vain versiosta {COMPRESSED_SINCE} alkaen diff --git a/crates/ui-egui/src/i18n/fr.tsv b/crates/ui-egui/src/i18n/fr.tsv index 48eb621eb..c5b62d657 100644 --- a/crates/ui-egui/src/i18n/fr.tsv +++ b/crates/ui-egui/src/i18n/fr.tsv @@ -4470,6 +4470,8 @@ axis Both Les deux @msg unknown workspace (one of {_1}) espace de travail inconnu (valeurs possibles : {_1}) @msg unsupported: {0} non pris en charge : {0} @msg variables are locked les variables sont verrouillées +@msg more than {MAX_CSV_ROWS} data sets: Import Data Sets reads at most {MAX_CSV_ROWS} plus de {MAX_CSV_ROWS} jeux de données : Importer des jeux de données en lit au plus {MAX_CSV_ROWS} +@msg more than {MAX_CSV_COLS} variables: Import Data Sets reads at most {MAX_CSV_COLS} plus de {MAX_CSV_COLS} variables : Importer des jeux de données en lit au plus {MAX_CSV_COLS} @msg variables that aren't text were left out: {kinds} les variables qui ne sont pas du texte ({kinds}) ont été ignorées @msg `{key}: {top}` and `options.{key}: {inner}` disagree: give the option once `{key}: {top}` et `options.{key}: {inner}` ne concordent pas. Indiquez l’option une seule fois @msg version {0} files can't be compressed: only version {COMPRESSED_SINCE} and later open compressed files les fichiers de version {0} ne peuvent pas être compressés : seules les versions {COMPRESSED_SINCE} et ultérieures ouvrent les fichiers compressés diff --git a/crates/ui-egui/src/i18n/hu.tsv b/crates/ui-egui/src/i18n/hu.tsv index 81f948263..bdcbfa992 100644 --- a/crates/ui-egui/src/i18n/hu.tsv +++ b/crates/ui-egui/src/i18n/hu.tsv @@ -5250,6 +5250,8 @@ imageTrace Outline Körvonal @msg unsupported native docking operation nem támogatott natív dokkolási művelet @msg unsupported: {0} nem támogatott: {0} @msg variables are locked a változók zárolva vannak +@msg more than {MAX_CSV_ROWS} data sets: Import Data Sets reads at most {MAX_CSV_ROWS} több mint {MAX_CSV_ROWS} adatkészlet: az Adatkészletek importálása legfeljebb {MAX_CSV_ROWS} adatkészletet olvas be +@msg more than {MAX_CSV_COLS} variables: Import Data Sets reads at most {MAX_CSV_COLS} több mint {MAX_CSV_COLS} változó: az Adatkészletek importálása legfeljebb {MAX_CSV_COLS} változót olvas be @msg variables that aren't text were left out: {kinds} a nem szöveges változók kimaradtak: {kinds} @msg VectorCraft doesn't search other apps' or the system's folders: {path} a VectorCraft nem keres más alkalmazások és a rendszer mappáiban: {path} @msg VectorCraft doesn't search the Shared or Public folder in Users: {path} a VectorCraft nem keres a Users alatti Shared és Public mappában: {path} diff --git a/crates/ui-egui/src/i18n/it.tsv b/crates/ui-egui/src/i18n/it.tsv index 6acfaf3c9..b912c4e8f 100644 --- a/crates/ui-egui/src/i18n/it.tsv +++ b/crates/ui-egui/src/i18n/it.tsv @@ -4521,6 +4521,8 @@ axis Both Entrambi @msg unknown workspace (one of {_1}) area di lavoro sconosciuta (una delle seguenti: {_1}) @msg unsupported: {0} non supportato: {0} @msg variables are locked le variabili sono bloccate +@msg more than {MAX_CSV_ROWS} data sets: Import Data Sets reads at most {MAX_CSV_ROWS} più di {MAX_CSV_ROWS} set di dati: Importa set di dati ne legge al massimo {MAX_CSV_ROWS} +@msg more than {MAX_CSV_COLS} variables: Import Data Sets reads at most {MAX_CSV_COLS} più di {MAX_CSV_COLS} variabili: Importa set di dati ne legge al massimo {MAX_CSV_COLS} @msg variables that aren't text were left out: {kinds} le variabili che non sono di testo sono state escluse: {kinds} @msg `{key}: {top}` and `options.{key}: {inner}` disagree: give the option once `{key}: {top}` e `options.{key}: {inner}` non coincidono: indicare l'opzione una sola volta @msg version {0} files can't be compressed: only version {COMPRESSED_SINCE} and later open compressed files i file della versione {0} non possono essere compressi: solo la versione {COMPRESSED_SINCE} e successive aprono file compressi diff --git a/crates/ui-egui/src/i18n/ja.tsv b/crates/ui-egui/src/i18n/ja.tsv index 4bf3cd6bd..0380bf497 100644 --- a/crates/ui-egui/src/i18n/ja.tsv +++ b/crates/ui-egui/src/i18n/ja.tsv @@ -4076,6 +4076,8 @@ swatch Bright Violet ビビッドバイオレット @msg Make Guides: select paths ガイドを作成: パスを選択してください @msg Release Guides: no guides ガイドを解除: ガイドがありません @msg variables are locked 変数がロックされています +@msg more than {MAX_CSV_ROWS} data sets: Import Data Sets reads at most {MAX_CSV_ROWS} データセットが {MAX_CSV_ROWS} 個を超えています: 「データセットを読み込み」が読み込めるのは {MAX_CSV_ROWS} 個までです +@msg more than {MAX_CSV_COLS} variables: Import Data Sets reads at most {MAX_CSV_COLS} 変数が {MAX_CSV_COLS} 個を超えています: 「データセットを読み込み」が読み込めるのは {MAX_CSV_COLS} 個までです @msg variables that aren't text were left out: {kinds} テキスト以外の変数は除外されました: {kinds} @msg guides are locked ガイドがロックされています @msg handle must be in or out handle には in または out を指定してください diff --git a/crates/ui-egui/src/i18n/ka.tsv b/crates/ui-egui/src/i18n/ka.tsv index cf411b072..296a233f8 100644 --- a/crates/ui-egui/src/i18n/ka.tsv +++ b/crates/ui-egui/src/i18n/ka.tsv @@ -5417,6 +5417,8 @@ imageTrace Outline კონტური @msg too many changed shortcuts ზედმეტად ბევრი შეცვლილი მალსახმობი @msg too many library panels were opened in this session ამ სესიაში ზედმეტად ბევრი ბიბლიოთეკის პანელი გაიხსნა @msg variables are locked ცვლადები ჩაკეტილია +@msg more than {MAX_CSV_ROWS} data sets: Import Data Sets reads at most {MAX_CSV_ROWS} {MAX_CSV_ROWS}-ზე მეტი მონაცემთა ნაკრები: მონაცემთა ნაკრებების იმპორტი კითხულობს მაქსიმუმ {MAX_CSV_ROWS}-ს +@msg more than {MAX_CSV_COLS} variables: Import Data Sets reads at most {MAX_CSV_COLS} {MAX_CSV_COLS}-ზე მეტი ცვლადი: მონაცემთა ნაკრებების იმპორტი კითხულობს მაქსიმუმ {MAX_CSV_COLS}-ს @msg variables that aren't text were left out: {kinds} ცვლადები, რომლებიც ტექსტი არ არის, გამოტოვებულია: {kinds} @msg x and y must be finite x და y სასრული უნდა იყოს @msg {id} opens another app: only the person at the keyboard can run it {id} სხვა აპს ხსნის: მისი გაშვება მხოლოდ კლავიატურასთან მყოფ ადამიანს შეუძლია diff --git a/crates/ui-egui/src/i18n/ko.tsv b/crates/ui-egui/src/i18n/ko.tsv index 81f6c600c..59baeea9f 100644 --- a/crates/ui-egui/src/i18n/ko.tsv +++ b/crates/ui-egui/src/i18n/ko.tsv @@ -4003,6 +4003,8 @@ theme Appearance 외관 @msg Make Guides: select paths 안내선 만들기: 패스를 선택하세요 @msg Release Guides: no guides 안내선 해제: 안내선이 없습니다 @msg variables are locked 변수가 잠겨 있습니다 +@msg more than {MAX_CSV_ROWS} data sets: Import Data Sets reads at most {MAX_CSV_ROWS} 데이터 세트가 {MAX_CSV_ROWS}개보다 많습니다: 데이터 세트 가져오기는 최대 {MAX_CSV_ROWS}개를 읽습니다 +@msg more than {MAX_CSV_COLS} variables: Import Data Sets reads at most {MAX_CSV_COLS} 변수가 {MAX_CSV_COLS}개보다 많습니다: 데이터 세트 가져오기는 최대 {MAX_CSV_COLS}개를 읽습니다 @msg variables that aren't text were left out: {kinds} 텍스트가 아닌 변수는 제외되었습니다: {kinds} @msg guides are locked 안내선이 잠겨 있습니다 @msg handle must be in or out handle은 in 또는 out이어야 합니다 diff --git a/crates/ui-egui/src/i18n/pl.tsv b/crates/ui-egui/src/i18n/pl.tsv index 14825f83c..8f292c0d9 100644 --- a/crates/ui-egui/src/i18n/pl.tsv +++ b/crates/ui-egui/src/i18n/pl.tsv @@ -4612,6 +4612,8 @@ imageTrace Outline Kontur @msg unknown workspace (one of {_1}) nieznany obszar roboczy (jeden z: {_1}) @msg unsupported: {0} nieobsługiwane: {0} @msg variables are locked zmienne są zablokowane +@msg more than {MAX_CSV_ROWS} data sets: Import Data Sets reads at most {MAX_CSV_ROWS} więcej niż {MAX_CSV_ROWS} zestawów danych: Importuj zestawy danych odczytuje najwyżej {MAX_CSV_ROWS} +@msg more than {MAX_CSV_COLS} variables: Import Data Sets reads at most {MAX_CSV_COLS} więcej niż {MAX_CSV_COLS} zmiennych: Importuj zestawy danych odczytuje najwyżej {MAX_CSV_COLS} @msg variables that aren't text were left out: {kinds} pominięto zmienne, które nie są tekstowe: {kinds} @msg `{key}: {top}` and `options.{key}: {inner}` disagree: give the option once `{key}: {top}` i `options.{key}: {inner}` są sprzeczne: podaj opcję tylko raz @msg version {0} files can't be compressed: only version {COMPRESSED_SINCE} and later open compressed files plików w wersji {0} nie można kompresować: skompresowane pliki otwierają tylko wersje {COMPRESSED_SINCE} i nowsze diff --git a/crates/ui-egui/src/i18n/pt-br.tsv b/crates/ui-egui/src/i18n/pt-br.tsv index 96a31c3e5..f4c43bdb8 100644 --- a/crates/ui-egui/src/i18n/pt-br.tsv +++ b/crates/ui-egui/src/i18n/pt-br.tsv @@ -4052,6 +4052,8 @@ axis Both Ambos @msg unknown workspace (one of {_1}) espaço de trabalho desconhecido (um de {_1}) @msg unsupported: {0} não suportado: {0} @msg variables are locked as variáveis estão bloqueadas +@msg more than {MAX_CSV_ROWS} data sets: Import Data Sets reads at most {MAX_CSV_ROWS} mais de {MAX_CSV_ROWS} conjuntos de dados: Importar Conjuntos de Dados lê no máximo {MAX_CSV_ROWS} +@msg more than {MAX_CSV_COLS} variables: Import Data Sets reads at most {MAX_CSV_COLS} mais de {MAX_CSV_COLS} variáveis: Importar Conjuntos de Dados lê no máximo {MAX_CSV_COLS} @msg variables that aren't text were left out: {kinds} as variáveis que não são de texto foram omitidas: {kinds} @msg `{key}: {top}` and `options.{key}: {inner}` disagree: give the option once `{key}: {top}` e `options.{key}: {inner}` não coincidem: informe a opção uma só vez @msg version {0} files can't be compressed: only version {COMPRESSED_SINCE} and later open compressed files arquivos da versão {0} não podem ser compactados: somente a versão {COMPRESSED_SINCE} e posteriores abrem arquivos compactados diff --git a/crates/ui-egui/src/i18n/ru.tsv b/crates/ui-egui/src/i18n/ru.tsv index fdb51b80d..9798ffe64 100644 --- a/crates/ui-egui/src/i18n/ru.tsv +++ b/crates/ui-egui/src/i18n/ru.tsv @@ -4516,6 +4516,8 @@ axis Both Оба @msg unknown workspace (one of {_1}) неизвестная рабочая среда (одна из: {_1}) @msg unsupported: {0} не поддерживается: {0} @msg variables are locked переменные заблокированы +@msg more than {MAX_CSV_ROWS} data sets: Import Data Sets reads at most {MAX_CSV_ROWS} больше {MAX_CSV_ROWS} наборов данных: «Импортировать наборы данных» читает не более {MAX_CSV_ROWS} +@msg more than {MAX_CSV_COLS} variables: Import Data Sets reads at most {MAX_CSV_COLS} больше {MAX_CSV_COLS} переменных: «Импортировать наборы данных» читает не более {MAX_CSV_COLS} @msg variables that aren't text were left out: {kinds} переменные, которые не являются текстовыми, пропущены: {kinds} @msg `{key}: {top}` and `options.{key}: {inner}` disagree: give the option once `{key}: {top}` и `options.{key}: {inner}` противоречат друг другу: укажите параметр только один раз @msg version {0} files can't be compressed: only version {COMPRESSED_SINCE} and later open compressed files файлы версии {0} не могут быть сжаты: только версия {COMPRESSED_SINCE} и новее открывают сжатые файлы diff --git a/crates/ui-egui/src/i18n/sv.tsv b/crates/ui-egui/src/i18n/sv.tsv index e2dddf022..1b6429b62 100644 --- a/crates/ui-egui/src/i18n/sv.tsv +++ b/crates/ui-egui/src/i18n/sv.tsv @@ -4379,6 +4379,8 @@ axis Both Båda @msg unknown workspace (one of {_1}) okänd arbetslayout (en av {_1}) @msg unsupported: {0} stöds inte: {0} @msg variables are locked variablerna är låsta +@msg more than {MAX_CSV_ROWS} data sets: Import Data Sets reads at most {MAX_CSV_ROWS} fler än {MAX_CSV_ROWS} datauppsättningar: Importera datauppsättningar läser högst {MAX_CSV_ROWS} +@msg more than {MAX_CSV_COLS} variables: Import Data Sets reads at most {MAX_CSV_COLS} fler än {MAX_CSV_COLS} variabler: Importera datauppsättningar läser högst {MAX_CSV_COLS} @msg variables that aren't text were left out: {kinds} variabler som inte är text utelämnades: {kinds} @msg `{key}: {top}` and `options.{key}: {inner}` disagree: give the option once `{key}: {top}` och `options.{key}: {inner}` stämmer inte överens: ange alternativet bara en gång @msg version {0} files can't be compressed: only version {COMPRESSED_SINCE} and later open compressed files filer i version {0} kan inte komprimeras: endast version {COMPRESSED_SINCE} och senare kan öppna komprimerade filer diff --git a/crates/ui-egui/src/i18n/tests.rs b/crates/ui-egui/src/i18n/tests.rs index 7e5ca938c..b0da961f0 100644 --- a/crates/ui-egui/src/i18n/tests.rs +++ b/crates/ui-egui/src/i18n/tests.rs @@ -1736,6 +1736,39 @@ fn saved_tracing_preset_errors_are_translated() { } } +/// Export Data Sets' refusals of more data sets or variables than Import Data Sets reads are +/// translated in every language that translates every message. +#[test] +fn dataset_export_limit_errors_are_translated() { + use serde_json::json; + use vectorcraft_engine::{EngineError, Session}; + let mut s = Session::new(); + s.execute("file.new", &json!({})).unwrap(); + let rows: String = (1..=1000).map(|i| format!("Set {i},x\n")).collect(); + s.execute("dataset.import", &json!({"csv": format!("name,V1\n{rows}")})).unwrap(); + s.execute("dataset.new", &json!({"name": "Set 1001"})).unwrap(); + let mut errors = vec![]; + let e = s.execute("dataset.export", &json!({})).unwrap_err(); + let want = "more than 1000 data sets: Import Data Sets reads at most 1000"; + assert!(matches!(&e, EngineError::BadParams { msg, .. } if msg == want), "{e}"); + errors.push((e.to_string(), want)); + s.execute("dataset.delete", &json!({"names": ["Set 1001"]})).unwrap(); + for i in 2..=257 { + s.execute("variable.define", &json!({"name": format!("V{i}"), "kind": "text"})).unwrap(); + } + let e = s.execute("dataset.export", &json!({})).unwrap_err(); + let want = "more than 256 variables: Import Data Sets reads at most 256"; + assert!(matches!(&e, EngineError::BadParams { msg, .. } if msg == want), "{e}"); + errors.push((e.to_string(), want)); + for code in COMPLETE_MESSAGES { + let lang = Lang::from_code(code).expect("registered"); + for (e, want) in &errors { + let shown = message(lang, e); + assert!(!shown.contains(want), "{code}: {shown}"); + } + } +} + /// The status bar's line for an EPS file whose PostScript stops on an error, opened partly or /// refused, and the refusal's dialog keep the error's name as PostScript spells it and its meaning, /// which each language shows as its catalog translates the meaning. diff --git a/crates/ui-egui/src/i18n/tr.tsv b/crates/ui-egui/src/i18n/tr.tsv index 9ecf2ccf9..66e00165b 100644 --- a/crates/ui-egui/src/i18n/tr.tsv +++ b/crates/ui-egui/src/i18n/tr.tsv @@ -5334,6 +5334,8 @@ theme Appearance Görünüm @msg the spine has no segments omurganın segmenti yok @msg too many library panels were opened in this session bu oturumda çok fazla kütüphane paneli açıldı @msg variables are locked değişkenler kilitli +@msg more than {MAX_CSV_ROWS} data sets: Import Data Sets reads at most {MAX_CSV_ROWS} {MAX_CSV_ROWS} veri setinden fazla: Veri Kümelerini İçe Aktar en fazla {MAX_CSV_ROWS} tane okur +@msg more than {MAX_CSV_COLS} variables: Import Data Sets reads at most {MAX_CSV_COLS} {MAX_CSV_COLS} değişkenden fazla: Veri Kümelerini İçe Aktar en fazla {MAX_CSV_COLS} tane okur @msg x and y must be finite x ve y sonlu olmalıdır @msg aiVersion 7 writes legacy .ai files; a .ait template is always PDF-compatible aiVersion 7 eski .ai dosyalarını yazar; bir .ait şablonu her zaman PDF uyumludur @msg Edit Original opens image and document files only; “{name}” is not one Özgünü Düzenle yalnızca görüntü ve belge dosyalarını açar; “{name}” bunlardan biri değil diff --git a/crates/ui-egui/src/i18n/uk.tsv b/crates/ui-egui/src/i18n/uk.tsv index d348440a2..ce992f29a 100644 --- a/crates/ui-egui/src/i18n/uk.tsv +++ b/crates/ui-egui/src/i18n/uk.tsv @@ -4505,6 +4505,8 @@ axis Both Обидві @msg unknown workspace (one of {_1}) невідоме робоче середовище (одна з: {_1}) @msg unsupported: {0} не підтримується: {0} @msg variables are locked змінні заблоковані +@msg more than {MAX_CSV_ROWS} data sets: Import Data Sets reads at most {MAX_CSV_ROWS} більше ніж {MAX_CSV_ROWS} наборів даних: «Імпортувати набори даних» читає не більше {MAX_CSV_ROWS} +@msg more than {MAX_CSV_COLS} variables: Import Data Sets reads at most {MAX_CSV_COLS} більше ніж {MAX_CSV_COLS} змінних: «Імпортувати набори даних» читає не більше {MAX_CSV_COLS} @msg variables that aren't text were left out: {kinds} змінні, що не є текстовими, пропущено: {kinds} @msg `{key}: {top}` and `options.{key}: {inner}` disagree: give the option once `{key}: {top}` і `options.{key}: {inner}` суперечать одне одному: вкажіть параметр лише один раз @msg version {0} files can't be compressed: only version {COMPRESSED_SINCE} and later open compressed files файли версії {0} не можуть бути стиснуті: тільки версія {COMPRESSED_SINCE} і новіші відкривають стислі файли diff --git a/crates/ui-egui/src/i18n/vi.tsv b/crates/ui-egui/src/i18n/vi.tsv index 09652ede2..9bb1c58a8 100644 --- a/crates/ui-egui/src/i18n/vi.tsv +++ b/crates/ui-egui/src/i18n/vi.tsv @@ -4912,6 +4912,8 @@ theme Appearance Giao diện @msg unsupported native docking operation thao tác neo gốc không được hỗ trợ @msg unsupported: {0} không được hỗ trợ: {0} @msg variables are locked biến số bị khóa +@msg more than {MAX_CSV_ROWS} data sets: Import Data Sets reads at most {MAX_CSV_ROWS} hơn {MAX_CSV_ROWS} tập dữ liệu: Nhập tập dữ liệu chỉ đọc tối đa {MAX_CSV_ROWS} +@msg more than {MAX_CSV_COLS} variables: Import Data Sets reads at most {MAX_CSV_COLS} hơn {MAX_CSV_COLS} biến số: Nhập tập dữ liệu chỉ đọc tối đa {MAX_CSV_COLS} @msg variables that aren't text were left out: {kinds} các biến số không phải văn bản đã bị bỏ qua: {kinds} @msg VectorCraft doesn't search other apps' or the system's folders: {path} VectorCraft không tìm kiếm trong thư mục của ứng dụng khác hoặc hệ thống: {path} @msg VectorCraft doesn't search the Shared or Public folder in Users: {path} VectorCraft không tìm kiếm thư mục Shared hoặc Public trong Users: {path} diff --git a/crates/ui-egui/src/i18n/zh-hans.tsv b/crates/ui-egui/src/i18n/zh-hans.tsv index 841bd4528..027d9c29d 100644 --- a/crates/ui-egui/src/i18n/zh-hans.tsv +++ b/crates/ui-egui/src/i18n/zh-hans.tsv @@ -3471,6 +3471,8 @@ digits Malayalam 马拉雅拉姆数字 Lock Variables 锁定变量 Unlock Variables 解锁变量 @msg variables are locked 变量已锁定 +@msg more than {MAX_CSV_ROWS} data sets: Import Data Sets reads at most {MAX_CSV_ROWS} 数据集超过 {MAX_CSV_ROWS} 个:“导入数据集”最多读取 {MAX_CSV_ROWS} 个 +@msg more than {MAX_CSV_COLS} variables: Import Data Sets reads at most {MAX_CSV_COLS} 变量超过 {MAX_CSV_COLS} 个:“导入数据集”最多读取 {MAX_CSV_COLS} 个 @msg variables that aren't text were left out: {kinds} 已省略非文本变量:{kinds} List Variables 列出变量 Bind Variable 绑定变量 diff --git a/crates/ui-egui/src/i18n/zh-hant.tsv b/crates/ui-egui/src/i18n/zh-hant.tsv index a515d59a7..ce25e4b0d 100644 --- a/crates/ui-egui/src/i18n/zh-hant.tsv +++ b/crates/ui-egui/src/i18n/zh-hant.tsv @@ -4459,6 +4459,8 @@ digits Malayalam 馬來亞拉姆數字 Lock Variables 鎖定變數 Unlock Variables 解除鎖定變數 @msg variables are locked 變數已鎖定 +@msg more than {MAX_CSV_ROWS} data sets: Import Data Sets reads at most {MAX_CSV_ROWS} 資料集超過 {MAX_CSV_ROWS} 個:「匯入資料集」最多讀取 {MAX_CSV_ROWS} 個 +@msg more than {MAX_CSV_COLS} variables: Import Data Sets reads at most {MAX_CSV_COLS} 變數超過 {MAX_CSV_COLS} 個:「匯入資料集」最多讀取 {MAX_CSV_COLS} 個 @msg variables that aren't text were left out: {kinds} 已略過非文字變數:{kinds} List Variables 列出變數 Bind Variable 綁定變數