// Map, wardley map editor for linux // Copyright (C) 2026 Rubén Beltrán del Río // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . use gtk::FileFilter; use gtk::prelude::*; use relm4::Sender; use relm4::{adw, gtk}; use crate::tr; use super::super::window::PreferencesInput; pub struct GeneralPage { container: gtk::Box, } impl GeneralPage { pub fn new(sender: &Sender) -> Self { let container = gtk::Box::new(gtk::Orientation::Vertical, 20); container.set_margin_top(20); container.set_margin_bottom(20); container.set_margin_start(20); container.set_margin_end(20); container.set_valign(gtk::Align::Start); // Preferences section let prefs_label = gtk::Label::new(Some(&tr!("preferences.general.preferences.title"))); prefs_label.add_css_class("heading"); prefs_label.set_halign(gtk::Align::Start); container.append(&prefs_label); let button_box = gtk::Box::new(gtk::Orientation::Horizontal, 10); // Export button let export_button = gtk::Button::with_label(&tr!("preferences.general.preferences.export")); { let sender = sender.clone(); export_button.connect_clicked(move |_| { sender.emit(PreferencesInput::Export); }); } button_box.append(&export_button); // Import button let import_button = gtk::Button::with_label(&tr!("preferences.general.preferences.import")); { let sender = sender.clone(); import_button.connect_clicked(move |_| { sender.emit(PreferencesInput::Import); }); } button_box.append(&import_button); // Reset button let reset_button = gtk::Button::with_label(&tr!("preferences.general.preferences.reset")); reset_button.add_css_class("destructive-action"); { let sender = sender.clone(); reset_button.connect_clicked(move |_| { sender.emit(PreferencesInput::ResetToDefaults); }); } button_box.append(&reset_button); container.append(&button_box); // Help text let help_label = gtk::Label::new(Some(&tr!("preferences.general.explanation"))); help_label.add_css_class("dim-label"); help_label.set_halign(gtk::Align::Start); help_label.set_wrap(true); container.append(&help_label); Self { container } } pub fn widget(&self) -> gtk::Box { self.container.clone() } } pub fn show_export_dialog(sender: &Sender, window: &adw::Window) { let filter = FileFilter::new(); filter.add_pattern("*.json"); filter.set_name(Some(&tr!("dialog.file_type.json"))); let filters = gtk::gio::ListStore::new::(); filters.append(&filter); let dialog = gtk::FileDialog::builder() .title(tr!("dialog.export_preferences.title")) .modal(true) .filters(&filters) .initial_name("preferences.json") .build(); let sender = sender.clone(); let window = window.clone(); gtk::glib::spawn_future_local(async move { if let Ok(file) = dialog.save_future(Some(&window)).await && let Some(path) = file.path() { sender.emit(PreferencesInput::ExportToFile(path)); } }); } pub fn show_import_dialog(sender: &Sender, window: &adw::Window) { let filter = FileFilter::new(); filter.add_pattern("*.json"); filter.set_name(Some(&tr!("dialog.file_type.json"))); let filters = gtk::gio::ListStore::new::(); filters.append(&filter); let dialog = gtk::FileDialog::builder() .title(tr!("dialog.import_preferences.title")) .modal(true) .filters(&filters) .build(); let sender = sender.clone(); let window = window.clone(); gtk::glib::spawn_future_local(async move { if let Ok(file) = dialog.open_future(Some(&window)).await && let Some(path) = file.path() { sender.emit(PreferencesInput::ImportFromFile(path)); } }); }