From 3429bbc76a6a9ee363756969e8d19aa4a5d335f9 Mon Sep 17 00:00:00 2001 From: dotCooCoo Date: Fri, 13 Nov 2026 14:16:15 -0800 Subject: [PATCH] Save, Export for Screens: warnings name an option the file doesn't read The save commands' warnings now follow an export's .ai rules: a legacy .ai file (aiVersion "7") reads only its own options, and the other .ai and .ait files don't read outlineText, hiddenObjects, transparentImages or preserveEditing. They name any option given beside the path that the file doesn't read, not only compress, version, preview and precision, and any such key in options. The bytes a save writes don't change. The Save Options dialog sends a .ai save only the options the chosen version reads, so a save from the dialog gets none of these warnings. When the document's own file is already a .ai, the .ai options that a save doesn't give and its file doesn't read keep their remembered values, so the dialog still shows them; the save doesn't write them, and a retry in another folder doesn't send them. Export for Screens and Export Assets already accepted a key in a format row or in a format's settings that only another format takes. Their warnings now name it as given (formats[0].quality, settings.png.quality). A key in a format's settings is named only when no row of that format, as the export writes it, reads it. The options of an exportPreset, and for assets.export the settings the document keeps, get no warning. Docs: params text of document.save, document.exportForScreens and assets.export; docs/mcp.md; docs/target-app-parity.md. --- crates/engine/src/cmd/assets.rs | 4 +- crates/engine/src/cmd/fileio.rs | 2 +- crates/engine/src/cmd/fileio/commands.rs | 2 +- crates/engine/src/cmd/fileio/export.rs | 27 +++-- crates/engine/src/cmd/fileio/save.rs | 79 +++++++++++++-- crates/engine/src/cmd/fileio/screens.rs | 94 ++++++++++++++++-- crates/engine/src/cmd/fileio/tests.rs | 4 +- .../engine/src/cmd/fileio/tests_exportas.rs | 99 +++++++++++++++++++ crates/engine/src/cmd/fileio/tests_screens.rs | 90 +++++++++++++++++ crates/engine/src/cmd/recovery.rs | 1 + crates/mcp/src/tests/fileio.rs | 10 +- crates/ui-egui/src/dialogs/save_options.rs | 10 +- .../ui-egui/src/dialogs/save_options/tests.rs | 27 +++++ crates/ui-egui/src/dialogs/tests_screens.rs | 33 +++++++ docs/mcp.md | 18 +++- docs/target-app-parity.md | 2 +- 16 files changed, 452 insertions(+), 50 deletions(-) diff --git a/crates/engine/src/cmd/assets.rs b/crates/engine/src/cmd/assets.rs index 1ebde5c026..e30e6efcdc 100644 --- a/crates/engine/src/cmd/assets.rs +++ b/crates/engine/src/cmd/assets.rs @@ -53,7 +53,7 @@ pub fn specs() -> Vec { "Export Assets", [], None, - "{assets?: [asset id…] (default all but the 3D assets, which assets.export3D writes), folder?, zip?, openLocation?, formats?, preset?, settings?, prefix?, subfolders?, antiAlias?} each asset's art alone, cropped to it, in every format row: document.exportForScreens {assets} at the document's export settings (document.exportSettings) under the ones given; with subfolders false every file goes into the folder itself, mobile and density rows too → what document.exportForScreens returns (no folder: the files, or one zip, as dataBase64). Leaves the remembered settings as they are (assets.settings.set changes them)", + "{assets?: [asset id…] (default all but the 3D assets, which assets.export3D writes), folder?, zip?, openLocation?, formats?, preset?, settings?, prefix?, subfolders?, antiAlias?} each asset's art alone, cropped to it, in every format row: document.exportForScreens {assets} at the document's export settings (document.exportSettings) under the ones given; with subfolders false every file goes into the folder itself, mobile and density rows too → what document.exportForScreens returns (no folder: the files, or one zip, as dataBase64; warnings name a key in the rows or settings given that only another format takes, not one in the remembered settings). Leaves the remembered settings as they are (assets.settings.set changes them)", has_doc, export ), @@ -429,7 +429,7 @@ fn export(s: &mut Session, p: &Value) -> Result { } q.insert("assets".into(), json!(all)); } - export_screens(s, &Value::Object(q)).map_err(|e| of_cmd(C, e)) + export_screens(s, &Value::Object(q), p).map_err(|e| of_cmd(C, e)) } fn settings_set(s: &mut Session, p: &Value) -> Result { diff --git a/crates/engine/src/cmd/fileio.rs b/crates/engine/src/cmd/fileio.rs index 9154ce7ee5..97f957ed0e 100644 --- a/crates/engine/src/cmd/fileio.rs +++ b/crates/engine/src/cmd/fileio.rs @@ -92,7 +92,7 @@ pub use pdfimport::{LoadOptions, page_document}; pub(crate) use save::job_for; pub(crate) use save::save as save_document; pub use save::{ - SAVE_FORMATS, SaveJob, SaveMode, SavePlan, StreamWrite, TEMPLATE_FORMATS, dialog_folder, documents_dialog_folder, export_folder, + SAVE_FORMATS, SaveJob, SaveMode, SavePlan, StreamWrite, TEMPLATE_FORMATS, dialog_folder, documents_dialog_folder, export_folder, file_reads, leave_out_unreadable_save_paths, reads_option as save_reads_option, remembered_save_options, save_filters, save_format, save_job, save_plan, save_with, stamp_save_dates, template_filters, templates_dialog_folder, templates_folder, }; diff --git a/crates/engine/src/cmd/fileio/commands.rs b/crates/engine/src/cmd/fileio/commands.rs index 5abe3e879c..e7656bb6d0 100644 --- a/crates/engine/src/cmd/fileio/commands.rs +++ b/crates/engine/src/cmd/fileio/commands.rs @@ -54,7 +54,7 @@ pub fn specs() -> Vec { "Export for Screens", ["File", "Export"], None, - "{folder?, zip?: false (one .zip of every file, each deflated or stored, whichever is smaller: no folder → {name, dataBase64, bytes, files: [name…]}; with a folder it is written there → {path, bytes, files}), artboard?: index | artboards?: [index…] | range?: \"1-3\" (default all), assets?: [asset id…] (instead of artboards: each asset's art alone, cropped to its bounds and named after the asset; see assets.list), layers?: [layer id…] (instead of artboards: each layer's art alone, sublayers included, named after the layer), selection?: one|each (instead of artboards: the selected art as one file, or a file per selected object, named after it), fullDocument?: false (one file per format instead: a PDF of every artboard, other formats the bounds of all visible art, named after the document), includeBleed?: false (artboards grown by the document's bleed), includeArtboardFill?: true (Include Artboard Fill: each artboard's background color behind its art; false leaves it out), pdfs?: multiple|single (Export PDFs As: with several artboards, single writes them as the pages of one PDF per PDF row, named after the document), exportPreset?: (a preset of document.exportPresets.list: its settings, under these params), subfolders?: false (each row's files in a sub-folder: its folder, else its size for raster (1x, 2x, 100w…) or its format (SVG, PDF)), folders?: none|rows (as subfolders)|format (a folder per extension: png, svg, pdf…)|item (a folder per artboard, asset, layer or object)|itemFormat (item/extension) (default: rows with subfolders or a preset, else none), name?: (a file name pattern instead of the item's name, with for the document, for the artboard, asset, layer or object, from 1, #### for the counter zero-padded to the run of #, , , (else the row's suffix ends the name), YYYYMMDD, YYYY-MM-DD, YYYY, ,