diff options
Diffstat (limited to 'src/dialogs.rs')
| -rw-r--r-- | src/dialogs.rs | 98 |
1 files changed, 97 insertions, 1 deletions
diff --git a/src/dialogs.rs b/src/dialogs.rs index 6b906ed..752f99d 100644 --- a/src/dialogs.rs +++ b/src/dialogs.rs @@ -6,7 +6,7 @@ use gtk::prelude::*; use relm4::{ComponentSender, gtk}; use crate::AppModel; -use crate::actions::Action; +use crate::actions::{Action, ImageFormat}; use crate::constants; use crate::file_registry; @@ -156,3 +156,99 @@ pub fn show_unsaved_changes_dialog( }); dialog.show(); } + +/// Creates a file filter for an image format. +fn create_image_filter(format: ImageFormat) -> gtk::FileFilter { + let filter = gtk::FileFilter::new(); + filter.add_pattern(&format!("*.{}", format.extension())); + filter.add_mime_type(format.mime_type()); + let name = match format { + ImageFormat::Png => "PNG Image", + ImageFormat::Svg => "SVG Image", + }; + filter.set_name(Some(name)); + filter +} + +/// Shows an export image dialog and handles the response. +pub fn show_export_dialog( + window: >k::Window, + current_file: Option<PathBuf>, + sender: ComponentSender<AppModel>, +) { + let dialog = gtk::FileChooserDialog::new( + Some("Export Map as Image"), + Some(window), + gtk::FileChooserAction::Save, + &[ + ("Cancel", gtk::ResponseType::Cancel), + ("Export", gtk::ResponseType::Accept), + ], + ); + + let png_filter = create_image_filter(ImageFormat::Png); + let svg_filter = create_image_filter(ImageFormat::Svg); + dialog.add_filter(&png_filter); + dialog.add_filter(&svg_filter); + + // Set default filename based on current file + let base_name = current_file + .as_ref() + .and_then(|p| p.file_stem()) + .and_then(|s| s.to_str()) + .unwrap_or("map") + .to_string(); + + if let Some(ref current_path) = current_file + && let Some(parent) = current_path.parent() + { + let folder = gtk::gio::File::for_path(parent); + dialog.set_current_folder(Some(&folder)).ok(); + } + dialog.set_current_name(&format!("{}.png", base_name)); + + // Update extension when filter changes + { + let png_filter_ref = png_filter.clone(); + let base_name_clone = base_name.clone(); + dialog.connect_notify_local(Some("filter"), move |dialog, _| { + let ext = if dialog.filter().as_ref() == Some(&png_filter_ref) { + "png" + } else { + "svg" + }; + dialog.set_current_name(&format!("{}.{}", base_name_clone, ext)); + }); + } + + let png_filter_clone = png_filter.clone(); + dialog.connect_response(move |dialog, response| { + dialog.close(); + if response == gtk::ResponseType::Accept + && let Some(file) = dialog.file() + && let Some(path) = file.path() + { + // Determine format from selected filter or file extension + let format = if dialog.filter().as_ref() == Some(&png_filter_clone) { + ImageFormat::Png + } else if let Some(ext) = path.extension().and_then(|e| e.to_str()) { + match ext.to_lowercase().as_str() { + "svg" => ImageFormat::Svg, + _ => ImageFormat::Png, + } + } else { + ImageFormat::Png + }; + + // Ensure correct extension + let path = if path.extension().is_none() { + path.with_extension(format.extension()) + } else { + path + }; + + sender.input(Action::ExportToFile { path, format }); + } + }); + dialog.present(); +} |