Wire settings dialog to persist config via ConfigStore

- Load current settings from ConfigStore on dialog open
- All switches, combos, and entries reflect saved values
- Save all settings back to ConfigStore on dialog close
- Covers: output, overwrite, skill level, threads, errors,
  accessibility, and notification preferences
This commit is contained in:
2026-03-06 11:44:16 +02:00
parent f353bbe5e6
commit eeb418ccdd

View File

@@ -1,10 +1,15 @@
use adw::prelude::*;
use pixstrip_core::config::{AppConfig, ErrorBehavior, OverwriteBehavior, SkillLevel};
use pixstrip_core::storage::ConfigStore;
pub fn build_settings_dialog() -> adw::PreferencesDialog {
let dialog = adw::PreferencesDialog::builder()
.title("Settings")
.build();
let config_store = ConfigStore::new();
let config = config_store.load().unwrap_or_default();
// General page
let general_page = adw::PreferencesPage::builder()
.title("General")
@@ -17,7 +22,7 @@ pub fn build_settings_dialog() -> adw::PreferencesDialog {
let subfolder_row = adw::EntryRow::builder()
.title("Default output subfolder")
.text("processed")
.text(&config.output_subfolder)
.build();
let overwrite_row = adw::ComboRow::builder()
@@ -31,11 +36,17 @@ pub fn build_settings_dialog() -> adw::PreferencesDialog {
"Skip existing files",
]);
overwrite_row.set_model(Some(&overwrite_model));
overwrite_row.set_selected(match config.overwrite_behavior {
OverwriteBehavior::Ask => 0,
OverwriteBehavior::AutoRename => 1,
OverwriteBehavior::Overwrite => 2,
OverwriteBehavior::Skip => 3,
});
let remember_row = adw::SwitchRow::builder()
.title("Remember last-used settings")
.subtitle("Restore wizard state on next launch")
.active(true)
.active(config.remember_settings)
.build();
output_group.add(&subfolder_row);
@@ -53,6 +64,10 @@ pub fn build_settings_dialog() -> adw::PreferencesDialog {
.build();
let skill_model = gtk::StringList::new(&["Simple", "Detailed"]);
skill_row.set_model(Some(&skill_model));
skill_row.set_selected(match config.skill_level {
SkillLevel::Simple => 0,
SkillLevel::Detailed => 1,
});
ui_group.add(&skill_row);
general_page.add(&ui_group);
@@ -81,6 +96,10 @@ pub fn build_settings_dialog() -> adw::PreferencesDialog {
.build();
let error_model = gtk::StringList::new(&["Skip and continue", "Pause on error"]);
error_row.set_model(Some(&error_model));
error_row.set_selected(match config.error_behavior {
ErrorBehavior::SkipAndContinue => 0,
ErrorBehavior::PauseOnError => 1,
});
threads_group.add(&threads_row);
threads_group.add(&error_row);
@@ -101,19 +120,19 @@ pub fn build_settings_dialog() -> adw::PreferencesDialog {
let contrast_row = adw::SwitchRow::builder()
.title("High contrast")
.subtitle("Increase visual contrast throughout the app")
.active(false)
.active(config.high_contrast)
.build();
let large_text_row = adw::SwitchRow::builder()
.title("Large text")
.subtitle("Increase text size throughout the app")
.active(false)
.active(config.large_text)
.build();
let motion_row = adw::SwitchRow::builder()
.title("Reduced motion")
.subtitle("Minimize animations and transitions")
.active(false)
.active(config.reduced_motion)
.build();
a11y_group.add(&contrast_row);
@@ -135,19 +154,19 @@ pub fn build_settings_dialog() -> adw::PreferencesDialog {
let desktop_notify_row = adw::SwitchRow::builder()
.title("Desktop notification")
.subtitle("Show notification when processing completes")
.active(true)
.active(config.notify_on_completion)
.build();
let sound_row = adw::SwitchRow::builder()
.title("Completion sound")
.subtitle("Play a sound when processing completes")
.active(false)
.active(config.play_completion_sound)
.build();
let auto_open_row = adw::SwitchRow::builder()
.title("Auto-open output folder")
.subtitle("Open the output folder in file manager when done")
.active(false)
.active(config.auto_open_output)
.build();
notify_group.add(&desktop_notify_row);
@@ -156,5 +175,39 @@ pub fn build_settings_dialog() -> adw::PreferencesDialog {
notify_page.add(&notify_group);
dialog.add(&notify_page);
// Save settings when the dialog closes
dialog.connect_closed(move |_| {
let new_config = AppConfig {
first_run_complete: true,
output_subfolder: subfolder_row.text().to_string(),
output_fixed_path: None,
overwrite_behavior: match overwrite_row.selected() {
1 => OverwriteBehavior::AutoRename,
2 => OverwriteBehavior::Overwrite,
3 => OverwriteBehavior::Skip,
_ => OverwriteBehavior::Ask,
},
remember_settings: remember_row.is_active(),
skill_level: match skill_row.selected() {
1 => SkillLevel::Detailed,
_ => SkillLevel::Simple,
},
thread_count: pixstrip_core::config::ThreadCount::Auto,
error_behavior: match error_row.selected() {
1 => ErrorBehavior::PauseOnError,
_ => ErrorBehavior::SkipAndContinue,
},
notify_on_completion: desktop_notify_row.is_active(),
play_completion_sound: sound_row.is_active(),
auto_open_output: auto_open_row.is_active(),
high_contrast: contrast_row.is_active(),
large_text: large_text_row.is_active(),
reduced_motion: motion_row.is_active(),
};
let store = ConfigStore::new();
let _ = store.save(&new_config);
});
dialog
}