From 26b4f29a13cdd692a8576eb5416545d9df02daf9 Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Fri, 7 Aug 2026 17:51:06 +0300 Subject: [PATCH] feat(options): offer the file association in Options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Registering as the .dwg/.dxf handler was reachable only by typing FILEASSOC, which is also the only thing that installs the icons the desktop shows — so a user with no reason to know the command had no way to arrive at either. The checkbox makes the same two calls the command does, so the stored setting and the actual registration cannot drift apart. A registration the system refuses puts the checkbox back rather than leaving it showing a state that is not true. The line under it says the icons come with it, since that is what sends people looking for this in the first place. Co-Authored-By: Claude Opus 5 --- src/app/mod.rs | 3 +++ src/app/update/mod.rs | 33 +++++++++++++++++++++++++++++++++ src/app/view/modal.rs | 1 + src/ui/window/options.rs | 17 +++++++++++++++++ 4 files changed, 54 insertions(+) diff --git a/src/app/mod.rs b/src/app/mod.rs index acf0f920b..82f8c8d77 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -1767,6 +1767,9 @@ pub enum Message { OptionsThemeChanged(String), /// Edit one of Custom theme's six base colours as #RRGGBB. OptionsThemeColorChanged(usize, String), + /// Register or unregister as the .dwg/.dxf handler, from Options. Same + /// setting the FILEASSOC command carries. + FileAssocChanged(bool), /// Switch the interface language and redraw localized views. LanguageChanged(crate::i18n::Language), /// Drop every entity from the active drawing. diff --git a/src/app/update/mod.rs b/src/app/update/mod.rs index cab874d5e..b70f2fc0f 100644 --- a/src/app/update/mod.rs +++ b/src/app/update/mod.rs @@ -5087,6 +5087,39 @@ impl OpenCADStudio { Task::none() } + Message::FileAssocChanged(enabled) => { + // The same two calls FILEASSOC makes, so the checkbox and the + // command cannot leave the setting and the registration + // disagreeing. + self.file_assoc_enabled = enabled; + self.persist_settings_if_changed(); + let outcome = if enabled { + crate::io::file_association::register_as_handler() + } else { + crate::io::file_association::unregister_handler() + }; + match outcome { + Ok(()) => { + let said = if enabled { + crate::t!("Registered as a .dwg/.dxf handler.") + } else { + crate::t!("No longer registered as a file handler.") + }; + self.command_line.push_output(said.as_ref()); + } + Err(why) => { + // The setting is what the user asked for; the + // registration is what the system allowed. Put the + // checkbox back rather than showing a state that is not + // true. + self.file_assoc_enabled = !enabled; + self.persist_settings_if_changed(); + self.command_line + .push_error(crate::tf!("File association failed: {why}").as_ref()); + } + } + Task::none() + } Message::LanguageChanged(language) => { if self.language == language { return Task::none(); diff --git a/src/app/view/modal.rs b/src/app/view/modal.rs index 7bc788519..71a2b1de6 100644 --- a/src/app/view/modal.rs +++ b/src/app/view/modal.rs @@ -91,6 +91,7 @@ impl OpenCADStudio { |flow| { crate::ui::window::options::view_window( &self.default_save_format, + self.file_assoc_enabled, &self.ui_theme, &self.theme_color_inputs, self.language, diff --git a/src/ui/window/options.rs b/src/ui/window/options.rs index 04fbbf544..cb27fd43c 100644 --- a/src/ui/window/options.rs +++ b/src/ui/window/options.rs @@ -20,6 +20,7 @@ impl fmt::Display for Labelled { pub fn view_window<'a>( default_save_format: &'a str, + file_assoc_enabled: bool, ui_theme: &'a UiThemeConfig, theme_color_inputs: &'a [String; 6], language: crate::i18n::Language, @@ -137,6 +138,22 @@ pub fn view_window<'a>( text(crate::tr!("options-default-save-format-help")) .size(11) .width(sizing.width), + Space::new().height(14), + row![ + iced::widget::checkbox(file_assoc_enabled) + .on_toggle(Message::FileAssocChanged) + .size(15), + text(crate::t!("Open .dwg and .dxf files with Open CAD Studio")) + .size(12), + ] + .spacing(8) + .align_y(iced::Center), + Space::new().height(6), + text(crate::t!( + "Also installs the application and file-type icons the desktop shows." + )) + .size(11) + .width(sizing.width), Space::new().height(22), text(crate::tr!("options-theme-section")).size(15), Space::new().height(10),