From 612bb26a8cd31a6bdc85ef2ab9fceac1052407b3 Mon Sep 17 00:00:00 2001 From: ramox81 <184937705+ramox81@users.noreply.github.com> Date: Mon, 5 Oct 2026 10:53:45 +0300 Subject: [PATCH] Sheet sets: reference menu order, new sheets stay closed, .dst reload, navigation fields The tree menus follow the reference per row kind (New Sheet / Import on a sheet work on its subset, Remove Subset only while empty, Rename Subset), a new sheet is not opened, an open set reloads when its .dst changes on disk, ViewportScale placeholders take the version of their format and the codec pin moves to the revision with navigation fields. Co-Authored-By: Claude Opus 5.5 --- Cargo.lock | 2 +- Cargo.toml | 2 +- locales/ar-SA/opencadstudio.ftl | 1 + locales/bg-BG/opencadstudio.ftl | 1 + locales/cs-CZ/opencadstudio.ftl | 1 + locales/de-DE/opencadstudio.ftl | 1 + locales/el-GR/opencadstudio.ftl | 1 + locales/en-US/opencadstudio.ftl | 1 + locales/es-ES/opencadstudio.ftl | 1 + locales/fi-FI/opencadstudio.ftl | 1 + locales/fr-FR/opencadstudio.ftl | 1 + locales/hi-IN/opencadstudio.ftl | 1 + locales/hu-HU/opencadstudio.ftl | 1 + locales/it-IT/opencadstudio.ftl | 1 + locales/ja-JP/opencadstudio.ftl | 1 + locales/ko-KR/opencadstudio.ftl | 1 + locales/nl-NL/opencadstudio.ftl | 1 + locales/pl-PL/opencadstudio.ftl | 1 + locales/pt-BR/opencadstudio.ftl | 1 + locales/ru-RU/opencadstudio.ftl | 1 + locales/tr-TR/opencadstudio.ftl | 1 + locales/zh-CN/opencadstudio.ftl | 1 + locales/zh-TW/opencadstudio.ftl | 1 + src/app/commands/sheet_set.rs | 41 ++++++++++++++++++++++++++-- src/app/view/mod.rs | 11 ++++++++ src/locale_catalog.rs | 1 + src/ui/window/field_dialog.rs | 8 ++++-- src/ui/window/sheet_set.rs | 47 ++++++++++++++++++++++----------- 28 files changed, 112 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7d6d8182e..864e44cb2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4206,7 +4206,7 @@ dependencies = [ [[package]] name = "opencadcodec" version = "0.5.5" -source = "git+https://github.com/ramox81/cadcodec.git?rev=19aec85#19aec855cf38d1dbdaf32d09c69343fc479bfbf9" +source = "git+https://github.com/ramox81/cadcodec.git?rev=3f5d40a#3f5d40a82368cd2dd5e5c44388f8630647ff3533" dependencies = [ "ahash 0.8.12", "anyhow", diff --git a/Cargo.toml b/Cargo.toml index c59d8bd1c..8efe2a874 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -91,7 +91,7 @@ block2 = "0.5" objc2-foundation = { version = "0.2", features = ["NSArray", "NSURL", "NSString", "NSObject", "NSNotification", "NSThread", "NSEnumerator"] } [patch."https://github.com/HakanSeven12/opencadcodec.git"] -opencadcodec = { git = "https://github.com/ramox81/cadcodec.git", rev = "19aec85" } +opencadcodec = { git = "https://github.com/ramox81/cadcodec.git", rev = "3f5d40a" } [patch.crates-io] iced_core = { git = "https://github.com/iced-rs/iced.git", rev = "23604ff22ab0aad9e00b9327cb7b8546ed84db39" } diff --git a/locales/ar-SA/opencadstudio.ftl b/locales/ar-SA/opencadstudio.ftl index e683b8007..20ccb54ce 100644 --- a/locales/ar-SA/opencadstudio.ftl +++ b/locales/ar-SA/opencadstudio.ftl @@ -4406,6 +4406,7 @@ view = .ss-subset-name = Subset name .ss-new-sheet-location = New sheet location .ss-remove-subset = Remove Subset + .ss-rename-subset = Rename Subset... .ss-remove-sheet = Remove Sheet .ss-lets-you-specify-one-or-more-folders-containing-drawings-the = Lets you specify one or more folders containing drawings. The layouts from these drawings can be automatically imported into the sheet set. .ss-creates-a-sheet-set-with-no-subsets-or-sheets = Creates a sheet set with no subsets or sheets. diff --git a/locales/bg-BG/opencadstudio.ftl b/locales/bg-BG/opencadstudio.ftl index d9c92b35f..457edab5c 100644 --- a/locales/bg-BG/opencadstudio.ftl +++ b/locales/bg-BG/opencadstudio.ftl @@ -4393,6 +4393,7 @@ view = .ss-subset-name = Subset name .ss-new-sheet-location = New sheet location .ss-remove-subset = Remove Subset + .ss-rename-subset = Rename Subset... .ss-remove-sheet = Remove Sheet .ss-lets-you-specify-one-or-more-folders-containing-drawings-the = Lets you specify one or more folders containing drawings. The layouts from these drawings can be automatically imported into the sheet set. .ss-creates-a-sheet-set-with-no-subsets-or-sheets = Creates a sheet set with no subsets or sheets. diff --git a/locales/cs-CZ/opencadstudio.ftl b/locales/cs-CZ/opencadstudio.ftl index 26d9d317d..762a52473 100644 --- a/locales/cs-CZ/opencadstudio.ftl +++ b/locales/cs-CZ/opencadstudio.ftl @@ -4391,6 +4391,7 @@ view = .ss-subset-name = Subset name .ss-new-sheet-location = New sheet location .ss-remove-subset = Remove Subset + .ss-rename-subset = Rename Subset... .ss-remove-sheet = Remove Sheet .ss-lets-you-specify-one-or-more-folders-containing-drawings-the = Lets you specify one or more folders containing drawings. The layouts from these drawings can be automatically imported into the sheet set. .ss-creates-a-sheet-set-with-no-subsets-or-sheets = Creates a sheet set with no subsets or sheets. diff --git a/locales/de-DE/opencadstudio.ftl b/locales/de-DE/opencadstudio.ftl index 0d4326f9f..14b3a2d12 100644 --- a/locales/de-DE/opencadstudio.ftl +++ b/locales/de-DE/opencadstudio.ftl @@ -4392,6 +4392,7 @@ view = .ss-subset-name = Subset name .ss-new-sheet-location = New sheet location .ss-remove-subset = Remove Subset + .ss-rename-subset = Rename Subset... .ss-remove-sheet = Remove Sheet .ss-lets-you-specify-one-or-more-folders-containing-drawings-the = Lets you specify one or more folders containing drawings. The layouts from these drawings can be automatically imported into the sheet set. .ss-creates-a-sheet-set-with-no-subsets-or-sheets = Creates a sheet set with no subsets or sheets. diff --git a/locales/el-GR/opencadstudio.ftl b/locales/el-GR/opencadstudio.ftl index 088975020..e393c26e6 100644 --- a/locales/el-GR/opencadstudio.ftl +++ b/locales/el-GR/opencadstudio.ftl @@ -4394,6 +4394,7 @@ view = .ss-subset-name = Subset name .ss-new-sheet-location = New sheet location .ss-remove-subset = Remove Subset + .ss-rename-subset = Rename Subset... .ss-remove-sheet = Remove Sheet .ss-lets-you-specify-one-or-more-folders-containing-drawings-the = Lets you specify one or more folders containing drawings. The layouts from these drawings can be automatically imported into the sheet set. .ss-creates-a-sheet-set-with-no-subsets-or-sheets = Creates a sheet set with no subsets or sheets. diff --git a/locales/en-US/opencadstudio.ftl b/locales/en-US/opencadstudio.ftl index 6a642c267..d7498da27 100644 --- a/locales/en-US/opencadstudio.ftl +++ b/locales/en-US/opencadstudio.ftl @@ -4395,6 +4395,7 @@ view = .ss-subset-name = Subset name .ss-new-sheet-location = New sheet location .ss-remove-subset = Remove Subset + .ss-rename-subset = Rename Subset... .ss-remove-sheet = Remove Sheet .ss-lets-you-specify-one-or-more-folders-containing-drawings-the = Lets you specify one or more folders containing drawings. The layouts from these drawings can be automatically imported into the sheet set. .ss-creates-a-sheet-set-with-no-subsets-or-sheets = Creates a sheet set with no subsets or sheets. diff --git a/locales/es-ES/opencadstudio.ftl b/locales/es-ES/opencadstudio.ftl index 19f7707f2..c62ac3377 100644 --- a/locales/es-ES/opencadstudio.ftl +++ b/locales/es-ES/opencadstudio.ftl @@ -4394,6 +4394,7 @@ view = .ss-subset-name = Subset name .ss-new-sheet-location = New sheet location .ss-remove-subset = Remove Subset + .ss-rename-subset = Rename Subset... .ss-remove-sheet = Remove Sheet .ss-lets-you-specify-one-or-more-folders-containing-drawings-the = Lets you specify one or more folders containing drawings. The layouts from these drawings can be automatically imported into the sheet set. .ss-creates-a-sheet-set-with-no-subsets-or-sheets = Creates a sheet set with no subsets or sheets. diff --git a/locales/fi-FI/opencadstudio.ftl b/locales/fi-FI/opencadstudio.ftl index 7750d75d1..cf0c70d6b 100644 --- a/locales/fi-FI/opencadstudio.ftl +++ b/locales/fi-FI/opencadstudio.ftl @@ -4393,6 +4393,7 @@ view = .ss-subset-name = Subset name .ss-new-sheet-location = New sheet location .ss-remove-subset = Remove Subset + .ss-rename-subset = Rename Subset... .ss-remove-sheet = Remove Sheet .ss-lets-you-specify-one-or-more-folders-containing-drawings-the = Lets you specify one or more folders containing drawings. The layouts from these drawings can be automatically imported into the sheet set. .ss-creates-a-sheet-set-with-no-subsets-or-sheets = Creates a sheet set with no subsets or sheets. diff --git a/locales/fr-FR/opencadstudio.ftl b/locales/fr-FR/opencadstudio.ftl index 12951271d..3392b9e2a 100644 --- a/locales/fr-FR/opencadstudio.ftl +++ b/locales/fr-FR/opencadstudio.ftl @@ -4394,6 +4394,7 @@ view = .ss-subset-name = Subset name .ss-new-sheet-location = New sheet location .ss-remove-subset = Remove Subset + .ss-rename-subset = Rename Subset... .ss-remove-sheet = Remove Sheet .ss-lets-you-specify-one-or-more-folders-containing-drawings-the = Lets you specify one or more folders containing drawings. The layouts from these drawings can be automatically imported into the sheet set. .ss-creates-a-sheet-set-with-no-subsets-or-sheets = Creates a sheet set with no subsets or sheets. diff --git a/locales/hi-IN/opencadstudio.ftl b/locales/hi-IN/opencadstudio.ftl index 0737d9ea8..0d2435a77 100644 --- a/locales/hi-IN/opencadstudio.ftl +++ b/locales/hi-IN/opencadstudio.ftl @@ -4382,6 +4382,7 @@ view = .ss-subset-name = Subset name .ss-new-sheet-location = New sheet location .ss-remove-subset = Remove Subset + .ss-rename-subset = Rename Subset... .ss-remove-sheet = Remove Sheet .ss-lets-you-specify-one-or-more-folders-containing-drawings-the = Lets you specify one or more folders containing drawings. The layouts from these drawings can be automatically imported into the sheet set. .ss-creates-a-sheet-set-with-no-subsets-or-sheets = Creates a sheet set with no subsets or sheets. diff --git a/locales/hu-HU/opencadstudio.ftl b/locales/hu-HU/opencadstudio.ftl index 7b4c83a21..7b4b9834c 100644 --- a/locales/hu-HU/opencadstudio.ftl +++ b/locales/hu-HU/opencadstudio.ftl @@ -4393,6 +4393,7 @@ view = .ss-subset-name = Subset name .ss-new-sheet-location = New sheet location .ss-remove-subset = Remove Subset + .ss-rename-subset = Rename Subset... .ss-remove-sheet = Remove Sheet .ss-lets-you-specify-one-or-more-folders-containing-drawings-the = Lets you specify one or more folders containing drawings. The layouts from these drawings can be automatically imported into the sheet set. .ss-creates-a-sheet-set-with-no-subsets-or-sheets = Creates a sheet set with no subsets or sheets. diff --git a/locales/it-IT/opencadstudio.ftl b/locales/it-IT/opencadstudio.ftl index 8c3dbd1e5..9cf03a923 100644 --- a/locales/it-IT/opencadstudio.ftl +++ b/locales/it-IT/opencadstudio.ftl @@ -4393,6 +4393,7 @@ view = .ss-subset-name = Subset name .ss-new-sheet-location = New sheet location .ss-remove-subset = Remove Subset + .ss-rename-subset = Rename Subset... .ss-remove-sheet = Remove Sheet .ss-lets-you-specify-one-or-more-folders-containing-drawings-the = Lets you specify one or more folders containing drawings. The layouts from these drawings can be automatically imported into the sheet set. .ss-creates-a-sheet-set-with-no-subsets-or-sheets = Creates a sheet set with no subsets or sheets. diff --git a/locales/ja-JP/opencadstudio.ftl b/locales/ja-JP/opencadstudio.ftl index 39769ff96..1479bab43 100644 --- a/locales/ja-JP/opencadstudio.ftl +++ b/locales/ja-JP/opencadstudio.ftl @@ -4382,6 +4382,7 @@ view = .ss-subset-name = Subset name .ss-new-sheet-location = New sheet location .ss-remove-subset = Remove Subset + .ss-rename-subset = Rename Subset... .ss-remove-sheet = Remove Sheet .ss-lets-you-specify-one-or-more-folders-containing-drawings-the = Lets you specify one or more folders containing drawings. The layouts from these drawings can be automatically imported into the sheet set. .ss-creates-a-sheet-set-with-no-subsets-or-sheets = Creates a sheet set with no subsets or sheets. diff --git a/locales/ko-KR/opencadstudio.ftl b/locales/ko-KR/opencadstudio.ftl index 41a78c6eb..29fa2501e 100644 --- a/locales/ko-KR/opencadstudio.ftl +++ b/locales/ko-KR/opencadstudio.ftl @@ -4393,6 +4393,7 @@ view = .ss-subset-name = Subset name .ss-new-sheet-location = New sheet location .ss-remove-subset = Remove Subset + .ss-rename-subset = Rename Subset... .ss-remove-sheet = Remove Sheet .ss-lets-you-specify-one-or-more-folders-containing-drawings-the = Lets you specify one or more folders containing drawings. The layouts from these drawings can be automatically imported into the sheet set. .ss-creates-a-sheet-set-with-no-subsets-or-sheets = Creates a sheet set with no subsets or sheets. diff --git a/locales/nl-NL/opencadstudio.ftl b/locales/nl-NL/opencadstudio.ftl index 881b8941a..c9b107482 100644 --- a/locales/nl-NL/opencadstudio.ftl +++ b/locales/nl-NL/opencadstudio.ftl @@ -4392,6 +4392,7 @@ view = .ss-subset-name = Subset name .ss-new-sheet-location = New sheet location .ss-remove-subset = Remove Subset + .ss-rename-subset = Rename Subset... .ss-remove-sheet = Remove Sheet .ss-lets-you-specify-one-or-more-folders-containing-drawings-the = Lets you specify one or more folders containing drawings. The layouts from these drawings can be automatically imported into the sheet set. .ss-creates-a-sheet-set-with-no-subsets-or-sheets = Creates a sheet set with no subsets or sheets. diff --git a/locales/pl-PL/opencadstudio.ftl b/locales/pl-PL/opencadstudio.ftl index 04a59f5ff..1b8174e41 100644 --- a/locales/pl-PL/opencadstudio.ftl +++ b/locales/pl-PL/opencadstudio.ftl @@ -4393,6 +4393,7 @@ view = .ss-subset-name = Subset name .ss-new-sheet-location = New sheet location .ss-remove-subset = Remove Subset + .ss-rename-subset = Rename Subset... .ss-remove-sheet = Remove Sheet .ss-lets-you-specify-one-or-more-folders-containing-drawings-the = Lets you specify one or more folders containing drawings. The layouts from these drawings can be automatically imported into the sheet set. .ss-creates-a-sheet-set-with-no-subsets-or-sheets = Creates a sheet set with no subsets or sheets. diff --git a/locales/pt-BR/opencadstudio.ftl b/locales/pt-BR/opencadstudio.ftl index 77d1ffb4d..f573797fe 100644 --- a/locales/pt-BR/opencadstudio.ftl +++ b/locales/pt-BR/opencadstudio.ftl @@ -4394,6 +4394,7 @@ view = .ss-subset-name = Subset name .ss-new-sheet-location = New sheet location .ss-remove-subset = Remove Subset + .ss-rename-subset = Rename Subset... .ss-remove-sheet = Remove Sheet .ss-lets-you-specify-one-or-more-folders-containing-drawings-the = Lets you specify one or more folders containing drawings. The layouts from these drawings can be automatically imported into the sheet set. .ss-creates-a-sheet-set-with-no-subsets-or-sheets = Creates a sheet set with no subsets or sheets. diff --git a/locales/ru-RU/opencadstudio.ftl b/locales/ru-RU/opencadstudio.ftl index a7688a594..61d26d9bd 100644 --- a/locales/ru-RU/opencadstudio.ftl +++ b/locales/ru-RU/opencadstudio.ftl @@ -4395,6 +4395,7 @@ view = .ss-subset-name = Subset name .ss-new-sheet-location = New sheet location .ss-remove-subset = Remove Subset + .ss-rename-subset = Rename Subset... .ss-remove-sheet = Remove Sheet .ss-lets-you-specify-one-or-more-folders-containing-drawings-the = Lets you specify one or more folders containing drawings. The layouts from these drawings can be automatically imported into the sheet set. .ss-creates-a-sheet-set-with-no-subsets-or-sheets = Creates a sheet set with no subsets or sheets. diff --git a/locales/tr-TR/opencadstudio.ftl b/locales/tr-TR/opencadstudio.ftl index 8448b40e6..ff6b922ff 100644 --- a/locales/tr-TR/opencadstudio.ftl +++ b/locales/tr-TR/opencadstudio.ftl @@ -4354,6 +4354,7 @@ view = .ss-subset-name = Alt küme adı .ss-new-sheet-location = Yeni sayfa konumu .ss-remove-subset = Alt Kümeyi Kaldır + .ss-rename-subset = Alt Kümeyi Yeniden Adlandır... .ss-remove-sheet = Sayfayı Kaldır .ss-lets-you-specify-one-or-more-folders-containing-drawings-the = Çizim içeren bir veya daha fazla klasör belirtmenizi sağlar. Bu çizimlerdeki düzenler sayfa kümesine otomatik olarak aktarılabilir. .ss-creates-a-sheet-set-with-no-subsets-or-sheets = Alt kümesi ve sayfası olmayan bir sayfa kümesi oluşturur. diff --git a/locales/zh-CN/opencadstudio.ftl b/locales/zh-CN/opencadstudio.ftl index 6b03e2057..5943c0419 100644 --- a/locales/zh-CN/opencadstudio.ftl +++ b/locales/zh-CN/opencadstudio.ftl @@ -4377,6 +4377,7 @@ view = .ss-subset-name = Subset name .ss-new-sheet-location = New sheet location .ss-remove-subset = Remove Subset + .ss-rename-subset = Rename Subset... .ss-remove-sheet = Remove Sheet .ss-lets-you-specify-one-or-more-folders-containing-drawings-the = Lets you specify one or more folders containing drawings. The layouts from these drawings can be automatically imported into the sheet set. .ss-creates-a-sheet-set-with-no-subsets-or-sheets = Creates a sheet set with no subsets or sheets. diff --git a/locales/zh-TW/opencadstudio.ftl b/locales/zh-TW/opencadstudio.ftl index 33617b666..96c93c254 100644 --- a/locales/zh-TW/opencadstudio.ftl +++ b/locales/zh-TW/opencadstudio.ftl @@ -4389,6 +4389,7 @@ view = .ss-subset-name = Subset name .ss-new-sheet-location = New sheet location .ss-remove-subset = Remove Subset + .ss-rename-subset = Rename Subset... .ss-remove-sheet = Remove Sheet .ss-lets-you-specify-one-or-more-folders-containing-drawings-the = Lets you specify one or more folders containing drawings. The layouts from these drawings can be automatically imported into the sheet set. .ss-creates-a-sheet-set-with-no-subsets-or-sheets = Creates a sheet set with no subsets or sheets. diff --git a/src/app/commands/sheet_set.rs b/src/app/commands/sheet_set.rs index 809ffd874..a32707a9f 100644 --- a/src/app/commands/sheet_set.rs +++ b/src/app/commands/sheet_set.rs @@ -254,6 +254,32 @@ impl OpenCADStudio { Ok(()) } + /// Reload every open set whose `.dst` was changed by someone else. + fn poll_sheet_sets(&mut self) { + let mut changed = false; + for db in &mut self.sheet_set.sets { + let Some(path) = db.path.clone() else { + continue; + }; + let Ok(modified) = std::fs::metadata(&path).and_then(|m| m.modified()) else { + continue; + }; + let key = ss::path_key(&path); + if self.sheet_set.seen.insert(key, modified).is_none_or(|t| t == modified) { + continue; + } + if let Ok(fresh) = SheetSetDatabase::read(&path) { + if fresh.root != db.root { + *db = fresh; + changed = true; + } + } + } + if changed { + self.sheet_sets_changed(); + } + } + /// Write the current set back to its `.dst`. fn save_current_sheet_set(&mut self) { let Some(db) = self.sheet_set.db_mut() else { @@ -358,6 +384,7 @@ impl OpenCADStudio { self.sheet_set.collapsed.insert(id); } } + SheetSetMsg::Poll => self.poll_sheet_sets(), SheetSetMsg::Refresh => { if let Some(path) = self.sheet_set.db().and_then(|db| db.path.clone()) { match SheetSetDatabase::read(&path) { @@ -513,6 +540,15 @@ impl OpenCADStudio { let Some(db) = self.sheet_set.db() else { return Task::none(); }; + // On a sheet, New Sheet and Import work on the subset holding it. + let id = match action { + MenuAction::NewSheet | MenuAction::ImportLayout + if db.find(&id).and_then(ComponentKind::of) == Some(ComponentKind::Sheet) => + { + db.parent_of(&id).map_or(id, |p| p.id().to_string()) + } + _ => id, + }; match action { MenuAction::Open => return self.open_sheet(&id), MenuAction::NewSheet => { @@ -1098,11 +1134,12 @@ impl OpenCADStudio { if let Err(e) = crate::io::save(&scene.document, &path) { self.command_line.push_error(&format!("{file}: {e}")); } + // The new sheet is not opened ("Open in drawing editor" is off by default). self.close_active_modal(); self.sheet_set.current = Some(f.set); - self.sheet_set.selected = Some(sheet.clone()); + self.sheet_set.selected = Some(sheet); self.sheet_sets_changed(); - self.open_sheet(&sheet) + Task::none() } } diff --git a/src/app/view/mod.rs b/src/app/view/mod.rs index f8b3ebc15..25e2df580 100644 --- a/src/app/view/mod.rs +++ b/src/app/view/mod.rs @@ -2644,6 +2644,16 @@ impl OpenCADStudio { }; #[cfg(target_arch = "wasm32")] let plugin_drain = Subscription::none(); + // Open sheet sets reload when their .dst changes on disk. + #[cfg(not(target_arch = "wasm32"))] + let sheet_set_poll = if self.sheet_set.sets.is_empty() { + Subscription::none() + } else { + iced::time::every(std::time::Duration::from_secs(1)) + .map(|_| Message::SheetSet(crate::ui::window::sheet_set::SheetSetMsg::Poll)) + }; + #[cfg(target_arch = "wasm32")] + let sheet_set_poll = Subscription::none(); let hatch_pattern_keys = if self.tabs[self.active_tab] .properties .hatch_pattern_picker_open @@ -2845,6 +2855,7 @@ impl OpenCADStudio { web_fonts, autosave, plugin_drain, + sheet_set_poll, single_instance, hatch_pattern_keys, keyboard_events, diff --git a/src/locale_catalog.rs b/src/locale_catalog.rs index c910a2d97..14452f731 100644 --- a/src/locale_catalog.rs +++ b/src/locale_catalog.rs @@ -49,6 +49,7 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static "Subset name" => Some(("view", "ss-subset-name")), "New sheet location" => Some(("view", "ss-new-sheet-location")), "Remove Subset" => Some(("view", "ss-remove-subset")), + "Rename Subset..." => Some(("view", "ss-rename-subset")), "Remove Sheet" => Some(("view", "ss-remove-sheet")), "Lets you specify one or more folders containing drawings. The layouts from these drawings can be automatically imported into the sheet set." => Some(("view", "ss-lets-you-specify-one-or-more-folders-containing-drawings-the")), "Creates a sheet set with no subsets or sheets." => Some(("view", "ss-creates-a-sheet-set-with-no-subsets-or-sheets")), diff --git a/src/ui/window/field_dialog.rs b/src/ui/window/field_dialog.rs index 49ecac3c4..6851c0612 100644 --- a/src/ui/window/field_dialog.rs +++ b/src/ui/window/field_dialog.rs @@ -328,14 +328,18 @@ impl FieldDialogState { FieldKind::SheetSetPlaceholder => { let (label, target, version) = PLACEHOLDER_TYPES[self.ss_placeholder.min(PLACEHOLDER_TYPES.len() - 1)]; let target = if label == "Custom" { format!("{target}{}", self.ss_custom) } else { target.to_string() }; - let base = format!("\\AcSm{version} {target}"); if label == "ViewportScale" { + // The version follows the format, as for PlotScale. + let version = codec::fields::PLOT_SCALE_FORMATS + .get(self.ss_scale_format) + .map_or("", |(_, code)| if code.starts_with("\\AcVar.16.2") { ".16.2" } else { "" }); + let base = format!("\\AcSm{version} {target}"); match viewport_scale_picture(self.ss_scale_format) { f if f.is_empty() => (base, vec![]), f => (format!("{base} {f}"), vec![]), } } else { - (case(base), vec![]) + (case(format!("\\AcSm{version} {target}")), vec![]) } } FieldKind::BlockPlaceholder => { diff --git a/src/ui/window/sheet_set.rs b/src/ui/window/sheet_set.rs index 18d3f37b1..a1c54c7dd 100644 --- a/src/ui/window/sheet_set.rs +++ b/src/ui/window/sheet_set.rs @@ -63,6 +63,8 @@ pub struct SheetSetManager { pub found: String, /// The open dialog (shown in the `SheetSet` modal). pub dialog: Option, + /// Last seen modification time of each open `.dst` (by path key). + pub seen: std::collections::HashMap, } impl SheetSetManager { @@ -99,6 +101,8 @@ pub enum SheetSetMsg { Activate(String), Menu(String, MenuAction), Refresh, + /// Once a second: reload sets whose `.dst` changed on disk. + Poll, /// A `.dst` picked by Open (or given by automation). OpenPicked(Option), /// A drawing picked by Import Layout as Sheet. @@ -322,23 +326,35 @@ fn menu_separator() -> Element<'static, Message> { } /// A row's right-click menu. -fn row_menu(id: String, kind: ComponentKind) -> Element<'static, Message> { +/// The reference's order per row kind; a sheet's New Sheet / Import work on +/// its subset, and only an empty subset can be removed. +fn row_menu(id: String, kind: ComponentKind, empty: bool) -> Element<'static, Message> { let entry = |label: &str, action: MenuAction, on: bool| { menu_entry(t!(label).into_owned(), on.then(|| msg(SheetSetMsg::Menu(id.clone(), action)))) }; - let sheet = kind == ComponentKind::Sheet; - let mut items = vec![ - entry("Open", MenuAction::Open, sheet), - menu_separator(), - entry("New Sheet...", MenuAction::NewSheet, !sheet), - entry("New Subset...", MenuAction::NewSubset, !sheet), - entry("Import Layout as Sheet...", MenuAction::ImportLayout, !sheet), - menu_separator(), - entry("Rename & Renumber...", MenuAction::Rename, sheet), - entry(if kind == ComponentKind::Subset { "Remove Subset" } else { "Remove Sheet" }, MenuAction::Remove, kind != ComponentKind::SheetSet), - ]; - if kind == ComponentKind::SheetSet { - items.push(entry("Close Sheet Set", MenuAction::Close, true)); + let mut items = Vec::new(); + match kind { + ComponentKind::SheetSet => items.extend([entry("Close Sheet Set", MenuAction::Close, true), menu_separator()]), + ComponentKind::Sheet => items.extend([entry("Open", MenuAction::Open, true), menu_separator()]), + ComponentKind::Subset => {} + } + items.push(entry("New Sheet...", MenuAction::NewSheet, true)); + if kind != ComponentKind::Sheet { + items.push(entry("New Subset...", MenuAction::NewSubset, true)); + } + items.push(entry("Import Layout as Sheet...", MenuAction::ImportLayout, true)); + match kind { + ComponentKind::SheetSet => {} + ComponentKind::Subset => items.extend([ + menu_separator(), + entry("Rename Subset...", MenuAction::Properties, true), + entry("Remove Subset", MenuAction::Remove, empty), + ]), + ComponentKind::Sheet => items.extend([ + menu_separator(), + entry("Rename & Renumber...", MenuAction::Rename, true), + entry("Remove Sheet", MenuAction::Remove, true), + ]), } items.push(menu_separator()); items.push(entry("Properties...", MenuAction::Properties, true)); @@ -391,7 +407,8 @@ fn tree_row<'a>( })) .on_press(msg(SheetSetMsg::Select(id.clone()))) .on_double_click(msg(SheetSetMsg::Activate(id.clone()))); - iced_aw::ContextMenu::new(area, move || row_menu(id.clone(), kind)).into() + let empty = !el.children.iter().any(|c| matches!(ComponentKind::of(c), Some(ComponentKind::Subset | ComponentKind::Sheet))); + iced_aw::ContextMenu::new(area, move || row_menu(id.clone(), kind, empty)).into() } fn push_tree<'a>(