diff --git a/crates/engine/tests/plugin_import.rs b/crates/engine/tests/plugin_import.rs index 7cb8d1a0a..7f62de2b7 100644 --- a/crates/engine/tests/plugin_import.rs +++ b/crates/engine/tests/plugin_import.rs @@ -51,6 +51,14 @@ fn objects(s: &Session) -> usize { s.doc().unwrap().doc.layers[0].children().unwrap().len() } +/// The open documents' count, the active one's index, its undo and redo steps, whether it has +/// unsaved changes, and its content. +fn state(s: &mut Session) -> (usize, Option, usize, usize, bool, Value) { + let content = s.execute("document.inspect", &json!({})).unwrap(); + let d = s.doc().unwrap(); + (s.documents().len(), s.active_index(), d.history.undo.len(), d.history.redo.len(), d.is_dirty(), content) +} + /// A fresh folder for files this test writes. fn tmp_dir(tag: &str) -> PathBuf { let d = std::env::temp_dir().join(format!("vc-plugin-import-{tag}-{}", std::process::id())); @@ -195,9 +203,11 @@ fn importer_names_that_do_not_fit_are_errors() { let mut s = Session::new(); echo(&mut s, "test.names", r#"["tsn"]"#); install(&mut s, &tpl::returning(&tpl::manifest("test.names.filter", "filter", "{}"), r#"{"objects":[]}"#)); + install(&mut s, &tpl::returning(&tpl::exporter("test.names.exporter", r#"["tsx"]"#, "{}"), r#"{"dataBase64":""}"#)); let cases = [ (json!({"importer": "plugin.test.names"}), "x.png", "opens .tsn files, not `x.png`"), - (json!({"importer": "plugin.test.names.filter"}), "x.tsn", "is a filter, not an importer"), + (json!({"importer": "plugin.test.names.filter"}), "x.tsn", "is a plug-in of kind `filter`, not an importer"), + (json!({"importer": "plugin.test.names.exporter"}), "x.tsn", "is a plug-in of kind `exporter`, not an importer"), (json!({"importer": "plugin.test.nothere"}), "x.tsn", "test.nothere"), (json!({"importer": 3}), "x.tsn", "`importer` must be a plug-in format id"), ]; @@ -257,6 +267,26 @@ fn failures_open_nothing() { install(&mut s, &tpl::module(&tpl::importer("test.fail.traps", r#"["tsf"]"#, "{}"), "(unreachable)", "", 1)); assert!(open(&mut s, "x.tsf", b"?", json!({"importer": "plugin.test.fail.traps"})).is_err()); assert!(s.documents().is_empty(), "nothing opened"); + + // A document that is already open keeps its tab, content and undo and redo steps. + install(&mut s, &tpl::returning(&tpl::importer("test.fail.opens", r#"["tsk"]"#, "{}"), RECT)); + install(&mut s, &tpl::module(&tpl::importer("test.fail.spins", r#"["tsf"]"#, "{}"), "(loop $l (br $l)) (i64.const 0)", "", 1)); + open(&mut s, "Kept.tsk", b"?", json!({})).unwrap(); + s.execute("select.all", &json!({})).unwrap(); + s.execute("object.move", &json!({"dx": 5, "dy": 0})).unwrap(); + s.execute("object.move", &json!({"dx": 5, "dy": 0})).unwrap(); + s.execute("edit.undo", &json!({})).unwrap(); + let before = state(&mut s); + assert!(before.2 > 0 && before.3 > 0, "{before:?}"); + for id in cases.iter().map(|c| c.0).chain(["test.fail.traps"]) { + assert!(open(&mut s, "x.tsf", b"?", json!({"importer": format!("plugin.{id}")})).is_err(), "{id}"); + assert_eq!(state(&mut s), before, "{id}"); + } + let token = vectorcraft_doc::cancel::CancelToken::new(); + token.cancel(); + let r = vectorcraft_doc::cancel::scope(&token, None, || open(&mut s, "x.tsf", b"?", json!({"importer": "plugin.test.fail.spins"}))); + assert!(matches!(r, Err(EngineError::Cancelled)), "{r:?}"); + assert_eq!(state(&mut s), before, "cancelled"); } /// Cancel stops an importer between two slices of its budget, and nothing opens: here one that diff --git a/crates/plugins/src/export.rs b/crates/plugins/src/export.rs index 9ecc76277..300bd80d2 100644 --- a/crates/plugins/src/export.rs +++ b/crates/plugins/src/export.rs @@ -83,7 +83,7 @@ pub fn limits(plugin: &Plugin) -> Limits { pub fn run(plugin: &Plugin, document: &[u8], params: &Value, target: Target) -> Result { let m = plugin.manifest(); if m.kind != Kind::Exporter { - return Err(Error::Params(format!("`{}` is a {}, not an exporter", m.id, m.kind.name()))); + return Err(Error::Params(format!("`{}` is a plug-in of kind `{}`, not an exporter", m.id, m.kind.name()))); } let mut params = Value::Object(m.resolve_params(params)?); params["_context"] = json!({"mode": "export", "extension": target.extension, "name": target.name}); diff --git a/crates/plugins/src/import.rs b/crates/plugins/src/import.rs index 5a7be6a85..6229d8959 100644 --- a/crates/plugins/src/import.rs +++ b/crates/plugins/src/import.rs @@ -51,7 +51,7 @@ pub fn named(importer: &str) -> Result> { /// The error of plug-in `m`, which is not an importer, asked to import. fn not_importer(m: &crate::Manifest) -> Error { - Error::Params(format!("`{}` is a {}, not an importer", m.id, m.kind.name())) + Error::Params(format!("`{}` is a plug-in of kind `{}`, not an importer", m.id, m.kind.name())) } /// The installed importers that list extension `ext` (any case, leading dot allowed), by plug-in diff --git a/crates/plugins/tests/abi.rs b/crates/plugins/tests/abi.rs index f5b78d224..1463f9916 100644 --- a/crates/plugins/tests/abi.rs +++ b/crates/plugins/tests/abi.rs @@ -272,7 +272,11 @@ fn an_exporter_returns_its_file_with_an_export_s_budget() { // Its parameters are checked, and a filter is not an exporter. assert!(matches!(export::run(&p, b"{}", &json!({"level": "high"}), target), Err(Error::Params(_)))); let filter = Plugin::load(&ok_module("(i64.const 0)"), Limits::default()).unwrap(); - assert!(matches!(export::run(&filter, b"{}", &Value::Null, target), Err(Error::Params(_)))); + let e = export::run(&filter, b"{}", &Value::Null, target).unwrap_err(); + assert!(matches!(e, Error::Params(_)) && e.to_string().contains("is a plug-in of kind `filter`, not an exporter"), "{e}"); + let importer = Plugin::load(&build(&tpl::returning(&tpl::importer("test.reads", r#"["tst"]"#, "{}"), "{}")), Limits::default()).unwrap(); + let e = export::run(&importer, b"{}", &Value::Null, target).unwrap_err(); + assert!(e.to_string().contains("is a plug-in of kind `importer`, not an exporter"), "{e}"); } /// The echo exporter the engine and UI tests read back what they hand a plug-in with: its file is diff --git a/crates/ui-egui/src/i18n/ca.tsv b/crates/ui-egui/src/i18n/ca.tsv index 953914129..5d0a001b8 100644 --- a/crates/ui-egui/src/i18n/ca.tsv +++ b/crates/ui-egui/src/i18n/ca.tsv @@ -6473,7 +6473,8 @@ breakText Glyphs Glifs @msg missing `importer` (see document.formats) falta `importer` (vegeu document.formats) @msg `importer` must be a plug-in format id (see document.formats) `importer` ha de ser l’id de format d’un complement (vegeu document.formats) @msg “{shown}” opens {_1} files, not `{_2}` «{shown}» obre fitxers {_1}, no `{_2}` -@msg `{_1}` is a {_2}, not an importer `{_1}` és un {_2}, no un importador +@msg `{_1}` is a plug-in of kind `{_2}`, not an importer `{_1}` és un complement del tipus `{_2}`, no un importador +@msg `{_1}` is a plug-in of kind `{_2}`, not an exporter `{_1}` és un complement del tipus `{_2}`, no un exportador @msg `{_1}` is an importer: open a file with document.open {{"importer"}"}} `{_1}` és un importador: obriu un fitxer amb document.open {{"importer"}"}} @msg the importer returned no objects l’importador no ha retornat cap objecte @msg an importer returns `objects` and `warnings`, not `{key}` un importador retorna `objects` i `warnings`, no `{key}` diff --git a/crates/ui-egui/src/i18n/cs.tsv b/crates/ui-egui/src/i18n/cs.tsv index dc95fe117..7366381e2 100644 --- a/crates/ui-egui/src/i18n/cs.tsv +++ b/crates/ui-egui/src/i18n/cs.tsv @@ -6490,7 +6490,8 @@ breakText Glyphs Glyfy @msg missing `importer` (see document.formats) chybí `importer` (viz document.formats) @msg `importer` must be a plug-in format id (see document.formats) `importer` musí být ID formátu zásuvného modulu (viz document.formats) @msg “{shown}” opens {_1} files, not `{_2}` „{shown}“ otevírá soubory {_1}, ne `{_2}` -@msg `{_1}` is a {_2}, not an importer `{_1}` je {_2}, ne importní zásuvný modul +@msg `{_1}` is a plug-in of kind `{_2}`, not an importer `{_1}` je zásuvný modul druhu `{_2}`, ne importní zásuvný modul +@msg `{_1}` is a plug-in of kind `{_2}`, not an exporter `{_1}` je zásuvný modul druhu `{_2}`, ne exportní zásuvný modul @msg `{_1}` is an importer: open a file with document.open {{"importer"}"}} `{_1}` je importní zásuvný modul: otevřete soubor pomocí document.open {{"importer"}"}} @msg the importer returned no objects importní zásuvný modul nevrátil žádné objekty @msg an importer returns `objects` and `warnings`, not `{key}` importní zásuvný modul vrací `objects` a `warnings`, ne `{key}` diff --git a/crates/ui-egui/src/i18n/de.tsv b/crates/ui-egui/src/i18n/de.tsv index 6ae88f96e..f34b88a6b 100644 --- a/crates/ui-egui/src/i18n/de.tsv +++ b/crates/ui-egui/src/i18n/de.tsv @@ -6076,7 +6076,8 @@ breakText Glyphs Glyphen @msg missing `importer` (see document.formats) `importer` fehlt (siehe document.formats) @msg `importer` must be a plug-in format id (see document.formats) `importer` muss die Format-ID eines Plug-ins sein (siehe document.formats) @msg “{shown}” opens {_1} files, not `{_2}` „{shown}“ öffnet {_1}-Dateien, nicht `{_2}` -@msg `{_1}` is a {_2}, not an importer `{_1}` ist ein {_2}, kein Import-Plug-in +@msg `{_1}` is a plug-in of kind `{_2}`, not an importer `{_1}` ist ein Plug-in der Art `{_2}`, kein Import-Plug-in +@msg `{_1}` is a plug-in of kind `{_2}`, not an exporter `{_1}` ist ein Plug-in der Art `{_2}`, kein Export-Plug-in @msg `{_1}` is an importer: open a file with document.open {{"importer"}"}} `{_1}` ist ein Import-Plug-in: Öffnen Sie eine Datei mit document.open {{"importer"}"}} @msg the importer returned no objects das Import-Plug-in hat keine Objekte zurückgegeben @msg an importer returns `objects` and `warnings`, not `{key}` ein Import-Plug-in gibt `objects` und `warnings` zurück, nicht `{key}` diff --git a/crates/ui-egui/src/i18n/el.tsv b/crates/ui-egui/src/i18n/el.tsv index 5c3f193c5..1d245a392 100644 --- a/crates/ui-egui/src/i18n/el.tsv +++ b/crates/ui-egui/src/i18n/el.tsv @@ -6442,7 +6442,8 @@ breakText Glyphs Γλύφοι @msg missing `importer` (see document.formats) λείπει το `importer` (δείτε document.formats) @msg `importer` must be a plug-in format id (see document.formats) το `importer` πρέπει να είναι αναγνωριστικό μορφής πρόσθετου (δείτε document.formats) @msg “{shown}” opens {_1} files, not `{_2}` το «{shown}» ανοίγει αρχεία {_1}, όχι `{_2}` -@msg `{_1}` is a {_2}, not an importer το `{_1}` είναι {_2}, όχι πρόσθετο εισαγωγής +@msg `{_1}` is a plug-in of kind `{_2}`, not an importer το `{_1}` είναι πρόσθετο τύπου `{_2}`, όχι πρόσθετο εισαγωγής +@msg `{_1}` is a plug-in of kind `{_2}`, not an exporter το `{_1}` είναι πρόσθετο τύπου `{_2}`, όχι πρόσθετο εξαγωγής @msg `{_1}` is an importer: open a file with document.open {{"importer"}"}} το `{_1}` είναι πρόσθετο εισαγωγής: ανοίξτε ένα αρχείο με document.open {{"importer"}"}} @msg the importer returned no objects το πρόσθετο εισαγωγής δεν επέστρεψε κανένα αντικείμενο @msg an importer returns `objects` and `warnings`, not `{key}` ένα πρόσθετο εισαγωγής επιστρέφει `objects` και `warnings`, όχι `{key}` diff --git a/crates/ui-egui/src/i18n/es.tsv b/crates/ui-egui/src/i18n/es.tsv index 99c7c5d0c..edeba9d58 100644 --- a/crates/ui-egui/src/i18n/es.tsv +++ b/crates/ui-egui/src/i18n/es.tsv @@ -6432,7 +6432,8 @@ breakText Glyphs Glifos @msg missing `importer` (see document.formats) falta `importer` (consulte document.formats) @msg `importer` must be a plug-in format id (see document.formats) `importer` debe ser el id de formato de un plugin (consulte document.formats) @msg “{shown}” opens {_1} files, not `{_2}` «{shown}» abre archivos {_1}, no `{_2}` -@msg `{_1}` is a {_2}, not an importer `{_1}` es un {_2}, no un plugin de importación +@msg `{_1}` is a plug-in of kind `{_2}`, not an importer `{_1}` es un plugin de tipo `{_2}`, no un plugin de importación +@msg `{_1}` is a plug-in of kind `{_2}`, not an exporter `{_1}` es un plugin de tipo `{_2}`, no un plugin de exportación @msg `{_1}` is an importer: open a file with document.open {{"importer"}"}} `{_1}` es un plugin de importación: abra un archivo con document.open {{"importer"}"}} @msg the importer returned no objects el plugin de importación no devolvió ningún objeto @msg an importer returns `objects` and `warnings`, not `{key}` un plugin de importación devuelve `objects` y `warnings`, no `{key}` diff --git a/crates/ui-egui/src/i18n/fi.tsv b/crates/ui-egui/src/i18n/fi.tsv index 53103e483..eef4c97f8 100644 --- a/crates/ui-egui/src/i18n/fi.tsv +++ b/crates/ui-egui/src/i18n/fi.tsv @@ -6525,7 +6525,8 @@ breakText Glyphs Merkit @msg missing `importer` (see document.formats) `importer` puuttuu (katso document.formats) @msg `importer` must be a plug-in format id (see document.formats) `importer` on oltava laajennuksen muototunnus (katso document.formats) @msg “{shown}” opens {_1} files, not `{_2}` ”{shown}” avaa {_1}-tiedostoja, ei `{_2}` -@msg `{_1}` is a {_2}, not an importer `{_1}` on {_2}, ei tuontilaajennus +@msg `{_1}` is a plug-in of kind `{_2}`, not an importer `{_1}` on lajin `{_2}` laajennus, ei tuontilaajennus +@msg `{_1}` is a plug-in of kind `{_2}`, not an exporter `{_1}` on lajin `{_2}` laajennus, ei vientilaajennus @msg `{_1}` is an importer: open a file with document.open {{"importer"}"}} `{_1}` on tuontilaajennus: avaa tiedosto komennolla document.open {{"importer"}"}} @msg the importer returned no objects tuontilaajennus ei palauttanut objekteja @msg an importer returns `objects` and `warnings`, not `{key}` tuontilaajennus palauttaa `objects` ja `warnings`, ei `{key}` diff --git a/crates/ui-egui/src/i18n/fr.tsv b/crates/ui-egui/src/i18n/fr.tsv index 717a8a3f6..97f74171a 100644 --- a/crates/ui-egui/src/i18n/fr.tsv +++ b/crates/ui-egui/src/i18n/fr.tsv @@ -6485,7 +6485,8 @@ breakText Glyphs Glyphes @msg missing `importer` (see document.formats) `importer` manquant (voir document.formats) @msg `importer` must be a plug-in format id (see document.formats) `importer` doit être l’identifiant de format d’un module externe (voir document.formats) @msg “{shown}” opens {_1} files, not `{_2}` « {shown} » ouvre les fichiers {_1}, pas `{_2}` -@msg `{_1}` is a {_2}, not an importer `{_1}` est un {_2}, pas un module externe d’importation +@msg `{_1}` is a plug-in of kind `{_2}`, not an importer `{_1}` est un module externe de type `{_2}`, pas un module externe d’importation +@msg `{_1}` is a plug-in of kind `{_2}`, not an exporter `{_1}` est un module externe de type `{_2}`, pas un module externe d’exportation @msg `{_1}` is an importer: open a file with document.open {{"importer"}"}} `{_1}` est un module externe d’importation : ouvrez un fichier avec document.open {{"importer"}"}} @msg the importer returned no objects le module externe d’importation n’a renvoyé aucun objet @msg an importer returns `objects` and `warnings`, not `{key}` un module externe d’importation renvoie `objects` et `warnings`, pas `{key}` diff --git a/crates/ui-egui/src/i18n/hi.tsv b/crates/ui-egui/src/i18n/hi.tsv index 7a6de9d9d..9ed4c6f39 100644 --- a/crates/ui-egui/src/i18n/hi.tsv +++ b/crates/ui-egui/src/i18n/hi.tsv @@ -5376,7 +5376,7 @@ @msg `{_1}` can't be edited or removed `{_1}` को संपादित या हटाया नहीं जा सकता है @msg `{_1}` has no brushes to apply `{_1}` को लागू करने के लिए कोई ब्रश नहीं है @msg `{_1}` has no symbols to place `{_1}` के पास कोई सिंबल नहीं है -@msg `{_1}` is a {_2}, not an exporter `{_1}` एक {_2} है, एक निर्यातक नहीं है +@msg `{_1}` is a plug-in of kind `{_2}`, not an exporter `{_1}` `{_2}` प्रकार का प्लग-इन है, निर्यातक नहीं @msg `{_1}` is a live effect: apply it with effect.apply {{"effect"}"}} `{_1}` एक लाइव इफ़ेक्ट है: इसे effect.apply {{"effect"}"}} के साथ लागू करें @msg `{_1}` is an exporter: export with document.export {{"format"}"}} `{_1}` एक एक्सपोर्टर है: document.export {{"format"}"}} से एक्सपोर्ट करें @msg `{_1}` is built in and always listed `{_1}` बनाया गया है और हमेशा सूचीबद्ध है @@ -7969,7 +7969,7 @@ theme Appearance अपीयरेंस @msg missing `importer` (see document.formats) `importer` नहीं दिया गया (document.formats देखें) @msg `importer` must be a plug-in format id (see document.formats) `importer` किसी प्लग-इन का फ़ॉर्मेट id होना चाहिए (document.formats देखें) @msg “{shown}” opens {_1} files, not `{_2}` “{shown}” {_1} फ़ाइलें खोलता है, `{_2}` नहीं -@msg `{_1}` is a {_2}, not an importer `{_1}` एक {_2} है, इंपोर्टर नहीं +@msg `{_1}` is a plug-in of kind `{_2}`, not an importer `{_1}` `{_2}` प्रकार का प्लग-इन है, इंपोर्टर नहीं @msg `{_1}` is an importer: open a file with document.open {{"importer"}"}} `{_1}` एक इंपोर्टर है: document.open {{"importer"}"}} से फ़ाइल खोलें @msg the importer returned no objects इंपोर्टर ने कोई ऑब्जेक्ट नहीं लौटाया @msg an importer returns `objects` and `warnings`, not `{key}` इंपोर्टर `objects` और `warnings` लौटाता है, `{key}` नहीं diff --git a/crates/ui-egui/src/i18n/hu.tsv b/crates/ui-egui/src/i18n/hu.tsv index b0b517101..03f40e14c 100644 --- a/crates/ui-egui/src/i18n/hu.tsv +++ b/crates/ui-egui/src/i18n/hu.tsv @@ -6474,7 +6474,8 @@ breakText Glyphs Glifák @msg missing `importer` (see document.formats) hiányzik az `importer` (lásd document.formats) @msg `importer` must be a plug-in format id (see document.formats) az `importer` egy bővítmény formátumazonosítója kell legyen (lásd document.formats) @msg “{shown}” opens {_1} files, not `{_2}` „{shown}” {_1} fájlokat nyit meg, nem `{_2}` -@msg `{_1}` is a {_2}, not an importer `{_1}`: {_2}, nem importáló bővítmény +@msg `{_1}` is a plug-in of kind `{_2}`, not an importer `{_1}`: `{_2}` fajtájú bővítmény, nem importáló bővítmény +@msg `{_1}` is a plug-in of kind `{_2}`, not an exporter `{_1}`: `{_2}` fajtájú bővítmény, nem exportáló bővítmény @msg `{_1}` is an importer: open a file with document.open {{"importer"}"}} `{_1}` importáló bővítmény: nyisson meg egy fájlt a document.open {{"importer"}"}} paranccsal @msg the importer returned no objects az importáló bővítmény nem adott vissza objektumot @msg an importer returns `objects` and `warnings`, not `{key}` az importáló bővítmény `objects` és `warnings` értéket ad vissza, nem `{key}` diff --git a/crates/ui-egui/src/i18n/it.tsv b/crates/ui-egui/src/i18n/it.tsv index b9731552d..4b09769d3 100644 --- a/crates/ui-egui/src/i18n/it.tsv +++ b/crates/ui-egui/src/i18n/it.tsv @@ -6110,7 +6110,8 @@ breakText Glyphs Glifi @msg missing `importer` (see document.formats) manca `importer` (vedi document.formats) @msg `importer` must be a plug-in format id (see document.formats) `importer` deve essere l’id di formato di un plug-in (vedi document.formats) @msg “{shown}” opens {_1} files, not `{_2}` «{shown}» apre file {_1}, non `{_2}` -@msg `{_1}` is a {_2}, not an importer `{_1}` è un {_2}, non un plug-in di importazione +@msg `{_1}` is a plug-in of kind `{_2}`, not an importer `{_1}` è un plug-in di tipo `{_2}`, non un plug-in di importazione +@msg `{_1}` is a plug-in of kind `{_2}`, not an exporter `{_1}` è un plug-in di tipo `{_2}`, non un plug-in di esportazione @msg `{_1}` is an importer: open a file with document.open {{"importer"}"}} `{_1}` è un plug-in di importazione: apri un file con document.open {{"importer"}"}} @msg the importer returned no objects il plug-in di importazione non ha restituito alcun oggetto @msg an importer returns `objects` and `warnings`, not `{key}` un plug-in di importazione restituisce `objects` e `warnings`, non `{key}` diff --git a/crates/ui-egui/src/i18n/ja.tsv b/crates/ui-egui/src/i18n/ja.tsv index 128cf09ee..11e1b702b 100644 --- a/crates/ui-egui/src/i18n/ja.tsv +++ b/crates/ui-egui/src/i18n/ja.tsv @@ -6175,7 +6175,8 @@ breakText Glyphs 字形 @msg missing `importer` (see document.formats) `importer` がありません (document.formats を参照) @msg `importer` must be a plug-in format id (see document.formats) `importer` にはプラグインの形式 ID を指定してください (document.formats を参照) @msg “{shown}” opens {_1} files, not `{_2}` 「{shown}」が開くのは {_1} ファイルで、`{_2}` ではありません -@msg `{_1}` is a {_2}, not an importer `{_1}` は {_2} で、読み込みプラグインではありません +@msg `{_1}` is a plug-in of kind `{_2}`, not an importer `{_1}` は種類 `{_2}` のプラグインで、読み込みプラグインではありません +@msg `{_1}` is a plug-in of kind `{_2}`, not an exporter `{_1}` は種類 `{_2}` のプラグインで、書き出しプラグインではありません @msg `{_1}` is an importer: open a file with document.open {{"importer"}"}} `{_1}` は読み込みプラグインです: document.open {{"importer"}"}} でファイルを開いてください @msg the importer returned no objects 読み込みプラグインがオブジェクトを返しませんでした @msg an importer returns `objects` and `warnings`, not `{key}` 読み込みプラグインが返すのは `objects` と `warnings` で、`{key}` ではありません diff --git a/crates/ui-egui/src/i18n/ka.tsv b/crates/ui-egui/src/i18n/ka.tsv index bb91ca78f..5d5cb1300 100644 --- a/crates/ui-egui/src/i18n/ka.tsv +++ b/crates/ui-egui/src/i18n/ka.tsv @@ -6502,7 +6502,8 @@ font-script Japanese იაპონური @msg missing `importer` (see document.formats) `importer` აკლია (იხ. document.formats) @msg `importer` must be a plug-in format id (see document.formats) `importer` უნდა იყოს პლაგინის ფორმატის ID (იხ. document.formats) @msg “{shown}” opens {_1} files, not `{_2}` „{shown}“ ხსნის {_1} ფაილებს და არა `{_2}`-ს -@msg `{_1}` is a {_2}, not an importer `{_1}` არის {_2} და არა იმპორტის პლაგინი +@msg `{_1}` is a plug-in of kind `{_2}`, not an importer `{_1}` არის `{_2}` სახის პლაგინი და არა იმპორტის პლაგინი +@msg `{_1}` is a plug-in of kind `{_2}`, not an exporter `{_1}` არის `{_2}` სახის პლაგინი და არა ექსპორტის პლაგინი @msg `{_1}` is an importer: open a file with document.open {{"importer"}"}} `{_1}` იმპორტის პლაგინია: გახსენით ფაილი document.open {{"importer"}"}}-ით @msg the importer returned no objects იმპორტის პლაგინმა ობიექტები არ დააბრუნა @msg an importer returns `objects` and `warnings`, not `{key}` იმპორტის პლაგინი აბრუნებს `objects`-ს და `warnings`-ს და არა `{key}`-ს diff --git a/crates/ui-egui/src/i18n/ko.tsv b/crates/ui-egui/src/i18n/ko.tsv index 4c93a520d..fa09154e6 100644 --- a/crates/ui-egui/src/i18n/ko.tsv +++ b/crates/ui-egui/src/i18n/ko.tsv @@ -6071,7 +6071,8 @@ breakText Glyphs 글리프 @msg missing `importer` (see document.formats) `importer`가 없습니다(document.formats 참조) @msg `importer` must be a plug-in format id (see document.formats) `importer`는 플러그인의 형식 ID여야 합니다(document.formats 참조) @msg “{shown}” opens {_1} files, not `{_2}` “{shown}”은(는) {_1} 파일을 엽니다. `{_2}`은(는) 열지 않습니다 -@msg `{_1}` is a {_2}, not an importer `{_1}`은(는) {_2}이며 가져오기 플러그인이 아닙니다 +@msg `{_1}` is a plug-in of kind `{_2}`, not an importer `{_1}`은(는) `{_2}` 종류의 플러그인이며 가져오기 플러그인이 아닙니다 +@msg `{_1}` is a plug-in of kind `{_2}`, not an exporter `{_1}`은(는) `{_2}` 종류의 플러그인이며 내보내기 플러그인이 아닙니다 @msg `{_1}` is an importer: open a file with document.open {{"importer"}"}} `{_1}`은(는) 가져오기 플러그인입니다: document.open {{"importer"}"}}로 파일을 여세요 @msg the importer returned no objects 가져오기 플러그인이 개체를 반환하지 않았습니다 @msg an importer returns `objects` and `warnings`, not `{key}` 가져오기 플러그인은 `{key}`가 아닌 `objects`와 `warnings`를 반환합니다 diff --git a/crates/ui-egui/src/i18n/pl.tsv b/crates/ui-egui/src/i18n/pl.tsv index 4467230b7..72f9f1894 100644 --- a/crates/ui-egui/src/i18n/pl.tsv +++ b/crates/ui-egui/src/i18n/pl.tsv @@ -6345,7 +6345,8 @@ breakText Glyphs Glify @msg missing `importer` (see document.formats) brak `importer` (zobacz document.formats) @msg `importer` must be a plug-in format id (see document.formats) `importer` musi być identyfikatorem formatu wtyczki (zobacz document.formats) @msg “{shown}” opens {_1} files, not `{_2}` „{shown}” otwiera pliki {_1}, a nie `{_2}` -@msg `{_1}` is a {_2}, not an importer `{_1}` to {_2}, a nie wtyczka importu +@msg `{_1}` is a plug-in of kind `{_2}`, not an importer `{_1}` to wtyczka rodzaju `{_2}`, a nie wtyczka importu +@msg `{_1}` is a plug-in of kind `{_2}`, not an exporter `{_1}` to wtyczka rodzaju `{_2}`, a nie wtyczka eksportu @msg `{_1}` is an importer: open a file with document.open {{"importer"}"}} `{_1}` to wtyczka importu: otwórz plik za pomocą document.open {{"importer"}"}} @msg the importer returned no objects wtyczka importu nie zwróciła żadnych obiektów @msg an importer returns `objects` and `warnings`, not `{key}` wtyczka importu zwraca `objects` i `warnings`, a nie `{key}` diff --git a/crates/ui-egui/src/i18n/pt-br.tsv b/crates/ui-egui/src/i18n/pt-br.tsv index 3fae0ea3a..22fd661a9 100644 --- a/crates/ui-egui/src/i18n/pt-br.tsv +++ b/crates/ui-egui/src/i18n/pt-br.tsv @@ -6563,7 +6563,8 @@ swatch Yellow Green Verde-amarelado @msg missing `importer` (see document.formats) falta `importer` (consulte document.formats) @msg `importer` must be a plug-in format id (see document.formats) `importer` deve ser o id de formato de um plug-in (consulte document.formats) @msg “{shown}” opens {_1} files, not `{_2}` “{shown}” abre arquivos {_1}, não `{_2}` -@msg `{_1}` is a {_2}, not an importer `{_1}` é um {_2}, não um plug-in de importação +@msg `{_1}` is a plug-in of kind `{_2}`, not an importer `{_1}` é um plug-in do tipo `{_2}`, não um plug-in de importação +@msg `{_1}` is a plug-in of kind `{_2}`, not an exporter `{_1}` é um plug-in do tipo `{_2}`, não um plug-in de exportação @msg `{_1}` is an importer: open a file with document.open {{"importer"}"}} `{_1}` é um plug-in de importação: abra um arquivo com document.open {{"importer"}"}} @msg the importer returned no objects o plug-in de importação não retornou nenhum objeto @msg an importer returns `objects` and `warnings`, not `{key}` um plug-in de importação retorna `objects` e `warnings`, não `{key}` diff --git a/crates/ui-egui/src/i18n/ru.tsv b/crates/ui-egui/src/i18n/ru.tsv index 33f826525..1193f43ef 100644 --- a/crates/ui-egui/src/i18n/ru.tsv +++ b/crates/ui-egui/src/i18n/ru.tsv @@ -6579,7 +6579,8 @@ shape Open Открытый @msg missing `importer` (see document.formats) не указан `importer` (см. document.formats) @msg `importer` must be a plug-in format id (see document.formats) `importer` должен быть идентификатором формата модуля (см. document.formats) @msg “{shown}” opens {_1} files, not `{_2}` «{shown}» открывает файлы {_1}, а не `{_2}` -@msg `{_1}` is a {_2}, not an importer `{_1}` — это {_2}, а не модуль импорта +@msg `{_1}` is a plug-in of kind `{_2}`, not an importer `{_1}` является модулем вида `{_2}`, а не модулем импорта +@msg `{_1}` is a plug-in of kind `{_2}`, not an exporter `{_1}` является модулем вида `{_2}`, а не модулем экспорта @msg `{_1}` is an importer: open a file with document.open {{"importer"}"}} `{_1}` — модуль импорта: откройте файл с помощью document.open {{"importer"}"}} @msg the importer returned no objects модуль импорта не вернул ни одного объекта @msg an importer returns `objects` and `warnings`, not `{key}` модуль импорта возвращает `objects` и `warnings`, а не `{key}` diff --git a/crates/ui-egui/src/i18n/sv.tsv b/crates/ui-egui/src/i18n/sv.tsv index ee1822273..85ed00f85 100644 --- a/crates/ui-egui/src/i18n/sv.tsv +++ b/crates/ui-egui/src/i18n/sv.tsv @@ -6643,7 +6643,7 @@ digits Hindi Hindi @msg {what} points outside memory {what} pekar utanför minnet @msg {what} would print on more than {MAX_TILES} tiles: scale it down {what} skulle skrivas ut på fler än {MAX_TILES} rutor: skala ned det @msg `{_1}` can't be edited or removed `{_1}` kan inte redigeras eller tas bort -@msg `{_1}` is a {_2}, not an exporter `{_1}` är av typen {_2}, inte en exportfunktion +@msg `{_1}` is a plug-in of kind `{_2}`, not an exporter `{_1}` är ett plugin av typen `{_2}`, inte en exportfunktion @msg `{_1}` is a live effect: apply it with effect.apply {{"effect"}"}} `{_1}` är en live-effekt: använd den med effect.apply {{"effect"}"}} @msg `{_1}` is an exporter: export with document.export {{"format"}"}} `{_1}` är en exportfunktion: exportera med document.export {{"format"}"}} @msg `{_1}` is built in and always listed `{_1}` är inbyggd och listas alltid @@ -7977,7 +7977,7 @@ digits Hindi Hindi @msg missing `importer` (see document.formats) `importer` saknas (se document.formats) @msg `importer` must be a plug-in format id (see document.formats) `importer` måste vara ett formatid för ett plugin (se document.formats) @msg “{shown}” opens {_1} files, not `{_2}` ”{shown}” öppnar {_1}-filer, inte `{_2}` -@msg `{_1}` is a {_2}, not an importer `{_1}` är av typen {_2}, inte en importfunktion +@msg `{_1}` is a plug-in of kind `{_2}`, not an importer `{_1}` är ett plugin av typen `{_2}`, inte en importfunktion @msg `{_1}` is an importer: open a file with document.open {{"importer"}"}} `{_1}` är en importfunktion: öppna en fil med document.open {{"importer"}"}} @msg the importer returned no objects importfunktionen returnerade inga objekt @msg an importer returns `objects` and `warnings`, not `{key}` en importfunktion returnerar `objects` och `warnings`, inte `{key}` diff --git a/crates/ui-egui/src/i18n/tr.tsv b/crates/ui-egui/src/i18n/tr.tsv index fb4269e2f..0d2960564 100644 --- a/crates/ui-egui/src/i18n/tr.tsv +++ b/crates/ui-egui/src/i18n/tr.tsv @@ -6447,7 +6447,8 @@ breakText Glyphs Glifler @msg missing `importer` (see document.formats) `importer` eksik (bkz. document.formats) @msg `importer` must be a plug-in format id (see document.formats) `importer` bir eklentinin biçim kimliği olmalıdır (bkz. document.formats) @msg “{shown}” opens {_1} files, not `{_2}` “{shown}” {_1} dosyalarını açar, `{_2}` dosyasını değil -@msg `{_1}` is a {_2}, not an importer `{_1}` bir {_2}, içe aktarma eklentisi değil +@msg `{_1}` is a plug-in of kind `{_2}`, not an importer `{_1}`, `{_2}` türünde bir eklentidir, içe aktarma eklentisi değildir +@msg `{_1}` is a plug-in of kind `{_2}`, not an exporter `{_1}`, `{_2}` türünde bir eklentidir, dışa aktarma eklentisi değildir @msg `{_1}` is an importer: open a file with document.open {{"importer"}"}} `{_1}` bir içe aktarma eklentisidir: dosyayı document.open {{"importer"}"}} ile açın @msg the importer returned no objects içe aktarma eklentisi hiç nesne döndürmedi @msg an importer returns `objects` and `warnings`, not `{key}` içe aktarma eklentisi `{key}` değil, `objects` ve `warnings` döndürür diff --git a/crates/ui-egui/src/i18n/uk.tsv b/crates/ui-egui/src/i18n/uk.tsv index ac74a7404..18475a371 100644 --- a/crates/ui-egui/src/i18n/uk.tsv +++ b/crates/ui-egui/src/i18n/uk.tsv @@ -6090,7 +6090,8 @@ breakText Glyphs Гліфи @msg missing `importer` (see document.formats) не вказано `importer` (див. document.formats) @msg `importer` must be a plug-in format id (see document.formats) `importer` має бути ідентифікатором формату модуля (див. document.formats) @msg “{shown}” opens {_1} files, not `{_2}` «{shown}» відкриває файли {_1}, а не `{_2}` -@msg `{_1}` is a {_2}, not an importer `{_1}` - це {_2}, а не модуль імпорту +@msg `{_1}` is a plug-in of kind `{_2}`, not an importer `{_1}` є модулем виду `{_2}`, а не модулем імпорту +@msg `{_1}` is a plug-in of kind `{_2}`, not an exporter `{_1}` є модулем виду `{_2}`, а не модулем експорту @msg `{_1}` is an importer: open a file with document.open {{"importer"}"}} `{_1}` - модуль імпорту: відкрийте файл за допомогою document.open {{"importer"}"}} @msg the importer returned no objects модуль імпорту не повернув жодного об’єкта @msg an importer returns `objects` and `warnings`, not `{key}` модуль імпорту повертає `objects` і `warnings`, а не `{key}` diff --git a/crates/ui-egui/src/i18n/vi.tsv b/crates/ui-egui/src/i18n/vi.tsv index 04c59cf6b..7491f1c22 100644 --- a/crates/ui-egui/src/i18n/vi.tsv +++ b/crates/ui-egui/src/i18n/vi.tsv @@ -6091,7 +6091,8 @@ breakText Glyphs Glyph @msg missing `importer` (see document.formats) thiếu `importer` (xem document.formats) @msg `importer` must be a plug-in format id (see document.formats) `importer` phải là id định dạng của một plug-in (xem document.formats) @msg “{shown}” opens {_1} files, not `{_2}` “{shown}” mở tệp {_1}, không phải `{_2}` -@msg `{_1}` is a {_2}, not an importer `{_1}` là {_2}, không phải plug-in nhập +@msg `{_1}` is a plug-in of kind `{_2}`, not an importer `{_1}` là plug-in loại `{_2}`, không phải plug-in nhập +@msg `{_1}` is a plug-in of kind `{_2}`, not an exporter `{_1}` là plug-in loại `{_2}`, không phải plug-in xuất @msg `{_1}` is an importer: open a file with document.open {{"importer"}"}} `{_1}` là plug-in nhập: hãy mở tệp bằng document.open {{"importer"}"}} @msg the importer returned no objects plug-in nhập không trả về đối tượng nào @msg an importer returns `objects` and `warnings`, not `{key}` plug-in nhập trả về `objects` và `warnings`, không phải `{key}` diff --git a/crates/ui-egui/src/i18n/zh-hans.tsv b/crates/ui-egui/src/i18n/zh-hans.tsv index 188fafbac..3896cb184 100644 --- a/crates/ui-egui/src/i18n/zh-hans.tsv +++ b/crates/ui-egui/src/i18n/zh-hans.tsv @@ -6331,7 +6331,8 @@ breakText Glyphs 字形 @msg missing `importer` (see document.formats) 缺少 `importer` (参见 document.formats) @msg `importer` must be a plug-in format id (see document.formats) `importer` 必须是增效工具的格式 ID (参见 document.formats) @msg “{shown}” opens {_1} files, not `{_2}` “{shown}” 打开的是 {_1} 文件,不是 `{_2}` -@msg `{_1}` is a {_2}, not an importer `{_1}` 是 {_2},不是导入增效工具 +@msg `{_1}` is a plug-in of kind `{_2}`, not an importer `{_1}` 是 `{_2}` 类型的增效工具,不是导入增效工具 +@msg `{_1}` is a plug-in of kind `{_2}`, not an exporter `{_1}` 是 `{_2}` 类型的增效工具,不是导出增效工具 @msg `{_1}` is an importer: open a file with document.open {{"importer"}"}} `{_1}` 是导入增效工具:请用 document.open {{"importer"}"}} 打开文件 @msg the importer returned no objects 导入增效工具未返回任何对象 @msg an importer returns `objects` and `warnings`, not `{key}` 导入增效工具返回 `objects` 和 `warnings`,不是 `{key}` diff --git a/crates/ui-egui/src/i18n/zh-hant.tsv b/crates/ui-egui/src/i18n/zh-hant.tsv index 0e9326ec5..a4d3cbf72 100644 --- a/crates/ui-egui/src/i18n/zh-hant.tsv +++ b/crates/ui-egui/src/i18n/zh-hant.tsv @@ -6128,7 +6128,8 @@ breakText Glyphs 字符 @msg missing `importer` (see document.formats) 未提供 `importer` (請參閱 document.formats) @msg `importer` must be a plug-in format id (see document.formats) `importer` 必須是增效模組的格式 ID (請參閱 document.formats) @msg “{shown}” opens {_1} files, not `{_2}` 「{shown}」開啟的是 {_1} 檔案,不是 `{_2}` -@msg `{_1}` is a {_2}, not an importer `{_1}` 是 {_2},不是匯入增效模組 +@msg `{_1}` is a plug-in of kind `{_2}`, not an importer `{_1}` 是 `{_2}` 類型的增效模組,不是匯入增效模組 +@msg `{_1}` is a plug-in of kind `{_2}`, not an exporter `{_1}` 是 `{_2}` 類型的增效模組,不是匯出增效模組 @msg `{_1}` is an importer: open a file with document.open {{"importer"}"}} `{_1}` 是匯入增效模組:請用 document.open {{"importer"}"}} 開啟檔案 @msg the importer returned no objects 匯入增效模組未傳回任何物件 @msg an importer returns `objects` and `warnings`, not `{key}` 匯入增效模組傳回 `objects` 和 `warnings`,不是 `{key}` diff --git a/docs/plugins.md b/docs/plugins.md index eb4537e17..9bae546a8 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -69,7 +69,10 @@ extensions with that importer (on the web, File › Open's picker opens instead) desktop the importer runs off the UI thread, and a run that takes a while shows a progress window with Cancel, which stops it. An importer with parameters, given no `params`, asks for them in a dialog of the same kind once the file is picked, and its Open -button opens the file; File › Open runs an importer with its parameters' defaults. **File › Open** of a `.wasm` file installs +button opens the file; File › Open runs an importer with its parameters' defaults. Open Recent opens a file the way +File › Open does: it does not remember the importer or the parameters given to Open With. A built-in format reads the +file if one can, and otherwise the first importer by id that lists its extension reads it with its parameters' defaults. +**File › Open** of a `.wasm` file installs a plug-in too (on the web this is how plug-ins get in). A heavy filter asks before it is installed, and runs in the background ([below](#heavy-filters)). A plug-in that lists permissions asks for them before it is installed ([below](#permissions)).