From 0b99d9c1d972957d31df1c8b2ca3029582d559d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mikrut?= Date: Mon, 13 Nov 2023 19:54:22 +0100 Subject: [PATCH] Loading/Saving settings --- Cargo.lock | 1 + krokiet/Cargo.toml | 1 + krokiet/src/connect_scan.rs | 6 +- krokiet/src/main.rs | 13 ++-- krokiet/src/settings.rs | 125 ++++++++++++++++++++++++++++-------- 5 files changed, 109 insertions(+), 37 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 510ed96..722acd2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3314,6 +3314,7 @@ dependencies = [ "chrono", "crossbeam-channel", "czkawka_core", + "directories-next", "handsome_logger", "home", "humansize", diff --git a/krokiet/Cargo.toml b/krokiet/Cargo.toml index a6213e1..0204576 100644 --- a/krokiet/Cargo.toml +++ b/krokiet/Cargo.toml @@ -33,6 +33,7 @@ serde = "1.0" serde_json = "1.0" humansize = "2.1.3" image = "0.24.7" +directories-next = "2.0" [build-dependencies] slint-build = "1.3.0" diff --git a/krokiet/src/connect_scan.rs b/krokiet/src/connect_scan.rs index 8aa66f5..cf3267a 100644 --- a/krokiet/src/connect_scan.rs +++ b/krokiet/src/connect_scan.rs @@ -1,7 +1,6 @@ use crate::common::create_vec_model_from_vec_string; use crate::settings::{collect_settings, SettingsCustom}; -use crate::GuiState; -use crate::{CurrentTab, MainListModel, MainWindow, ProgressToSend}; +use crate::{CurrentTab, GuiState, MainListModel, MainWindow, ProgressToSend}; use chrono::NaiveDateTime; use crossbeam_channel::{Receiver, Sender}; use czkawka_core::common::split_path; @@ -12,8 +11,7 @@ use czkawka_core::empty_files::EmptyFiles; use czkawka_core::empty_folder::EmptyFolder; use czkawka_core::similar_images; use czkawka_core::similar_images::SimilarImages; -use humansize::format_size; -use humansize::BINARY; +use humansize::{format_size, BINARY}; use slint::{ComponentHandle, ModelRc, SharedString, VecModel, Weak}; use std::path::PathBuf; use std::rc::Rc; diff --git a/krokiet/src/main.rs b/krokiet/src/main.rs index 102faa6..e520768 100644 --- a/krokiet/src/main.rs +++ b/krokiet/src/main.rs @@ -33,7 +33,7 @@ use crate::connect_directories_changes::connect_add_remove_directories; use crate::connect_progress_receiver::connect_progress_gathering; use crate::connect_show_preview::connect_show_preview; use crate::connect_stop::connect_stop_button; -use crate::settings::reset_settings; +use crate::settings::{load_settings_from_file, reset_settings, save_settings_to_file}; use czkawka_core::common::setup_logger; use czkawka_core::common_dir_traversal::ProgressData; use slint::{ModelRc, VecModel}; @@ -42,13 +42,16 @@ slint::include_modules!(); fn main() { setup_logger(false); - let app = MainWindow::new().unwrap(); //.run().unwrap(); + let app = MainWindow::new().unwrap(); let (progress_sender, progress_receiver): (Sender, Receiver) = unbounded(); let (stop_sender, stop_receiver): (Sender<()>, Receiver<()>) = unbounded(); - // Fills model at start, don't really needed too much after testing + to_remove_debug(&app); + reset_settings(&app); + load_settings_from_file(&app); + connect_delete_button(&app); connect_scan_button(&app, progress_sender, stop_receiver); connect_stop_button(&app, stop_sender); @@ -57,9 +60,9 @@ fn main() { connect_add_remove_directories(&app); connect_show_preview(&app); - reset_settings(&app); - app.run().unwrap(); + + save_settings_to_file(&app); } // TODO remove this after debugging - or leave commented diff --git a/krokiet/src/settings.rs b/krokiet/src/settings.rs index f329c2c..0570d68 100644 --- a/krokiet/src/settings.rs +++ b/krokiet/src/settings.rs @@ -3,9 +3,11 @@ use std::env; use std::path::PathBuf; use crate::common::create_string_standard_list_view_from_pathbuf; -use crate::GuiState; -use crate::Settings; +use crate::{GuiState, Settings}; +use directories_next::ProjectDirs; use home::home_dir; +use log::error; +use serde::{Deserialize, Serialize}; use slint::{ComponentHandle, Model}; #[cfg(target_family = "unix")] @@ -13,15 +15,86 @@ const DEFAULT_EXCLUDED_DIRECTORIES: &[&str] = &["/proc", "/dev", "/sys", "/run", #[cfg(not(target_family = "unix"))] const DEFAULT_EXCLUDED_DIRECTORIES: &[&str] = &["C:\\Windows"]; +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct SettingsCustom { + #[serde(default = "default_included_directories")] pub included_directories: Vec, + #[serde(default = "default_excluded_directories")] pub excluded_directories: Vec, } +impl Default for SettingsCustom { + fn default() -> Self { + Self { + included_directories: default_included_directories(), + excluded_directories: default_excluded_directories(), + } + } +} pub fn reset_settings(app: &MainWindow) { set_settings_to_gui(app, &SettingsCustom::default()); } +pub fn load_settings_from_file(app: &MainWindow) { + let Some(config_file) = get_config_file() else { + error!("Cannot get config file"); + return; + }; + if !config_file.is_file() { + error!("Config file doesn't exists"); + return; + } + + match std::fs::read_to_string(config_file) { + Ok(serialized) => match serde_json::from_str(&serialized) { + Ok(custom_settings) => { + set_settings_to_gui(app, &custom_settings); + } + Err(e) => { + error!("Cannot deserialize settings: {e}"); + } + }, + Err(e) => { + error!("Cannot read config file: {e}"); + } + } +} + +pub fn save_settings_to_file(app: &MainWindow) { + let Some(config_file) = get_config_file() else { + error!("Cannot get config file"); + return; + }; + // Create dirs if not exists + if let Some(parent) = config_file.parent() { + if let Err(e) = std::fs::create_dir_all(parent) { + error!("Cannot create config folder: {e}"); + return; + } + } + + let collected_settings = collect_settings(app); + match serde_json::to_string_pretty(&collected_settings) { + Ok(serialized) => { + if let Err(e) = std::fs::write(config_file, serialized) { + error!("Cannot save config file: {e}"); + } + } + Err(e) => { + error!("Cannot serialize settings: {e}"); + } + } +} + +pub fn get_config_file() -> Option { + let Some(configs) = ProjectDirs::from("pl", "Qarmin", "Krokiet") else { + return None; + }; + let config_folder = configs.config_dir(); + let config_file = config_folder.join("config.json"); + Some(config_file) +} + pub fn set_settings_to_gui(app: &MainWindow, custom_settings: &SettingsCustom) { let settings = app.global::(); @@ -37,32 +110,6 @@ pub fn set_settings_to_gui(app: &MainWindow, custom_settings: &SettingsCustom) { app.global::().set_info_text("".into()); } -impl Default for SettingsCustom { - fn default() -> Self { - let mut included_directories = vec![]; - if let Ok(current_dir) = env::current_dir() { - included_directories.push(current_dir.to_string_lossy().to_string()); - } else if let Some(home_dir) = home_dir() { - included_directories.push(home_dir.to_string_lossy().to_string()); - } else if cfg!(target_family = "unix") { - included_directories.push("/".to_string()); - } else { - // This could be set to default - included_directories.push("C:\\".to_string()); - }; - included_directories.sort(); - let included_directories = included_directories.iter().map(PathBuf::from).collect::>(); - - let mut excluded_directories = DEFAULT_EXCLUDED_DIRECTORIES.iter().map(PathBuf::from).collect::>(); - excluded_directories.sort(); - - Self { - included_directories, - excluded_directories, - } - } -} - pub fn collect_settings(app: &MainWindow) -> SettingsCustom { let settings = app.global::(); @@ -77,3 +124,25 @@ pub fn collect_settings(app: &MainWindow) -> SettingsCustom { excluded_directories, } } + +fn default_included_directories() -> Vec { + let mut included_directories = vec![]; + if let Ok(current_dir) = env::current_dir() { + included_directories.push(current_dir.to_string_lossy().to_string()); + } else if let Some(home_dir) = home_dir() { + included_directories.push(home_dir.to_string_lossy().to_string()); + } else if cfg!(target_family = "unix") { + included_directories.push("/".to_string()); + } else { + // This could be set to default + included_directories.push("C:\\".to_string()); + }; + included_directories.sort(); + included_directories.iter().map(PathBuf::from).collect::>() +} + +fn default_excluded_directories() -> Vec { + let mut excluded_directories = DEFAULT_EXCLUDED_DIRECTORIES.iter().map(PathBuf::from).collect::>(); + excluded_directories.sort(); + excluded_directories +}