355 lines
15 KiB
Rust
355 lines
15 KiB
Rust
use crate::gui_data::*;
|
|
use crate::help_functions::{get_list_store, ColumnsDirectory};
|
|
use directories_next::ProjectDirs;
|
|
use gtk::prelude::*;
|
|
use gtk::{EntryExt, GtkListStoreExt, ToggleButtonExt};
|
|
use std::fs::File;
|
|
use std::io::Write;
|
|
use std::path::Path;
|
|
use std::{env, fs};
|
|
|
|
const SAVE_FILE_NAME: &str = "czkawka_gui_config.txt";
|
|
|
|
pub fn save_configuration(gui_data: &GuiData, manual_execution: bool) {
|
|
let check_button_settings_save_at_exit = gui_data.check_button_settings_save_at_exit.clone();
|
|
let text_view_errors = gui_data.text_view_errors.clone();
|
|
|
|
if !manual_execution && !check_button_settings_save_at_exit.get_active() {
|
|
// When check button is deselected, not save configuration at exit
|
|
return;
|
|
}
|
|
if let Some(proj_dirs) = ProjectDirs::from("pl", "Qarmin", "Czkawka") {
|
|
// Lin: /home/alice/.config/barapp
|
|
// Win: C:\Users\Alice\AppData\Roaming\Foo Corp\Bar App\config
|
|
// Mac: /Users/Alice/Library/Application Support/com.Foo-Corp.Bar-App
|
|
|
|
let config_dir = proj_dirs.config_dir();
|
|
if config_dir.exists() {
|
|
if !config_dir.is_dir() {
|
|
text_view_errors
|
|
.get_buffer()
|
|
.unwrap()
|
|
.set_text(format!("Cannot create save file inside {} because this isn't a folder.", config_dir.display()).as_str());
|
|
return;
|
|
}
|
|
} else if fs::create_dir(config_dir).is_err() {
|
|
text_view_errors.get_buffer().unwrap().set_text(format!("Failed configuration to create configuration folder {}", config_dir.display()).as_str());
|
|
return;
|
|
}
|
|
|
|
let mut data_to_save: Vec<String> = Vec::new();
|
|
|
|
//// Included Directories
|
|
data_to_save.push("--included_directories:".to_string());
|
|
let scrolled_window_included_directories = gui_data.scrolled_window_included_directories.clone();
|
|
let list_store = get_list_store(&scrolled_window_included_directories);
|
|
if let Some(iter) = list_store.get_iter_first() {
|
|
loop {
|
|
data_to_save.push(list_store.get_value(&iter, ColumnsDirectory::Path as i32).get::<String>().unwrap().unwrap());
|
|
if !list_store.iter_next(&iter) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//// Excluded Directories
|
|
data_to_save.push("--excluded_directories:".to_string());
|
|
let scrolled_window_excluded_directories = gui_data.scrolled_window_excluded_directories.clone();
|
|
let list_store = get_list_store(&scrolled_window_excluded_directories);
|
|
if let Some(iter) = list_store.get_iter_first() {
|
|
loop {
|
|
data_to_save.push(list_store.get_value(&iter, ColumnsDirectory::Path as i32).get::<String>().unwrap().unwrap());
|
|
if !list_store.iter_next(&iter) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//// Excluded Items
|
|
data_to_save.push("--excluded_items:".to_string());
|
|
let entry_excluded_items = gui_data.entry_excluded_items.clone();
|
|
for item in entry_excluded_items.get_text().split(',') {
|
|
if item.trim().is_empty() {
|
|
continue;
|
|
}
|
|
data_to_save.push(item.to_string());
|
|
}
|
|
|
|
//// Allowed extensions
|
|
data_to_save.push("--allowed_extensions:".to_string());
|
|
let entry_allowed_extensions = gui_data.entry_allowed_extensions.clone();
|
|
for extension in entry_allowed_extensions.get_text().split(',') {
|
|
if extension.trim().is_empty() {
|
|
continue;
|
|
}
|
|
data_to_save.push(extension.to_string());
|
|
}
|
|
|
|
//// Save at exit
|
|
data_to_save.push("--save_at_exit:".to_string());
|
|
let check_button_settings_save_at_exit = gui_data.check_button_settings_save_at_exit.clone();
|
|
data_to_save.push(check_button_settings_save_at_exit.get_active().to_string());
|
|
|
|
//// Load at start
|
|
data_to_save.push("--load_at_start:".to_string());
|
|
let check_button_settings_load_at_start = gui_data.check_button_settings_load_at_start.clone();
|
|
data_to_save.push(check_button_settings_load_at_start.get_active().to_string());
|
|
|
|
// Creating/Opening config file
|
|
|
|
let config_file = config_dir.join(Path::new(SAVE_FILE_NAME));
|
|
|
|
let mut config_file_handler = match File::create(&config_file) {
|
|
Ok(t) => t,
|
|
Err(_) => {
|
|
text_view_errors.get_buffer().unwrap().set_text(format!("Failed to create config file {}", config_file.display()).as_str());
|
|
return;
|
|
}
|
|
};
|
|
|
|
for data in data_to_save {
|
|
match writeln!(config_file_handler, "{}", data) {
|
|
Ok(_) => {
|
|
text_view_errors.get_buffer().unwrap().set_text(format!("Saved configuration to file {}", config_file.display()).as_str());
|
|
}
|
|
Err(_) => {
|
|
text_view_errors.get_buffer().unwrap().set_text(format!("Failed to save configuration data to file {}", config_file.display()).as_str());
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
text_view_errors.get_buffer().unwrap().set_text("Failed to get home directory, so can't save file.");
|
|
}
|
|
}
|
|
|
|
enum TypeOfLoadedData {
|
|
None,
|
|
IncludedDirectories,
|
|
ExcludedDirectories,
|
|
ExcludedItems,
|
|
AllowedExtensions,
|
|
LoadingAtStart,
|
|
SavingAtExit,
|
|
}
|
|
|
|
pub fn load_configuration(gui_data: &GuiData, manual_execution: bool) {
|
|
let text_view_errors = gui_data.text_view_errors.clone();
|
|
if let Some(proj_dirs) = ProjectDirs::from("pl", "Qarmin", "Czkawka") {
|
|
// Lin: /home/alice/.config/barapp
|
|
// Win: C:\Users\Alice\AppData\Roaming\Foo Corp\Bar App\config
|
|
// Mac: /Users/Alice/Library/Application Support/com.Foo-Corp.Bar-App
|
|
|
|
let config_dir = proj_dirs.config_dir();
|
|
let config_file = config_dir.join(Path::new(SAVE_FILE_NAME));
|
|
if !config_file.exists() || !config_file.is_file() {
|
|
if manual_execution {
|
|
// Don't show errors when there is no configuration file when starting app
|
|
text_view_errors.get_buffer().unwrap().set_text(format!("Cannot load configuration from file {:?}.", config_file.display()).as_str());
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Loading Data
|
|
let loaded_data: String = match fs::read_to_string(&config_file) {
|
|
Ok(t) => t,
|
|
Err(_) => {
|
|
text_view_errors.get_buffer().unwrap().set_text(format!("Failed to read data from file {:?}.", config_file).as_str());
|
|
return;
|
|
}
|
|
};
|
|
|
|
// Parsing Data
|
|
|
|
let mut included_directories: Vec<String> = Vec::new();
|
|
let mut excluded_directories: Vec<String> = Vec::new();
|
|
let mut excluded_items: Vec<String> = Vec::new();
|
|
let mut allowed_extensions: Vec<String> = Vec::new();
|
|
let mut loading_at_start: bool = true;
|
|
let mut saving_at_exit: bool = true;
|
|
|
|
let mut current_type = TypeOfLoadedData::None;
|
|
for (line_number, line) in loaded_data.replace("\r\n", "\n").split('\n').enumerate() {
|
|
let line: String = line.trim().to_string();
|
|
if line.trim().is_empty() {
|
|
continue; // Empty line, so we just skip it
|
|
}
|
|
if line.starts_with("--included_directories") {
|
|
current_type = TypeOfLoadedData::IncludedDirectories;
|
|
} else if line.starts_with("--excluded_directories") {
|
|
current_type = TypeOfLoadedData::ExcludedDirectories;
|
|
} else if line.starts_with("--excluded_items") {
|
|
current_type = TypeOfLoadedData::ExcludedItems;
|
|
} else if line.starts_with("--allowed_extensions") {
|
|
current_type = TypeOfLoadedData::AllowedExtensions;
|
|
} else if line.starts_with("--load_at_start") {
|
|
current_type = TypeOfLoadedData::LoadingAtStart;
|
|
} else if line.starts_with("--save_at_exit") {
|
|
current_type = TypeOfLoadedData::SavingAtExit;
|
|
} else {
|
|
match current_type {
|
|
TypeOfLoadedData::None => {
|
|
text_view_errors
|
|
.get_buffer()
|
|
.unwrap()
|
|
.set_text(format!("Found orphan data in line {} \"\"\"{}\"\"\" when loading file {:?}", line_number, line, config_file).as_str());
|
|
return;
|
|
}
|
|
TypeOfLoadedData::IncludedDirectories => {
|
|
included_directories.push(line);
|
|
}
|
|
TypeOfLoadedData::ExcludedDirectories => {
|
|
excluded_directories.push(line);
|
|
}
|
|
TypeOfLoadedData::ExcludedItems => {
|
|
excluded_items.push(line);
|
|
}
|
|
TypeOfLoadedData::AllowedExtensions => {
|
|
allowed_extensions.push(line);
|
|
}
|
|
TypeOfLoadedData::LoadingAtStart => {
|
|
let line = line.to_lowercase();
|
|
if line == "1" || line == "true" {
|
|
loading_at_start = true;
|
|
} else if line == "0" || line == "false" {
|
|
loading_at_start = false;
|
|
} else {
|
|
text_view_errors
|
|
.get_buffer()
|
|
.unwrap()
|
|
.set_text(format!("Found invalid data in line {} \"\"\"{}\"\"\" isn't proper value(0/1/true/false) when loading file {:?}", line_number, line, config_file).as_str());
|
|
}
|
|
}
|
|
TypeOfLoadedData::SavingAtExit => {
|
|
let line = line.to_lowercase();
|
|
if line == "1" || line == "true" {
|
|
saving_at_exit = true;
|
|
} else if line == "0" || line == "false" {
|
|
saving_at_exit = false;
|
|
} else {
|
|
text_view_errors
|
|
.get_buffer()
|
|
.unwrap()
|
|
.set_text(format!("Found invalid data in line {} \"\"\"{}\"\"\" isn't proper value(0/1/true/false) when loading file {:?}", line_number, line, config_file).as_str());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Setting data
|
|
if manual_execution || loading_at_start {
|
|
//// Included Directories
|
|
let scrolled_window_included_directories = gui_data.scrolled_window_included_directories.clone();
|
|
let list_store = get_list_store(&scrolled_window_included_directories);
|
|
list_store.clear();
|
|
|
|
let col_indices = [0];
|
|
|
|
for directory in included_directories {
|
|
let values: [&dyn ToValue; 1] = [&directory];
|
|
list_store.set(&list_store.append(), &col_indices, &values);
|
|
}
|
|
|
|
//// Exclude Directories
|
|
let scrolled_window_excluded_directories = gui_data.scrolled_window_excluded_directories.clone();
|
|
let list_store = get_list_store(&scrolled_window_excluded_directories);
|
|
list_store.clear();
|
|
|
|
let col_indices = [0];
|
|
|
|
for directory in excluded_directories {
|
|
let values: [&dyn ToValue; 1] = [&directory];
|
|
list_store.set(&list_store.append(), &col_indices, &values);
|
|
}
|
|
|
|
//// Excluded Items
|
|
let entry_excluded_items = gui_data.entry_excluded_items.clone();
|
|
entry_excluded_items.set_text(excluded_items.iter().map(|e| e.to_string() + ",").collect::<String>().as_str());
|
|
|
|
//// Allowed extensions
|
|
let entry_allowed_extensions = gui_data.entry_allowed_extensions.clone();
|
|
entry_allowed_extensions.set_text(allowed_extensions.iter().map(|e| e.to_string() + ",").collect::<String>().as_str());
|
|
|
|
//// Buttons
|
|
gui_data.check_button_settings_load_at_start.set_active(loading_at_start);
|
|
gui_data.check_button_settings_save_at_exit.set_active(saving_at_exit);
|
|
} else {
|
|
gui_data.check_button_settings_load_at_start.set_active(false);
|
|
}
|
|
|
|
if manual_execution {
|
|
text_view_errors.get_buffer().unwrap().set_text(format!("Properly loaded configuration from file {:?}", config_file).as_str());
|
|
}
|
|
} else {
|
|
text_view_errors.get_buffer().unwrap().set_text("Failed to get home directory, so can't load file.");
|
|
}
|
|
}
|
|
|
|
pub fn reset_configuration(gui_data: &GuiData, manual_clearing: bool) {
|
|
// TODO Maybe add popup dialog to confirm resetting
|
|
let text_view_errors = gui_data.text_view_errors.clone();
|
|
// Resetting included directories
|
|
{
|
|
let col_indices = [0];
|
|
let scrolled_window_included_directories = gui_data.scrolled_window_included_directories.clone();
|
|
let list_store = get_list_store(&scrolled_window_included_directories);
|
|
list_store.clear();
|
|
|
|
let current_dir: String = match env::current_dir() {
|
|
Ok(t) => t.to_str().unwrap().to_string(),
|
|
Err(_) => {
|
|
if cfg!(target_family = "unix") {
|
|
println!("Failed to read current directory, setting /home instead");
|
|
"/home".to_string()
|
|
} else if cfg!(target_family = "windows") {
|
|
println!("Failed to read current directory, setting C:\\ instead");
|
|
"C:\\".to_string()
|
|
} else {
|
|
"".to_string()
|
|
}
|
|
}
|
|
};
|
|
|
|
let values: [&dyn ToValue; 1] = [¤t_dir];
|
|
list_store.set(&list_store.append(), &col_indices, &values);
|
|
}
|
|
// Resetting excluded directories
|
|
{
|
|
let col_indices = [0];
|
|
let scrolled_window_excluded_directories = gui_data.scrolled_window_excluded_directories.clone();
|
|
let list_store = get_list_store(&scrolled_window_excluded_directories);
|
|
list_store.clear();
|
|
if cfg!(target_family = "unix") {
|
|
for i in ["/proc", "/dev", "/sys", "/run", "/snap"].iter() {
|
|
let values: [&dyn ToValue; 1] = [&i];
|
|
list_store.set(&list_store.append(), &col_indices, &values);
|
|
}
|
|
}
|
|
}
|
|
// Resetting excluded items
|
|
{
|
|
let entry_excluded_items = gui_data.entry_excluded_items.clone();
|
|
if cfg!(target_family = "unix") {
|
|
entry_excluded_items.set_text("*/.git/*,*/node_modules/*,*/lost+found/*,*/Trash/*");
|
|
}
|
|
if cfg!(target_family = "windows") {
|
|
entry_excluded_items.set_text("*/.git/*,*/node_modules/*,*/lost+found/*,*:/windows/*");
|
|
}
|
|
}
|
|
// Resetting allowed extensions
|
|
{
|
|
let entry_allowed_extensions = gui_data.entry_allowed_extensions.clone();
|
|
entry_allowed_extensions.set_text("");
|
|
}
|
|
|
|
// Set settings
|
|
{
|
|
gui_data.check_button_settings_save_at_exit.set_active(true);
|
|
gui_data.check_button_settings_load_at_start.set_active(true);
|
|
}
|
|
if manual_clearing {
|
|
text_view_errors.get_buffer().unwrap().set_text("Current configuration was cleared.");
|
|
}
|
|
}
|