From c9719758c7186304785a9e9065b4b584d1b15fab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mikrut?= <41945903+qarmin@users.noreply.github.com> Date: Thu, 25 Nov 2021 08:36:49 +0100 Subject: [PATCH] Clean GUI code, make it easier to understand and change (#462) * Add static variable for basic notebook data * Opening, selecting results by space, enter and mouse * Now hard/symbolic links * Now deleting * Now popovers * Move tests to different function * Don't crash when there is no selected records * Button symlinks * Now move * Compute results * Move again * Again Popovers * More popovers and more * Key clicking, removing * KEY_DELETE * No more GuiData clone * Adding directories * Reorganize a little files --- LICENSE | 2 +- ..._compute_results.rs => compute_results.rs} | 419 ++++---- czkawka_gui/src/connect_button_delete.rs | 281 ++--- czkawka_gui/src/connect_button_hardlink.rs | 194 ++-- czkawka_gui/src/connect_button_move.rs | 302 ++---- czkawka_gui/src/connect_button_save.rs | 16 +- czkawka_gui/src/connect_button_select.rs | 81 +- czkawka_gui/src/connect_button_symlink.rs | 70 -- czkawka_gui/src/connect_popovers.rs | 956 ++++++------------ .../src/connect_selection_of_directories.rs | 158 +-- czkawka_gui/src/connect_settings.rs | 19 +- czkawka_gui/src/create_tree_view.rs | 60 +- czkawka_gui/src/double_click_opening.rs | 187 ---- czkawka_gui/src/gui_main_notebook.rs | 16 + czkawka_gui/src/help_functions.rs | 312 +++++- czkawka_gui/src/initialize_gui.rs | 258 ++--- czkawka_gui/src/main.rs | 21 +- czkawka_gui/src/opening_selecting_records.rs | 119 +++ czkawka_gui/src/saving_loading.rs | 114 ++- czkawka_gui/src/tests.rs | 37 + 20 files changed, 1461 insertions(+), 2161 deletions(-) rename czkawka_gui/src/{connect_compute_results.rs => compute_results.rs} (60%) delete mode 100644 czkawka_gui/src/connect_button_symlink.rs delete mode 100644 czkawka_gui/src/double_click_opening.rs create mode 100644 czkawka_gui/src/opening_selecting_records.rs create mode 100644 czkawka_gui/src/tests.rs diff --git a/LICENSE b/LICENSE index 5ebe4f1..5d8cf32 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 Rafał Mikrut +Copyright (c) 2020-2021 Rafał Mikrut Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/czkawka_gui/src/connect_compute_results.rs b/czkawka_gui/src/compute_results.rs similarity index 60% rename from czkawka_gui/src/connect_compute_results.rs rename to czkawka_gui/src/compute_results.rs index 528814d..945acde 100644 --- a/czkawka_gui/src/connect_compute_results.rs +++ b/czkawka_gui/src/compute_results.rs @@ -1,4 +1,6 @@ use humansize::{file_size_opts as options, FileSize}; +use std::cell::RefCell; +use std::collections::HashMap; use crate::gui_data::GuiData; use crate::help_functions::*; @@ -10,6 +12,7 @@ use czkawka_core::similar_images; use glib::Receiver; use gtk::prelude::*; use std::path::PathBuf; +use std::rc::Rc; pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver) { let buttons_search = gui_data.bottom_buttons.buttons_search.clone(); @@ -129,28 +132,31 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< }; let values: [(u32, &dyn ToValue); 8] = [ - (0, &false), - (1, &false), - (2, &name), - (3, (&(format!("{} results", vector.len())))), - (4, (&"".to_string())), // No text in 3 column - (5, (&(0))), // Not used here - (6, &(HEADER_ROW_COLOR.to_string())), - (7, &(TEXT_COLOR.to_string())), + (ColumnsDuplicates::ActivatableSelectButton as u32, &false), + (ColumnsDuplicates::SelectionButton as u32, &false), + (ColumnsDuplicates::Name as u32, &name), + (ColumnsDuplicates::Path as u32, (&(format!("{} results", vector.len())))), + (ColumnsDuplicates::Modification as u32, (&"".to_string())), // No text in 3 column + (ColumnsDuplicates::ModificationAsSecs as u32, (&(0))), // Not used here + (ColumnsDuplicates::Color as u32, &(HEADER_ROW_COLOR.to_string())), + (ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())), ]; list_store.set(&list_store.append(), &values); for entry in vector { let (directory, file) = split_path(&entry.path); let values: [(u32, &dyn ToValue); 8] = [ - (0, &true), - (1, &false), - (2, &file), - (3, &directory), - (4, &(format!("{} - ({})", NaiveDateTime::from_timestamp(entry.modified_date as i64, 0), entry.size.file_size(options::BINARY).unwrap()))), - (5, &(entry.modified_date)), - (6, &(MAIN_ROW_COLOR.to_string())), - (7, &(TEXT_COLOR.to_string())), + (ColumnsDuplicates::ActivatableSelectButton as u32, &true), + (ColumnsDuplicates::SelectionButton as u32, &false), + (ColumnsDuplicates::Name as u32, &file), + (ColumnsDuplicates::Path as u32, &directory), + ( + ColumnsDuplicates::Modification as u32, + &(format!("{} - ({})", NaiveDateTime::from_timestamp(entry.modified_date as i64, 0), entry.size.file_size(options::BINARY).unwrap())), + ), + (ColumnsDuplicates::ModificationAsSecs as u32, &(entry.modified_date)), + (ColumnsDuplicates::Color as u32, &(MAIN_ROW_COLOR.to_string())), + (ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())), ]; list_store.set(&list_store.append(), &values); } @@ -174,17 +180,17 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< }; let values: [(u32, &dyn ToValue); 8] = [ - (0, &false), - (1, &false), - (2, &(format!("{} x {} ({} bytes)", vector.len(), size.file_size(options::BINARY).unwrap(), size))), + (ColumnsDuplicates::ActivatableSelectButton as u32, &false), + (ColumnsDuplicates::SelectionButton as u32, &false), + (ColumnsDuplicates::Name as u32, &(format!("{} x {} ({} bytes)", vector.len(), size.file_size(options::BINARY).unwrap(), size))), ( - 3, + ColumnsDuplicates::Path as u32, &(format!("{} ({} bytes) lost", ((vector.len() - 1) as u64 * *size as u64).file_size(options::BINARY).unwrap(), (vector.len() - 1) as u64 * *size as u64)), ), - (4, &"".to_string()), // No text in 3 column - (5, &(0)), - (6, &(HEADER_ROW_COLOR.to_string())), - (7, &(TEXT_COLOR.to_string())), + (ColumnsDuplicates::Modification as u32, &"".to_string()), // No text in 3 column + (ColumnsDuplicates::ModificationAsSecs as u32, &(0)), + (ColumnsDuplicates::Color as u32, &(HEADER_ROW_COLOR.to_string())), + (ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())), ]; list_store.set(&list_store.append(), &values); @@ -192,14 +198,14 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< let (directory, file) = split_path(&entry.path); let values: [(u32, &dyn ToValue); 8] = [ - (0, &true), - (1, &false), - (2, &file), - (3, &directory), - (4, &(NaiveDateTime::from_timestamp(entry.modified_date as i64, 0).to_string())), - (5, &(entry.modified_date)), - (6, &(MAIN_ROW_COLOR.to_string())), - (7, &(TEXT_COLOR.to_string())), + (ColumnsDuplicates::ActivatableSelectButton as u32, &true), + (ColumnsDuplicates::SelectionButton as u32, &false), + (ColumnsDuplicates::Name as u32, &file), + (ColumnsDuplicates::Path as u32, &directory), + (ColumnsDuplicates::Modification as u32, &(NaiveDateTime::from_timestamp(entry.modified_date as i64, 0).to_string())), + (ColumnsDuplicates::ModificationAsSecs as u32, &(entry.modified_date)), + (ColumnsDuplicates::Color as u32, &(MAIN_ROW_COLOR.to_string())), + (ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())), ]; list_store.set(&list_store.append(), &values); @@ -223,31 +229,31 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< vector.clone() }; let values: [(u32, &dyn ToValue); 8] = [ - (0, &false), - (1, &false), - (2, &(format!("{} x {} ({} bytes)", vector.len(), size.file_size(options::BINARY).unwrap(), size))), + (ColumnsDuplicates::ActivatableSelectButton as u32, &false), + (ColumnsDuplicates::SelectionButton as u32, &false), + (ColumnsDuplicates::Name as u32, &(format!("{} x {} ({} bytes)", vector.len(), size.file_size(options::BINARY).unwrap(), size))), ( - 3, + ColumnsDuplicates::Path as u32, &(format!("{} ({} bytes) lost", ((vector.len() - 1) as u64 * *size as u64).file_size(options::BINARY).unwrap(), (vector.len() - 1) as u64 * *size as u64)), ), - (4, &"".to_string()), // No text in 3 column - (5, &(0)), // Not used here - (6, &(HEADER_ROW_COLOR.to_string())), - (7, &(TEXT_COLOR.to_string())), + (ColumnsDuplicates::Modification as u32, &"".to_string()), // No text in 3 column + (ColumnsDuplicates::ModificationAsSecs as u32, &(0)), // Not used here + (ColumnsDuplicates::Color as u32, &(HEADER_ROW_COLOR.to_string())), + (ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())), ]; list_store.set(&list_store.append(), &values); for entry in vector { let (directory, file) = split_path(&entry.path); let values: [(u32, &dyn ToValue); 8] = [ - (0, &true), - (1, &false), - (2, &file), - (3, &directory), - (4, &(NaiveDateTime::from_timestamp(entry.modified_date as i64, 0).to_string())), - (5, &(entry.modified_date)), - (6, &(MAIN_ROW_COLOR.to_string())), - (7, &(TEXT_COLOR.to_string())), + (ColumnsDuplicates::ActivatableSelectButton as u32, &true), + (ColumnsDuplicates::SelectionButton as u32, &false), + (ColumnsDuplicates::Name as u32, &file), + (ColumnsDuplicates::Path as u32, &directory), + (ColumnsDuplicates::Modification as u32, &(NaiveDateTime::from_timestamp(entry.modified_date as i64, 0).to_string())), + (ColumnsDuplicates::ModificationAsSecs as u32, &(entry.modified_date)), + (ColumnsDuplicates::Color as u32, &(MAIN_ROW_COLOR.to_string())), + (ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())), ]; list_store.set(&list_store.append(), &values); } @@ -265,21 +271,8 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< { *shared_duplication_state.borrow_mut() = df; - if duplicates_number > 0 { - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Duplicate).unwrap().get_mut("save").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Duplicate).unwrap().get_mut("delete").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Duplicate).unwrap().get_mut("select").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Duplicate).unwrap().get_mut("symlink").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Duplicate).unwrap().get_mut("hardlink").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Duplicate).unwrap().get_mut("move").unwrap() = true; - } else { - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Duplicate).unwrap().get_mut("save").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Duplicate).unwrap().get_mut("delete").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Duplicate).unwrap().get_mut("select").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Duplicate).unwrap().get_mut("symlink").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Duplicate).unwrap().get_mut("hardlink").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Duplicate).unwrap().get_mut("move").unwrap() = false; - } + set_specific_buttons_as_active(&shared_buttons, &NotebookMainEnum::Duplicate, &["save", "delete", "select", "symlink", "hardlink", "move"], duplicates_number > 0); + set_buttons(&mut *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Duplicate).unwrap(), &buttons_array, &buttons_names); } } @@ -309,7 +302,12 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< for path in vector { let (directory, file) = split_path(&path); - let values: [(u32, &dyn ToValue); 4] = [(0, &false), (1, &file), (2, &directory), (3, &(NaiveDateTime::from_timestamp(hashmap.get(&path).unwrap().modified_date as i64, 0).to_string()))]; + let values: [(u32, &dyn ToValue); 4] = [ + (ColumnsEmptyFolders::SelectionButton as u32, &false), + (ColumnsEmptyFolders::Name as u32, &file), + (ColumnsEmptyFolders::Path as u32, &directory), + (ColumnsEmptyFolders::Modification as u32, &(NaiveDateTime::from_timestamp(hashmap.get(&path).unwrap().modified_date as i64, 0).to_string())), + ]; list_store.set(&list_store.append(), &values); } print_text_messages_to_text_view(text_messages, &text_view_errors); @@ -319,17 +317,8 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< { *shared_empty_folders_state.borrow_mut() = ef; - if empty_folder_number > 0 { - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyDirectories).unwrap().get_mut("save").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyDirectories).unwrap().get_mut("delete").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyDirectories).unwrap().get_mut("select").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyDirectories).unwrap().get_mut("move").unwrap() = true; - } else { - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyDirectories).unwrap().get_mut("save").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyDirectories).unwrap().get_mut("delete").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyDirectories).unwrap().get_mut("select").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyDirectories).unwrap().get_mut("move").unwrap() = false; - } + set_specific_buttons_as_active(&shared_buttons, &NotebookMainEnum::EmptyDirectories, &["save", "delete", "select", "move"], empty_folder_number > 0); + set_buttons(&mut *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyDirectories).unwrap(), &buttons_array, &buttons_names); } } @@ -360,7 +349,12 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< for file_entry in vector { let (directory, file) = split_path(&file_entry.path); - let values: [(u32, &dyn ToValue); 4] = [(0, &false), (1, &file), (2, &directory), (3, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string()))]; + let values: [(u32, &dyn ToValue); 4] = [ + (ColumnsEmptyFiles::SelectionButton as u32, &false), + (ColumnsEmptyFiles::Name as u32, &file), + (ColumnsEmptyFiles::Path as u32, &directory), + (ColumnsEmptyFiles::Modification as u32, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())), + ]; list_store.set(&list_store.append(), &values); } print_text_messages_to_text_view(text_messages, &text_view_errors); @@ -370,17 +364,8 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< { *shared_empty_files_state.borrow_mut() = vf; - if empty_files_number > 0 { - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyFiles).unwrap().get_mut("save").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyFiles).unwrap().get_mut("delete").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyFiles).unwrap().get_mut("select").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyFiles).unwrap().get_mut("move").unwrap() = true; - } else { - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyFiles).unwrap().get_mut("save").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyFiles).unwrap().get_mut("delete").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyFiles).unwrap().get_mut("select").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyFiles).unwrap().get_mut("move").unwrap() = false; - } + set_specific_buttons_as_active(&shared_buttons, &NotebookMainEnum::EmptyFiles, &["save", "delete", "select", "move"], empty_files_number > 0); + set_buttons(&mut *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyFiles).unwrap(), &buttons_array, &buttons_names); } } @@ -411,11 +396,11 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< for file_entry in vector { let (directory, file) = split_path(&file_entry.path); let values: [(u32, &dyn ToValue); 5] = [ - (0, &false), - (1, &(format!("{} ({} bytes)", size.file_size(options::BINARY).unwrap(), size))), - (2, &file), - (3, &directory), - (4, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())), + (ColumnsBigFiles::SelectionButton as u32, &false), + (ColumnsBigFiles::Size as u32, &(format!("{} ({} bytes)", size.file_size(options::BINARY).unwrap(), size))), + (ColumnsBigFiles::Name as u32, &file), + (ColumnsBigFiles::Path as u32, &directory), + (ColumnsBigFiles::Modification as u32, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())), ]; list_store.set(&list_store.append(), &values); } @@ -427,17 +412,8 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< { *shared_big_files_state.borrow_mut() = bf; - if biggest_files_number > 0 { - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BigFiles).unwrap().get_mut("save").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BigFiles).unwrap().get_mut("delete").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BigFiles).unwrap().get_mut("select").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BigFiles).unwrap().get_mut("move").unwrap() = true; - } else { - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BigFiles).unwrap().get_mut("save").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BigFiles).unwrap().get_mut("delete").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BigFiles).unwrap().get_mut("select").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BigFiles).unwrap().get_mut("move").unwrap() = false; - } + set_specific_buttons_as_active(&shared_buttons, &NotebookMainEnum::BigFiles, &["save", "delete", "select", "move"], biggest_files_number > 0); + set_buttons(&mut *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BigFiles).unwrap(), &buttons_array, &buttons_names); } } @@ -468,7 +444,12 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< for file_entry in vector { let (directory, file) = split_path(&file_entry.path); - let values: [(u32, &dyn ToValue); 4] = [(0, &false), (1, &file), (2, &directory), (3, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string()))]; + let values: [(u32, &dyn ToValue); 4] = [ + (ColumnsTemporaryFiles::SelectionButton as u32, &false), + (ColumnsTemporaryFiles::Name as u32, &file), + (ColumnsTemporaryFiles::Path as u32, &directory), + (ColumnsTemporaryFiles::Modification as u32, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())), + ]; list_store.set(&list_store.append(), &values); } print_text_messages_to_text_view(text_messages, &text_view_errors); @@ -478,17 +459,8 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< { *shared_temporary_files_state.borrow_mut() = tf; - if temporary_files_number > 0 { - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Temporary).unwrap().get_mut("save").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Temporary).unwrap().get_mut("delete").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Temporary).unwrap().get_mut("select").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Temporary).unwrap().get_mut("move").unwrap() = true; - } else { - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Temporary).unwrap().get_mut("save").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Temporary).unwrap().get_mut("delete").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Temporary).unwrap().get_mut("select").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Temporary).unwrap().get_mut("move").unwrap() = false; - } + set_specific_buttons_as_active(&shared_buttons, &NotebookMainEnum::Temporary, &["save", "delete", "select", "move"], temporary_files_number > 0); + set_buttons(&mut *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Temporary).unwrap(), &buttons_array, &buttons_names); } } @@ -525,18 +497,18 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< // Header let values: [(u32, &dyn ToValue); 12] = [ - (0, &false), - (1, &false), - (2, &"".to_string()), - (3, &"".to_string()), - (4, &(0)), - (5, &"".to_string()), - (6, &"".to_string()), - (7, &"".to_string()), - (8, &"".to_string()), - (9, &(0)), - (10, &(HEADER_ROW_COLOR.to_string())), - (11, &(TEXT_COLOR.to_string())), + (ColumnsSimilarImages::ActivatableSelectButton as u32, &false), + (ColumnsSimilarImages::SelectionButton as u32, &false), + (ColumnsSimilarImages::Similarity as u32, &"".to_string()), + (ColumnsSimilarImages::Size as u32, &"".to_string()), + (ColumnsSimilarImages::SizeAsBytes as u32, &(0)), + (ColumnsSimilarImages::Dimensions as u32, &"".to_string()), + (ColumnsSimilarImages::Name as u32, &"".to_string()), + (ColumnsSimilarImages::Path as u32, &"".to_string()), + (ColumnsSimilarImages::Modification as u32, &"".to_string()), + (ColumnsSimilarImages::ModificationAsSecs as u32, &(0)), + (ColumnsSimilarImages::Color as u32, &(HEADER_ROW_COLOR.to_string())), + (ColumnsSimilarImages::TextColor as u32, &(TEXT_COLOR.to_string())), ]; list_store.set(&list_store.append(), &values); @@ -544,18 +516,18 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< for file_entry in vec_file_entry.iter() { let (directory, file) = split_path(&file_entry.path); let values: [(u32, &dyn ToValue); 12] = [ - (0, &true), - (1, &false), - (2, &(similar_images::get_string_from_similarity(&file_entry.similarity, hash_size).to_string())), - (3, &file_entry.size.file_size(options::BINARY).unwrap()), - (4, &file_entry.size), - (5, &file_entry.dimensions), - (6, &file), - (7, &directory), - (8, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())), - (9, &(file_entry.modified_date)), - (10, &(MAIN_ROW_COLOR.to_string())), - (11, &(TEXT_COLOR.to_string())), + (ColumnsSimilarImages::ActivatableSelectButton as u32, &true), + (ColumnsSimilarImages::SelectionButton as u32, &false), + (ColumnsSimilarImages::Similarity as u32, &(similar_images::get_string_from_similarity(&file_entry.similarity, hash_size).to_string())), + (ColumnsSimilarImages::Size as u32, &file_entry.size.file_size(options::BINARY).unwrap()), + (ColumnsSimilarImages::SizeAsBytes as u32, &file_entry.size), + (ColumnsSimilarImages::Dimensions as u32, &file_entry.dimensions), + (ColumnsSimilarImages::Name as u32, &file), + (ColumnsSimilarImages::Path as u32, &directory), + (ColumnsSimilarImages::Modification as u32, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())), + (ColumnsSimilarImages::ModificationAsSecs as u32, &(file_entry.modified_date)), + (ColumnsSimilarImages::Color as u32, &(MAIN_ROW_COLOR.to_string())), + (ColumnsSimilarImages::TextColor as u32, &(TEXT_COLOR.to_string())), ]; list_store.set(&list_store.append(), &values); } @@ -568,21 +540,8 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< { *shared_similar_images_state.borrow_mut() = sf; - if base_images_size > 0 { - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarImages).unwrap().get_mut("save").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarImages).unwrap().get_mut("delete").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarImages).unwrap().get_mut("select").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarImages).unwrap().get_mut("symlink").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarImages).unwrap().get_mut("hardlink").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarImages).unwrap().get_mut("move").unwrap() = true; - } else { - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarImages).unwrap().get_mut("save").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarImages).unwrap().get_mut("delete").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarImages).unwrap().get_mut("select").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarImages).unwrap().get_mut("symlink").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarImages).unwrap().get_mut("hardlink").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarImages).unwrap().get_mut("move").unwrap() = false; - } + set_specific_buttons_as_active(&shared_buttons, &NotebookMainEnum::SimilarImages, &["save", "delete", "select", "symlink", "hardlink", "move"], base_images_size > 0); + set_buttons(&mut *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarImages).unwrap(), &buttons_array, &buttons_names); } } @@ -620,7 +579,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< // Header let values: [(u32, &dyn ToValue); 10] = [ (ColumnsSimilarVideos::ActivatableSelectButton as u32, &false), - (ColumnsSimilarVideos::ActiveSelectButton as u32, &false), + (ColumnsSimilarVideos::SelectionButton as u32, &false), (ColumnsSimilarVideos::Size as u32, &"".to_string()), (ColumnsSimilarVideos::SizeAsBytes as u32, &(0)), (ColumnsSimilarVideos::Name as u32, &"".to_string()), @@ -637,7 +596,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< let (directory, file) = split_path(&file_entry.path); let values: [(u32, &dyn ToValue); 10] = [ (ColumnsSimilarVideos::ActivatableSelectButton as u32, &true), - (ColumnsSimilarVideos::ActiveSelectButton as u32, &false), + (ColumnsSimilarVideos::SelectionButton as u32, &false), (ColumnsSimilarVideos::Size as u32, &file_entry.size.file_size(options::BINARY).unwrap()), (ColumnsSimilarVideos::SizeAsBytes as u32, &file_entry.size), (ColumnsSimilarVideos::Name as u32, &file), @@ -658,21 +617,8 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< { *shared_similar_videos_state.borrow_mut() = ff; - if base_videos_size > 0 { - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarVideos).unwrap().get_mut("save").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarVideos).unwrap().get_mut("delete").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarVideos).unwrap().get_mut("select").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarVideos).unwrap().get_mut("symlink").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarVideos).unwrap().get_mut("hardlink").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarVideos).unwrap().get_mut("move").unwrap() = true; - } else { - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarVideos).unwrap().get_mut("save").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarVideos).unwrap().get_mut("delete").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarVideos).unwrap().get_mut("select").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarVideos).unwrap().get_mut("symlink").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarVideos).unwrap().get_mut("hardlink").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarVideos).unwrap().get_mut("move").unwrap() = false; - } + set_specific_buttons_as_active(&shared_buttons, &NotebookMainEnum::SimilarVideos, &["save", "delete", "select", "symlink", "hardlink", "move"], base_videos_size > 0); + set_buttons(&mut *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarVideos).unwrap(), &buttons_array, &buttons_names); } } @@ -718,71 +664,71 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< }; let values: [(u32, &dyn ToValue); 15] = [ - (0, &false), - (1, &false), - (2, &"".to_string()), - (3, &(0)), - (4, &"".to_string()), - (5, &"".to_string()), + (ColumnsSameMusic::ActivatableSelectButton as u32, &false), + (ColumnsSameMusic::SelectionButton as u32, &false), + (ColumnsSameMusic::Size as u32, &"".to_string()), + (ColumnsSameMusic::SizeAsBytes as u32, &(0)), + (ColumnsSameMusic::Name as u32, &"".to_string()), + (ColumnsSameMusic::Path as u32, &"".to_string()), ( - 6, + ColumnsSameMusic::Title as u32, &(match is_title { true => text.clone(), false => "".to_string(), }), ), ( - 7, + ColumnsSameMusic::Artist as u32, &(match is_artist { true => text.clone(), false => "".to_string(), }), ), ( - 8, + ColumnsSameMusic::AlbumTitle as u32, &(match is_album_title { true => text.clone(), false => "".to_string(), }), ), ( - 9, + ColumnsSameMusic::AlbumArtist as u32, &(match is_album_artist { true => text.clone(), false => "".to_string(), }), ), ( - 10, + ColumnsSameMusic::Year as u32, &(match is_year { true => text.clone(), false => "".to_string(), }), ), - (11, &"".to_string()), - (12, &(0)), - (13, &(HEADER_ROW_COLOR.to_string())), - (14, &(TEXT_COLOR.to_string())), + (ColumnsSameMusic::Modification as u32, &"".to_string()), + (ColumnsSameMusic::ModificationAsSecs as u32, &(0)), + (ColumnsSameMusic::Color as u32, &(HEADER_ROW_COLOR.to_string())), + (ColumnsSameMusic::TextColor as u32, &(TEXT_COLOR.to_string())), ]; list_store.set(&list_store.append(), &values); for file_entry in vec_file_entry { let (directory, file) = split_path(&file_entry.path); let values: [(u32, &dyn ToValue); 15] = [ - (0, &true), - (1, &false), - (2, &file_entry.size.file_size(options::BINARY).unwrap()), - (3, &file_entry.size), - (4, &file), - (5, &directory), - (6, &file_entry.title), - (7, &file_entry.artist), - (8, &file_entry.album_title), - (9, &file_entry.album_artist), - (10, &file_entry.year.to_string()), - (11, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())), - (12, &(file_entry.modified_date)), - (13, &(MAIN_ROW_COLOR.to_string())), - (14, &(TEXT_COLOR.to_string())), + (ColumnsSameMusic::ActivatableSelectButton as u32, &true), + (ColumnsSameMusic::SelectionButton as u32, &false), + (ColumnsSameMusic::Size as u32, &file_entry.size.file_size(options::BINARY).unwrap()), + (ColumnsSameMusic::SizeAsBytes as u32, &file_entry.size), + (ColumnsSameMusic::Name as u32, &file), + (ColumnsSameMusic::Path as u32, &directory), + (ColumnsSameMusic::Title as u32, &file_entry.title), + (ColumnsSameMusic::Artist as u32, &file_entry.artist), + (ColumnsSameMusic::AlbumTitle as u32, &file_entry.album_title), + (ColumnsSameMusic::AlbumArtist as u32, &file_entry.album_artist), + (ColumnsSameMusic::Year as u32, &file_entry.year.to_string()), + (ColumnsSameMusic::Modification as u32, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())), + (ColumnsSameMusic::ModificationAsSecs as u32, &(file_entry.modified_date)), + (ColumnsSameMusic::Color as u32, &(MAIN_ROW_COLOR.to_string())), + (ColumnsSameMusic::TextColor as u32, &(TEXT_COLOR.to_string())), ]; list_store.set(&list_store.append(), &values); } @@ -794,21 +740,8 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< { *shared_same_music_state.borrow_mut() = mf; - if same_music_number > 0 { - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SameMusic).unwrap().get_mut("save").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SameMusic).unwrap().get_mut("delete").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SameMusic).unwrap().get_mut("select").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SameMusic).unwrap().get_mut("symlink").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SameMusic).unwrap().get_mut("hardlink").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SameMusic).unwrap().get_mut("move").unwrap() = true; - } else { - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SameMusic).unwrap().get_mut("save").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SameMusic).unwrap().get_mut("delete").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SameMusic).unwrap().get_mut("select").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SameMusic).unwrap().get_mut("symlink").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SameMusic).unwrap().get_mut("hardlink").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SameMusic).unwrap().get_mut("move").unwrap() = false; - } + set_specific_buttons_as_active(&shared_buttons, &NotebookMainEnum::SameMusic, &["save", "delete", "select", "symlink", "hardlink", "move"], same_music_number > 0); + set_buttons(&mut *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SameMusic).unwrap(), &buttons_array, &buttons_names); } } @@ -841,12 +774,12 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< for file_entry in vector { let (directory, file) = split_path(&file_entry.symlink_path); let values: [(u32, &dyn ToValue); 6] = [ - (0, &false), - (1, &file), - (2, &directory), - (3, &file_entry.destination_path.to_string_lossy().to_string()), - (4, &get_text_from_invalid_symlink_cause(&file_entry.type_of_error)), - (5, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())), + (ColumnsInvalidSymlinks::SelectionButton as u32, &false), + (ColumnsInvalidSymlinks::Name as u32, &file), + (ColumnsInvalidSymlinks::Path as u32, &directory), + (ColumnsInvalidSymlinks::DestinationPath as u32, &file_entry.destination_path.to_string_lossy().to_string()), + (ColumnsInvalidSymlinks::TypeOfError as u32, &get_text_from_invalid_symlink_cause(&file_entry.type_of_error)), + (ColumnsInvalidSymlinks::Modification as u32, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())), ]; list_store.set(&list_store.append(), &values); } @@ -857,17 +790,8 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< { *shared_same_invalid_symlinks.borrow_mut() = ifs; - if invalid_symlinks > 0 { - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Symlinks).unwrap().get_mut("save").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Symlinks).unwrap().get_mut("delete").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Symlinks).unwrap().get_mut("select").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Symlinks).unwrap().get_mut("move").unwrap() = true; - } else { - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Symlinks).unwrap().get_mut("save").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Symlinks).unwrap().get_mut("delete").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Symlinks).unwrap().get_mut("select").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Symlinks).unwrap().get_mut("move").unwrap() = false; - } + set_specific_buttons_as_active(&shared_buttons, &NotebookMainEnum::Symlinks, &["save", "delete", "select", "move"], invalid_symlinks > 0); + set_buttons(&mut *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Symlinks).unwrap(), &buttons_array, &buttons_names); } } @@ -899,11 +823,11 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< for file_entry in vector { let (directory, file) = split_path(&file_entry.path); let values: [(u32, &dyn ToValue); 5] = [ - (0, &false), - (1, &file), - (2, &directory), - (3, &file_entry.error_string), - (4, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())), + (ColumnsBrokenFiles::SelectionButton as u32, &false), + (ColumnsBrokenFiles::Name as u32, &file), + (ColumnsBrokenFiles::Path as u32, &directory), + (ColumnsBrokenFiles::ErrorType as u32, &file_entry.error_string), + (ColumnsBrokenFiles::Modification as u32, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())), ]; list_store.set(&list_store.append(), &values); } @@ -914,17 +838,8 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< { *shared_broken_files_state.borrow_mut() = br; - if broken_files_number > 0 { - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BrokenFiles).unwrap().get_mut("save").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BrokenFiles).unwrap().get_mut("delete").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BrokenFiles).unwrap().get_mut("select").unwrap() = true; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BrokenFiles).unwrap().get_mut("move").unwrap() = true; - } else { - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BrokenFiles).unwrap().get_mut("save").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BrokenFiles).unwrap().get_mut("delete").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BrokenFiles).unwrap().get_mut("select").unwrap() = false; - *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BrokenFiles).unwrap().get_mut("move").unwrap() = false; - } + set_specific_buttons_as_active(&shared_buttons, &NotebookMainEnum::BrokenFiles, &["save", "delete", "select", "move"], broken_files_number > 0); + set_buttons(&mut *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BrokenFiles).unwrap(), &buttons_array, &buttons_names); } } @@ -934,3 +849,9 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< glib::Continue(true) }); } + +fn set_specific_buttons_as_active(buttons_array: &Rc>>>, notebook_enum: &NotebookMainEnum, buttons: &[&str], value_to_set: bool) { + for i in buttons { + *buttons_array.borrow_mut().get_mut(notebook_enum).unwrap().get_mut(*i).unwrap() = value_to_set; + } +} diff --git a/czkawka_gui/src/connect_button_delete.rs b/czkawka_gui/src/connect_button_delete.rs index f344c10..2c12091 100644 --- a/czkawka_gui/src/connect_button_delete.rs +++ b/czkawka_gui/src/connect_button_delete.rs @@ -2,7 +2,7 @@ use crate::gui_data::GuiData; use crate::help_functions::*; use crate::notebook_enums::*; use gtk::prelude::*; -use gtk::Align; +use gtk::{Align, CheckButton, TextView}; use std::collections::BTreeMap; use std::fs; use std::fs::Metadata; @@ -10,159 +10,59 @@ use std::fs::Metadata; // TODO add support for checking if really symlink doesn't point to correct directory/file pub fn connect_button_delete(gui_data: &GuiData) { - let gui_data = gui_data.clone(); let buttons_delete = gui_data.bottom_buttons.buttons_delete.clone(); let tree_view_duplicate_finder = gui_data.main_notebook.tree_view_duplicate_finder.clone(); let notebook_main = gui_data.main_notebook.notebook_main.clone(); let window_main = gui_data.window_main.clone(); - let tree_view_empty_folder_finder = gui_data.main_notebook.tree_view_empty_folder_finder.clone(); - let tree_view_big_files_finder = gui_data.main_notebook.tree_view_big_files_finder.clone(); - let tree_view_empty_files_finder = gui_data.main_notebook.tree_view_empty_files_finder.clone(); - let tree_view_temporary_files_finder = gui_data.main_notebook.tree_view_temporary_files_finder.clone(); - let tree_view_similar_images_finder = gui_data.main_notebook.tree_view_similar_images_finder.clone(); - let tree_view_similar_videos_finder = gui_data.main_notebook.tree_view_similar_videos_finder.clone(); - let tree_view_same_music_finder = gui_data.main_notebook.tree_view_same_music_finder.clone(); - let tree_view_invalid_symlinks = gui_data.main_notebook.tree_view_invalid_symlinks.clone(); - let tree_view_broken_files = gui_data.main_notebook.tree_view_broken_files.clone(); let check_button_settings_confirm_deletion = gui_data.settings.check_button_settings_confirm_deletion.clone(); let check_button_settings_confirm_group_deletion = gui_data.settings.check_button_settings_confirm_group_deletion.clone(); let image_preview_similar_images = gui_data.main_notebook.image_preview_similar_images.clone(); + let image_preview_duplicates = gui_data.main_notebook.image_preview_duplicates.clone(); + + let main_tree_views = gui_data.main_notebook.get_main_tree_views(); + + let check_button_settings_use_trash = gui_data.settings.check_button_settings_use_trash.clone(); + + let text_view_errors = gui_data.text_view_errors.clone(); buttons_delete.connect_clicked(move |_| { + // TODO maybe add to this dialog info how much things will be deleted if !check_if_can_delete_files(&check_button_settings_confirm_deletion, &window_main) { return; } - match to_notebook_main_enum(notebook_main.current_page().unwrap()) { - NotebookMainEnum::Duplicate => { - if !check_button_settings_confirm_group_deletion.is_active() - || !check_if_deleting_all_files_in_group( - &tree_view_duplicate_finder.clone(), - ColumnsDuplicates::Color as i32, - ColumnsDuplicates::ActiveSelectButton as i32, - &window_main, - &check_button_settings_confirm_group_deletion, - ) - { - tree_remove( - &tree_view_duplicate_finder.clone(), - ColumnsDuplicates::Name as i32, - ColumnsDuplicates::Path as i32, - ColumnsDuplicates::Color as i32, - ColumnsDuplicates::ActiveSelectButton as i32, - &gui_data, - ); - } - } - NotebookMainEnum::EmptyDirectories => { - empty_folder_remover( - &tree_view_empty_folder_finder.clone(), - ColumnsEmptyFolders::Name as i32, - ColumnsEmptyFolders::Path as i32, - ColumnsEmptyFolders::ActiveSelectButton as i32, - &gui_data, + let nb_number = notebook_main.current_page().unwrap(); + let tree_view = &main_tree_views[nb_number as usize]; + let nb_object = &NOTEBOOKS_INFOS[nb_number as usize]; + + if let Some(column_color) = nb_object.column_color { + if !check_button_settings_confirm_group_deletion.is_active() || !check_if_deleting_all_files_in_group(tree_view, column_color, nb_object.column_selection, &window_main, &check_button_settings_confirm_group_deletion) { + tree_remove( + &tree_view_duplicate_finder.clone(), + nb_object.column_name, + nb_object.column_path, + column_color, + nb_object.column_selection, + &check_button_settings_use_trash, + &text_view_errors, ); } - NotebookMainEnum::EmptyFiles => { - basic_remove( - &tree_view_empty_files_finder.clone(), - ColumnsEmptyFiles::Name as i32, - ColumnsEmptyFiles::Path as i32, - ColumnsEmptyFiles::ActiveSelectButton as i32, - &gui_data, - ); - } - NotebookMainEnum::Temporary => { - basic_remove( - &tree_view_temporary_files_finder.clone(), - ColumnsTemporaryFiles::Name as i32, - ColumnsTemporaryFiles::Path as i32, - ColumnsTemporaryFiles::ActiveSelectButton as i32, - &gui_data, - ); - } - NotebookMainEnum::BigFiles => { - basic_remove(&tree_view_big_files_finder.clone(), ColumnsBigFiles::Name as i32, ColumnsBigFiles::Path as i32, ColumnsBigFiles::ActiveSelectButton as i32, &gui_data); + } else { + if nb_number == NotebookMainEnum::EmptyDirectories as u32 { + empty_folder_remover(&tree_view.clone(), nb_object.column_name, nb_object.column_path, nb_object.column_selection, &check_button_settings_use_trash, &text_view_errors); + } else { + basic_remove(&tree_view.clone(), nb_object.column_name, nb_object.column_path, nb_object.column_selection, &check_button_settings_use_trash, &text_view_errors); } + } + + match &nb_object.notebook_type { NotebookMainEnum::SimilarImages => { - if !check_button_settings_confirm_group_deletion.is_active() - || !check_if_deleting_all_files_in_group( - &tree_view_similar_images_finder.clone(), - ColumnsSimilarImages::Color as i32, - ColumnsSimilarImages::ActiveSelectButton as i32, - &window_main, - &check_button_settings_confirm_group_deletion, - ) - { - tree_remove( - &tree_view_similar_images_finder.clone(), - ColumnsSimilarImages::Name as i32, - ColumnsSimilarImages::Path as i32, - ColumnsSimilarImages::Color as i32, - ColumnsSimilarImages::ActiveSelectButton as i32, - &gui_data, - ); - image_preview_similar_images.hide(); - } + image_preview_similar_images.hide(); } - NotebookMainEnum::SimilarVideos => { - if !check_button_settings_confirm_group_deletion.is_active() - || !check_if_deleting_all_files_in_group( - &tree_view_similar_videos_finder.clone(), - ColumnsSimilarVideos::Color as i32, - ColumnsSimilarVideos::ActiveSelectButton as i32, - &window_main, - &check_button_settings_confirm_group_deletion, - ) - { - tree_remove( - &tree_view_similar_videos_finder.clone(), - ColumnsSimilarVideos::Name as i32, - ColumnsSimilarVideos::Path as i32, - ColumnsSimilarVideos::Color as i32, - ColumnsSimilarVideos::ActiveSelectButton as i32, - &gui_data, - ); - } - } - NotebookMainEnum::SameMusic => { - if !check_button_settings_confirm_group_deletion.is_active() - || !check_if_deleting_all_files_in_group( - &tree_view_same_music_finder.clone(), - ColumnsSameMusic::Color as i32, - ColumnsSameMusic::ActiveSelectButton as i32, - &window_main, - &check_button_settings_confirm_group_deletion, - ) - { - tree_remove( - &tree_view_same_music_finder.clone(), - ColumnsSameMusic::Name as i32, - ColumnsSameMusic::Path as i32, - ColumnsSameMusic::Color as i32, - ColumnsSameMusic::ActiveSelectButton as i32, - &gui_data, - ); - } - } - NotebookMainEnum::Symlinks => { - basic_remove( - &tree_view_invalid_symlinks.clone(), - ColumnsInvalidSymlinks::Name as i32, - ColumnsInvalidSymlinks::Path as i32, - ColumnsInvalidSymlinks::ActiveSelectButton as i32, - &gui_data, - ); - } - NotebookMainEnum::BrokenFiles => { - basic_remove( - &tree_view_broken_files.clone(), - ColumnsBrokenFiles::Name as i32, - ColumnsBrokenFiles::Path as i32, - ColumnsInvalidSymlinks::ActiveSelectButton as i32, - &gui_data, - ); + NotebookMainEnum::Duplicate => { + image_preview_duplicates.hide(); } + _ => {} } }); } @@ -289,9 +189,8 @@ pub fn check_if_deleting_all_files_in_group(tree_view: >k::TreeView, column_co false } -pub fn empty_folder_remover(tree_view: >k::TreeView, column_file_name: i32, column_path: i32, column_selection: i32, gui_data: &GuiData) { - let text_view_errors = gui_data.text_view_errors.clone(); - let use_trash = gui_data.settings.check_button_settings_use_trash.clone().is_active(); +pub fn empty_folder_remover(tree_view: >k::TreeView, column_file_name: i32, column_path: i32, column_selection: i32, check_button_settings_use_trash: &CheckButton, text_view_errors: &TextView) { + let use_trash = check_button_settings_use_trash.is_active(); let model = get_list_store(tree_view); @@ -308,6 +207,10 @@ pub fn empty_folder_remover(tree_view: >k::TreeView, column_file_name: i32, co } } + if selected_rows.is_empty() { + return; // No selected rows + } + let mut messages: String = "".to_string(); // Must be deleted from end to start, because when deleting entries, TreePath(and also TreeIter) will points to invalid data @@ -390,20 +293,19 @@ pub fn empty_folder_remover(tree_view: >k::TreeView, column_file_name: i32, co text_view_errors.buffer().unwrap().set_text(messages.as_str()); } -pub fn basic_remove(tree_view: >k::TreeView, column_file_name: i32, column_path: i32, column_selection: i32, gui_data: &GuiData) { - let text_view_errors = gui_data.text_view_errors.clone(); - let use_trash = gui_data.settings.check_button_settings_use_trash.clone().is_active(); +pub fn basic_remove(tree_view: >k::TreeView, column_file_name: i32, column_path: i32, column_selection: i32, check_button_settings_use_trash: &CheckButton, text_view_errors: &TextView) { + let use_trash = check_button_settings_use_trash.is_active(); let model = get_list_store(tree_view); let mut messages: String = "".to_string(); - let mut selection_rows = Vec::new(); + let mut selected_rows = Vec::new(); if let Some(iter) = model.iter_first() { loop { if model.value(&iter, column_selection).get::().unwrap() { - selection_rows.push(model.path(&iter).unwrap()); + selected_rows.push(model.path(&iter).unwrap()); } if !model.iter_next(&iter) { @@ -412,8 +314,12 @@ pub fn basic_remove(tree_view: >k::TreeView, column_file_name: i32, column_pat } } + if selected_rows.is_empty() { + return; // No selected rows + } + // Must be deleted from end to start, because when deleting entries, TreePath(and also TreeIter) will points to invalid data - for tree_path in selection_rows.iter().rev() { + for tree_path in selected_rows.iter().rev() { let iter = model.iter(tree_path).unwrap(); let name = model.value(&iter, column_file_name).get::().unwrap(); @@ -440,9 +346,8 @@ pub fn basic_remove(tree_view: >k::TreeView, column_file_name: i32, column_pat } // Remove all occurrences - remove every element which have same path and name as even non selected ones -pub fn tree_remove(tree_view: >k::TreeView, column_file_name: i32, column_path: i32, column_color: i32, column_selection: i32, gui_data: &GuiData) { - let text_view_errors = gui_data.text_view_errors.clone(); - let use_trash = gui_data.settings.check_button_settings_use_trash.clone().is_active(); +pub fn tree_remove(tree_view: >k::TreeView, column_file_name: i32, column_path: i32, column_color: i32, column_selection: i32, check_button_settings_use_trash: &CheckButton, text_view_errors: &TextView) { + let use_trash = check_button_settings_use_trash.is_active(); let model = get_list_store(tree_view); @@ -451,16 +356,15 @@ pub fn tree_remove(tree_view: >k::TreeView, column_file_name: i32, column_path let mut vec_path_to_delete: Vec<(String, String)> = Vec::new(); let mut map_with_path_to_delete: BTreeMap> = Default::default(); // BTreeMap> - let mut selection_rows = Vec::new(); + let mut selected_rows = Vec::new(); if let Some(iter) = model.iter_first() { loop { if model.value(&iter, column_selection).get::().unwrap() { - // TODO, this maybe isn't required if we will be sure that any header cannot be selected if model.value(&iter, column_color).get::().unwrap() == MAIN_ROW_COLOR { - selection_rows.push(model.path(&iter).unwrap()); + selected_rows.push(model.path(&iter).unwrap()); } else { - panic!("Header row shouldn't have selected, selection button"); + panic!("Header row shouldn't be selected, please report bug."); } } @@ -470,8 +374,12 @@ pub fn tree_remove(tree_view: >k::TreeView, column_file_name: i32, column_path } } + if selected_rows.is_empty() { + return; // No selected rows + } + // Save to variable paths of files, and remove it when not removing all occurrences. - for tree_path in selection_rows.iter().rev() { + for tree_path in selected_rows.iter().rev() { let iter = model.iter(tree_path).unwrap(); let file_name = model.value(&iter, column_file_name).get::().unwrap(); @@ -500,74 +408,7 @@ pub fn tree_remove(tree_view: >k::TreeView, column_file_name: i32, column_path } } - // Remove only child from header - if let Some(first_iter) = model.iter_first() { - let mut vec_tree_path_to_delete: Vec = Vec::new(); - let mut current_iter = first_iter; - if model.value(¤t_iter, column_color).get::().unwrap() != HEADER_ROW_COLOR { - panic!("First deleted element, should be a header"); // First element should be header - }; - - let mut next_iter; - let mut next_next_iter; - 'main: loop { - if model.value(¤t_iter, column_color).get::().unwrap() != HEADER_ROW_COLOR { - panic!("First deleted element, should be a header"); // First element should be header - }; - - next_iter = current_iter.clone(); - if !model.iter_next(&next_iter) { - // There is only single header left (H1 -> END) -> (NOTHING) - vec_tree_path_to_delete.push(model.path(¤t_iter).unwrap()); - break 'main; - } - - if model.value(&next_iter, column_color).get::().unwrap() == HEADER_ROW_COLOR { - // There are two headers each others(we remove just first) -> (H1 -> H2) -> (H2) - vec_tree_path_to_delete.push(model.path(¤t_iter).unwrap()); - current_iter = next_iter.clone(); - continue 'main; - } - - next_next_iter = next_iter.clone(); - if !model.iter_next(&next_next_iter) { - // There is only one child of header left, so we remove it with header (H1 -> C1 -> END) -> (NOTHING) - vec_tree_path_to_delete.push(model.path(¤t_iter).unwrap()); - vec_tree_path_to_delete.push(model.path(&next_iter).unwrap()); - break 'main; - } - - if model.value(&next_next_iter, column_color).get::().unwrap() == HEADER_ROW_COLOR { - // One child between two headers, we can remove them (H1 -> C1 -> H2) -> (H2) - vec_tree_path_to_delete.push(model.path(¤t_iter).unwrap()); - vec_tree_path_to_delete.push(model.path(&next_iter).unwrap()); - current_iter = next_next_iter.clone(); - continue 'main; - } - - loop { - // (H1 -> C1 -> C2 -> Cn -> END) -> (NO CHANGE, BECAUSE IS GOOD) - if !model.iter_next(&next_next_iter) { - break 'main; - } - // Move to next header - if model.value(&next_next_iter, column_color).get::().unwrap() == HEADER_ROW_COLOR { - current_iter = next_next_iter.clone(); - continue 'main; - } - } - } - for tree_path in vec_tree_path_to_delete.iter().rev() { - model.remove(&model.iter(tree_path).unwrap()); - } - } - - // Last step, remove orphan header if exists - if let Some(iter) = model.iter_first() { - if !model.iter_next(&iter) { - model.clear(); - } - } + clean_invalid_headers(&model, column_color); text_view_errors.buffer().unwrap().set_text(messages.as_str()); } diff --git a/czkawka_gui/src/connect_button_hardlink.rs b/czkawka_gui/src/connect_button_hardlink.rs index 8d7463d..d6d484c 100644 --- a/czkawka_gui/src/connect_button_hardlink.rs +++ b/czkawka_gui/src/connect_button_hardlink.rs @@ -3,78 +3,74 @@ use crate::help_functions::*; use crate::notebook_enums::*; use czkawka_core::duplicate::make_hard_link; use gtk::prelude::*; -use gtk::{TreeIter, TreePath}; +use gtk::{TextView, TreeIter, TreePath}; use std::fs; use std::path::PathBuf; -pub fn connect_button_hardlink(gui_data: &GuiData) { - let gui_data = gui_data.clone(); - +pub fn connect_button_hardlink_symlink(gui_data: &GuiData) { let buttons_hardlink = gui_data.bottom_buttons.buttons_hardlink.clone(); - let notebook_main = gui_data.main_notebook.notebook_main.clone(); - let tree_view_duplicate_finder = gui_data.main_notebook.tree_view_duplicate_finder.clone(); - let tree_view_similar_images_finder = gui_data.main_notebook.tree_view_similar_images_finder.clone(); - let tree_view_similar_videos_finder = gui_data.main_notebook.tree_view_similar_videos_finder.clone(); - let tree_view_same_music_finder = gui_data.main_notebook.tree_view_same_music_finder.clone(); + let notebook_main = gui_data.main_notebook.notebook_main.clone(); + let main_tree_views = gui_data.main_notebook.get_main_tree_views(); let image_preview_similar_images = gui_data.main_notebook.image_preview_similar_images.clone(); + let image_preview_duplicates = gui_data.main_notebook.image_preview_duplicates.clone(); - buttons_hardlink.connect_clicked(move |_| match to_notebook_main_enum(notebook_main.current_page().unwrap()) { - NotebookMainEnum::Duplicate => { - hardlink_symlink( - tree_view_duplicate_finder.clone(), - ColumnsDuplicates::Name as i32, - ColumnsDuplicates::Path as i32, - ColumnsDuplicates::Color as i32, - ColumnsDuplicates::ActiveSelectButton as i32, - true, - &gui_data, - ); + let text_view_errors = gui_data.text_view_errors.clone(); + + buttons_hardlink.connect_clicked(move |_| { + let nb_number = notebook_main.current_page().unwrap(); + let tree_view = &main_tree_views[nb_number as usize]; + let nb_object = &NOTEBOOKS_INFOS[nb_number as usize]; + + let column_color = nb_object.column_color.expect("Hardinkning can be only used for tree views with grouped results"); + hardlink_symlink(tree_view, nb_object.column_name, nb_object.column_path, column_color, nb_object.column_selection, true, &text_view_errors); + + match &nb_object.notebook_type { + NotebookMainEnum::SimilarImages => { + image_preview_similar_images.hide(); + } + NotebookMainEnum::Duplicate => { + image_preview_duplicates.hide(); + } + _ => {} } - NotebookMainEnum::SameMusic => { - hardlink_symlink( - tree_view_same_music_finder.clone(), - ColumnsSameMusic::Name as i32, - ColumnsSameMusic::Path as i32, - ColumnsSameMusic::Color as i32, - ColumnsSameMusic::ActiveSelectButton as i32, - true, - &gui_data, - ); + }); + + let buttons_symlink = gui_data.bottom_buttons.buttons_symlink.clone(); + + let notebook_main = gui_data.main_notebook.notebook_main.clone(); + let main_tree_views = gui_data.main_notebook.get_main_tree_views(); + + let image_preview_similar_images = gui_data.main_notebook.image_preview_similar_images.clone(); + let image_preview_duplicates = gui_data.main_notebook.image_preview_duplicates.clone(); + + let text_view_errors = gui_data.text_view_errors.clone(); + + buttons_symlink.connect_clicked(move |_| { + let nb_number = notebook_main.current_page().unwrap(); + let tree_view = &main_tree_views[nb_number as usize]; + let nb_object = &NOTEBOOKS_INFOS[nb_number as usize]; + + let column_color = nb_object.column_color.expect("Symlinking can be only used for tree views with grouped results"); + hardlink_symlink(tree_view, nb_object.column_name, nb_object.column_path, column_color, nb_object.column_selection, false, &text_view_errors); + + match &nb_object.notebook_type { + NotebookMainEnum::SimilarImages => { + image_preview_similar_images.hide(); + } + NotebookMainEnum::Duplicate => { + image_preview_duplicates.hide(); + } + _ => {} } - NotebookMainEnum::SimilarImages => { - hardlink_symlink( - tree_view_similar_images_finder.clone(), - ColumnsSimilarImages::Name as i32, - ColumnsSimilarImages::Path as i32, - ColumnsSimilarImages::Color as i32, - ColumnsSimilarImages::ActiveSelectButton as i32, - true, - &gui_data, - ); - image_preview_similar_images.hide(); - } - NotebookMainEnum::SimilarVideos => { - hardlink_symlink( - tree_view_similar_videos_finder.clone(), - ColumnsSimilarVideos::Name as i32, - ColumnsSimilarVideos::Path as i32, - ColumnsSimilarVideos::Color as i32, - ColumnsSimilarVideos::ActiveSelectButton as i32, - true, - &gui_data, - ); - } - e => panic!("Not existent {:?}", e), }); } -pub fn hardlink_symlink(tree_view: gtk::TreeView, column_file_name: i32, column_path: i32, column_color: i32, column_selection: i32, hardlinking: bool, gui_data: &GuiData) { - let text_view_errors = gui_data.text_view_errors.clone(); - reset_text_view(&text_view_errors); +pub fn hardlink_symlink(tree_view: >k::TreeView, column_file_name: i32, column_path: i32, column_color: i32, column_selection: i32, hardlinking: bool, text_view_errors: &TextView) { + reset_text_view(text_view_errors); - let model = get_list_store(&tree_view); + let model = get_list_store(tree_view); #[derive(Debug)] struct SymHardlinkData { @@ -92,8 +88,12 @@ pub fn hardlink_symlink(tree_view: gtk::TreeView, column_file_name: i32, column_ let mut selected_rows = Vec::new(); if let Some(iter) = model.iter_first() { loop { - if model.value(&iter, column_color).get::().unwrap() == MAIN_ROW_COLOR && model.value(&iter, column_selection).get::().unwrap() { - selected_rows.push(model.path(&iter).unwrap()); + if model.value(&iter, column_selection).get::().unwrap() { + if model.value(&iter, column_color).get::().unwrap() == MAIN_ROW_COLOR { + selected_rows.push(model.path(&iter).unwrap()); + } else { + panic!("Header row shouldn't be selected, please report bug."); + } } if !model.iter_next(&iter) { break; @@ -101,6 +101,10 @@ pub fn hardlink_symlink(tree_view: gtk::TreeView, column_file_name: i32, column_ } } + if selected_rows.is_empty() { + return; // No selected rows + } + let mut current_symhardlink_data: Option = None; let mut current_selected_index = 0; loop { @@ -165,12 +169,11 @@ pub fn hardlink_symlink(tree_view: gtk::TreeView, column_file_name: i32, column_ match make_hard_link(&PathBuf::from(&symhardlink_data.original_data), &PathBuf::from(&file_to_hardlink)) { Ok(_) => (), Err(e) => { - add_text_to_text_view(&text_view_errors, format!("Failed to hardlink {}, reason {}", file_to_hardlink, e).as_str()); + add_text_to_text_view(text_view_errors, format!("Failed to hardlink {}, reason {}", file_to_hardlink, e).as_str()); continue; } } } - println!(); } } else { for symhardlink_data in vec_symhardlink_data { @@ -178,7 +181,7 @@ pub fn hardlink_symlink(tree_view: gtk::TreeView, column_file_name: i32, column_ match fs::remove_file(&file_to_symlink) { Ok(_) => (), Err(e) => { - add_text_to_text_view(&text_view_errors, format!("Failed to remove file {} when creating symlink, reason {}", file_to_symlink, e).as_str()); + add_text_to_text_view(text_view_errors, format!("Failed to remove file {} when creating symlink, reason {}", file_to_symlink, e).as_str()); continue; } }; @@ -188,7 +191,7 @@ pub fn hardlink_symlink(tree_view: gtk::TreeView, column_file_name: i32, column_ match std::os::unix::fs::symlink(&symhardlink_data.original_data, &file_to_symlink) { Ok(_) => (), Err(e) => { - add_text_to_text_view(&text_view_errors, format!("Failed to remove file {} when creating symlink, reason {}", file_to_symlink, e).as_str()); + add_text_to_text_view(text_view_errors, format!("Failed to remove file {} when creating symlink, reason {}", file_to_symlink, e).as_str()); continue; } }; @@ -204,72 +207,11 @@ pub fn hardlink_symlink(tree_view: gtk::TreeView, column_file_name: i32, column_ }; } } - println!(); } } for tree_path in vec_tree_path_to_remove.iter().rev() { model.remove(&model.iter(tree_path).unwrap()); } - // Remove only child from header - if let Some(first_iter) = model.iter_first() { - let mut vec_tree_path_to_delete: Vec = Vec::new(); - let mut current_iter = first_iter; - if model.value(¤t_iter, column_color).get::().unwrap() != HEADER_ROW_COLOR { - panic!(); // First element should be header - }; - - let mut next_iter; - let mut next_next_iter; - 'main: loop { - if model.value(¤t_iter, column_color).get::().unwrap() != HEADER_ROW_COLOR { - panic!(); // First element should be header - }; - - next_iter = current_iter.clone(); - if !model.iter_next(&next_iter) { - // There is only single header left (H1 -> END) -> (NOTHING) - vec_tree_path_to_delete.push(model.path(¤t_iter).unwrap()); - break 'main; - } - - if model.value(&next_iter, column_color).get::().unwrap() == HEADER_ROW_COLOR { - // There are two headers each others(we remove just first) -> (H1 -> H2) -> (H2) - vec_tree_path_to_delete.push(model.path(¤t_iter).unwrap()); - current_iter = next_iter.clone(); - continue 'main; - } - - next_next_iter = next_iter.clone(); - if !model.iter_next(&next_next_iter) { - // There is only one child of header left, so we remove it with header (H1 -> C1 -> END) -> (NOTHING) - vec_tree_path_to_delete.push(model.path(¤t_iter).unwrap()); - vec_tree_path_to_delete.push(model.path(&next_iter).unwrap()); - break 'main; - } - - if model.value(&next_next_iter, column_color).get::().unwrap() == HEADER_ROW_COLOR { - // One child between two headers, we can remove them (H1 -> C1 -> H2) -> (H2) - vec_tree_path_to_delete.push(model.path(¤t_iter).unwrap()); - vec_tree_path_to_delete.push(model.path(&next_iter).unwrap()); - current_iter = next_next_iter.clone(); - continue 'main; - } - - loop { - // (H1 -> C1 -> C2 -> Cn -> END) -> (NO CHANGE, BECAUSE IS GOOD) - if !model.iter_next(&next_next_iter) { - break 'main; - } - // Move to next header - if model.value(&next_next_iter, column_color).get::().unwrap() == HEADER_ROW_COLOR { - current_iter = next_next_iter.clone(); - continue 'main; - } - } - } - for tree_path in vec_tree_path_to_delete.iter().rev() { - model.remove(&model.iter(tree_path).unwrap()); - } - } + clean_invalid_headers(&model, column_color); } diff --git a/czkawka_gui/src/connect_button_move.rs b/czkawka_gui/src/connect_button_move.rs index cd60b59..2efbbcf 100644 --- a/czkawka_gui/src/connect_button_move.rs +++ b/czkawka_gui/src/connect_button_move.rs @@ -2,141 +2,58 @@ use crate::gui_data::GuiData; use crate::help_functions::*; use crate::notebook_enums::*; use gtk::prelude::*; +use gtk::TreePath; use std::path::{Path, PathBuf}; pub fn connect_button_move(gui_data: &GuiData) { - let gui_data = gui_data.clone(); - let buttons_move = gui_data.bottom_buttons.buttons_move.clone(); let notebook_main = gui_data.main_notebook.notebook_main.clone(); - let tree_view_duplicate_finder = gui_data.main_notebook.tree_view_duplicate_finder.clone(); - let tree_view_empty_folder_finder = gui_data.main_notebook.tree_view_empty_folder_finder.clone(); - let tree_view_big_files_finder = gui_data.main_notebook.tree_view_big_files_finder.clone(); - let tree_view_empty_files_finder = gui_data.main_notebook.tree_view_empty_files_finder.clone(); - let tree_view_temporary_files_finder = gui_data.main_notebook.tree_view_temporary_files_finder.clone(); - let tree_view_similar_images_finder = gui_data.main_notebook.tree_view_similar_images_finder.clone(); - let tree_view_same_music_finder = gui_data.main_notebook.tree_view_same_music_finder.clone(); - let tree_view_invalid_symlinks = gui_data.main_notebook.tree_view_invalid_symlinks.clone(); - let tree_view_broken_files = gui_data.main_notebook.tree_view_broken_files.clone(); + let main_tree_views = gui_data.main_notebook.get_main_tree_views(); let image_preview_similar_images = gui_data.main_notebook.image_preview_similar_images.clone(); + let image_preview_duplicates = gui_data.main_notebook.image_preview_duplicates.clone(); - buttons_move.connect_clicked(move |_| match to_notebook_main_enum(notebook_main.current_page().unwrap()) { - NotebookMainEnum::Duplicate => { - move_things( - tree_view_duplicate_finder.clone(), - ColumnsDuplicates::Name as i32, - ColumnsDuplicates::Path as i32, - Some(ColumnsDuplicates::Color as i32), - ColumnsDuplicates::ActiveSelectButton as i32, - &gui_data, - ); - } - NotebookMainEnum::SameMusic => { - move_things( - tree_view_same_music_finder.clone(), - ColumnsSameMusic::Name as i32, - ColumnsSameMusic::Path as i32, - Some(ColumnsSameMusic::Color as i32), - ColumnsSameMusic::ActiveSelectButton as i32, - &gui_data, - ); - } - NotebookMainEnum::SimilarImages => { - move_things( - tree_view_similar_images_finder.clone(), - ColumnsSimilarImages::Name as i32, - ColumnsSimilarImages::Path as i32, - Some(ColumnsSimilarImages::Color as i32), - ColumnsSimilarImages::ActiveSelectButton as i32, - &gui_data, - ); - image_preview_similar_images.hide(); - } - NotebookMainEnum::SimilarVideos => { - move_things( - tree_view_similar_images_finder.clone(), - ColumnsSimilarVideos::Name as i32, - ColumnsSimilarVideos::Path as i32, - Some(ColumnsSimilarVideos::Color as i32), - ColumnsSimilarVideos::ActiveSelectButton as i32, - &gui_data, - ); - } - NotebookMainEnum::BigFiles => { - move_things( - tree_view_big_files_finder.clone(), - ColumnsBigFiles::Name as i32, - ColumnsBigFiles::Path as i32, - None, - ColumnsBigFiles::ActiveSelectButton as i32, - &gui_data, - ); - } - NotebookMainEnum::BrokenFiles => { - move_things( - tree_view_broken_files.clone(), - ColumnsBrokenFiles::Name as i32, - ColumnsBrokenFiles::Path as i32, - None, - ColumnsBrokenFiles::ActiveSelectButton as i32, - &gui_data, - ); - } - NotebookMainEnum::EmptyDirectories => { - move_things( - tree_view_empty_folder_finder.clone(), - ColumnsEmptyFolders::Name as i32, - ColumnsEmptyFolders::Path as i32, - None, - ColumnsEmptyFolders::ActiveSelectButton as i32, - &gui_data, - ); - } - NotebookMainEnum::EmptyFiles => { - move_things( - tree_view_empty_files_finder.clone(), - ColumnsEmptyFiles::Name as i32, - ColumnsEmptyFiles::Path as i32, - None, - ColumnsEmptyFiles::ActiveSelectButton as i32, - &gui_data, - ); - } - NotebookMainEnum::Symlinks => { - move_things( - tree_view_invalid_symlinks.clone(), - ColumnsInvalidSymlinks::Name as i32, - ColumnsInvalidSymlinks::Path as i32, - None, - ColumnsInvalidSymlinks::ActiveSelectButton as i32, - &gui_data, - ); - } - NotebookMainEnum::Temporary => { - move_things( - tree_view_temporary_files_finder.clone(), - ColumnsTemporaryFiles::Name as i32, - ColumnsTemporaryFiles::Path as i32, - None, - ColumnsTemporaryFiles::ActiveSelectButton as i32, - &gui_data, - ); + let entry_info = gui_data.entry_info.clone(); + let text_view_errors = gui_data.text_view_errors.clone(); + + let window_main = gui_data.window_main.clone(); + + buttons_move.connect_clicked(move |_| { + let nb_number = notebook_main.current_page().unwrap(); + let tree_view = &main_tree_views[nb_number as usize]; + let nb_object = &NOTEBOOKS_INFOS[nb_number as usize]; + + move_things( + tree_view, + nb_object.column_name, + nb_object.column_path, + nb_object.column_color, + nb_object.column_selection, + &entry_info, + &text_view_errors, + &window_main, + ); + + match &nb_object.notebook_type { + NotebookMainEnum::SimilarImages => { + image_preview_similar_images.hide(); + } + NotebookMainEnum::Duplicate => { + image_preview_duplicates.hide(); + } + _ => {} } }); } -// TODO create and show folder chooser where user can select path -fn move_things(tree_view: gtk::TreeView, column_file_name: i32, column_path: i32, column_color: Option, column_selection: i32, gui_data: &GuiData) { - let text_view_errors = gui_data.text_view_errors.clone(); - let window_main = gui_data.window_main.clone(); - - reset_text_view(&text_view_errors); +// TODO add progress bar +fn move_things(tree_view: >k::TreeView, column_file_name: i32, column_path: i32, column_color: Option, column_selection: i32, entry_info: >k::Entry, text_view_errors: >k::TextView, window_main: >k::Window) { + reset_text_view(text_view_errors); let chooser = gtk::FileChooserDialog::with_buttons( Some("Choose folder to which you want to move duplicated files"), - Some(&window_main), + Some(window_main), gtk::FileChooserAction::SelectFolder, &[("Ok", gtk::ResponseType::Ok), ("Close", gtk::ResponseType::Cancel)], ); @@ -146,36 +63,30 @@ fn move_things(tree_view: gtk::TreeView, column_file_name: i32, column_path: i32 if response_type == gtk::ResponseType::Ok { let folders = chooser.filenames(); if folders.len() != 1 { - add_text_to_text_view(&text_view_errors, format!("Only 1 path must be selected to be able to copy there duplicated files, found {:?}", folders).as_str()); + add_text_to_text_view(text_view_errors, format!("Only 1 path must be selected to be able to copy there duplicated files, found {:?}", folders).as_str()); } else { let folder = folders[0].clone(); if let Some(column_color) = column_color { - move_with_tree(tree_view, column_file_name, column_path, column_color, column_selection, gui_data, folder); + move_with_tree(tree_view, column_file_name, column_path, column_color, column_selection, folder, entry_info, text_view_errors); } else { - move_with_list(tree_view, column_file_name, column_path, column_selection, gui_data, folder); + move_with_list(tree_view, column_file_name, column_path, column_selection, folder, entry_info, text_view_errors); } } } chooser.close(); } -fn move_with_tree(tree_view: gtk::TreeView, column_file_name: i32, column_path: i32, column_color: i32, column_selection: i32, gui_data: &GuiData, destination_folder: PathBuf) { - let text_view_errors = gui_data.text_view_errors.clone(); - let entry_info = gui_data.entry_info.clone(); +fn move_with_tree(tree_view: >k::TreeView, column_file_name: i32, column_path: i32, column_color: i32, column_selection: i32, destination_folder: PathBuf, entry_info: >k::Entry, text_view_errors: >k::TextView) { + let model = get_list_store(tree_view); - let model = get_list_store(&tree_view); - - let mut messages: String = "".to_string(); - - let mut selection_rows = Vec::new(); + let mut selected_rows = Vec::new(); if let Some(iter) = model.iter_first() { loop { if model.value(&iter, column_selection).get::().unwrap() { - // TODO, this maybe isn't required if we will be sure that any header cannot be selected if model.value(&iter, column_color).get::().unwrap() == MAIN_ROW_COLOR { - selection_rows.push(model.path(&iter).unwrap()); + selected_rows.push(model.path(&iter).unwrap()); } else { - panic!("Header row shouldn't have selected, selection button"); + panic!("Header row shouldn't be selected, please report bug."); } } @@ -185,119 +96,24 @@ fn move_with_tree(tree_view: gtk::TreeView, column_file_name: i32, column_path: } } - let mut moved_files: u32 = 0; - - // Save to variable paths of files, and remove it when not removing all occurrences. - 'next_result: for tree_path in selection_rows.iter().rev() { - let iter = model.iter(tree_path).unwrap(); - - let file_name = model.value(&iter, column_file_name).get::().unwrap(); - let path = model.value(&iter, column_path).get::().unwrap(); - - let thing = format!("{}/{}", path, file_name); - let destination_file = destination_folder.join(file_name); - if Path::new(&thing).is_dir() { - if let Err(e) = fs_extra::dir::move_dir(&thing, &destination_file, &fs_extra::dir::CopyOptions::new()) { - messages += format!("Failed to move folder, reason {}\n", e).as_str(); - continue 'next_result; - } - } else { - if let Err(e) = fs_extra::file::move_file(&thing, &destination_file, &fs_extra::file::CopyOptions::new()) { - messages += format!("Failed to move file, reason {}\n", e).as_str(); - continue 'next_result; - } - } - model.remove(&iter); - moved_files += 1; - } - entry_info.set_text(format!("Properly moved {}/{} files/folders", moved_files, selection_rows.len()).as_str()); - - // TODO move this to different function, this is used in different places - // Remove only child from header - if let Some(first_iter) = model.iter_first() { - let mut vec_tree_path_to_delete: Vec = Vec::new(); - let mut current_iter = first_iter; - if model.value(¤t_iter, column_color).get::().unwrap() != HEADER_ROW_COLOR { - panic!("First deleted element, should be a header"); // First element should be header - }; - - let mut next_iter; - let mut next_next_iter; - 'main: loop { - if model.value(¤t_iter, column_color).get::().unwrap() != HEADER_ROW_COLOR { - panic!("First deleted element, should be a header"); // First element should be header - }; - - next_iter = current_iter.clone(); - if !model.iter_next(&next_iter) { - // There is only single header left (H1 -> END) -> (NOTHING) - vec_tree_path_to_delete.push(model.path(¤t_iter).unwrap()); - break 'main; - } - - if model.value(&next_iter, column_color).get::().unwrap() == HEADER_ROW_COLOR { - // There are two headers each others(we remove just first) -> (H1 -> H2) -> (H2) - vec_tree_path_to_delete.push(model.path(¤t_iter).unwrap()); - current_iter = next_iter.clone(); - continue 'main; - } - - next_next_iter = next_iter.clone(); - if !model.iter_next(&next_next_iter) { - // There is only one child of header left, so we remove it with header (H1 -> C1 -> END) -> (NOTHING) - vec_tree_path_to_delete.push(model.path(¤t_iter).unwrap()); - vec_tree_path_to_delete.push(model.path(&next_iter).unwrap()); - break 'main; - } - - if model.value(&next_next_iter, column_color).get::().unwrap() == HEADER_ROW_COLOR { - // One child between two headers, we can remove them (H1 -> C1 -> H2) -> (H2) - vec_tree_path_to_delete.push(model.path(¤t_iter).unwrap()); - vec_tree_path_to_delete.push(model.path(&next_iter).unwrap()); - current_iter = next_next_iter.clone(); - continue 'main; - } - - loop { - // (H1 -> C1 -> C2 -> Cn -> END) -> (NO CHANGE, BECAUSE IS GOOD) - if !model.iter_next(&next_next_iter) { - break 'main; - } - // Move to next header - if model.value(&next_next_iter, column_color).get::().unwrap() == HEADER_ROW_COLOR { - current_iter = next_next_iter.clone(); - continue 'main; - } - } - } - for tree_path in vec_tree_path_to_delete.iter().rev() { - model.remove(&model.iter(tree_path).unwrap()); - } + if selected_rows.is_empty() { + return; // No selected rows } - // Last step, remove orphan header if exists - if let Some(iter) = model.iter_first() { - if !model.iter_next(&iter) { - model.clear(); - } - } + move_files_common(&selected_rows, &model, column_file_name, column_path, &destination_folder, entry_info, text_view_errors); - text_view_errors.buffer().unwrap().set_text(messages.as_str()); + clean_invalid_headers(&model, column_color); } -fn move_with_list(tree_view: gtk::TreeView, column_file_name: i32, column_path: i32, column_selection: i32, gui_data: &GuiData, destination_folder: PathBuf) { - let text_view_errors = gui_data.text_view_errors.clone(); - let entry_info = gui_data.entry_info.clone(); - let model = get_list_store(&tree_view); +fn move_with_list(tree_view: >k::TreeView, column_file_name: i32, column_path: i32, column_selection: i32, destination_folder: PathBuf, entry_info: >k::Entry, text_view_errors: >k::TextView) { + let model = get_list_store(tree_view); - let mut messages: String = "".to_string(); - - let mut selection_rows = Vec::new(); + let mut selected_rows = Vec::new(); if let Some(iter) = model.iter_first() { loop { if model.value(&iter, column_selection).get::().unwrap() { - selection_rows.push(model.path(&iter).unwrap()); + selected_rows.push(model.path(&iter).unwrap()); } if !model.iter_next(&iter) { @@ -306,10 +122,20 @@ fn move_with_list(tree_view: gtk::TreeView, column_file_name: i32, column_path: } } + if selected_rows.is_empty() { + return; // No selected rows + } + + move_files_common(&selected_rows, &model, column_file_name, column_path, &destination_folder, entry_info, text_view_errors) +} + +fn move_files_common(selected_rows: &[TreePath], model: >k::ListStore, column_file_name: i32, column_path: i32, destination_folder: &Path, entry_info: >k::Entry, text_view_errors: >k::TextView) { + let mut messages: String = "".to_string(); + let mut moved_files: u32 = 0; // Save to variable paths of files, and remove it when not removing all occurrences. - 'next_result: for tree_path in selection_rows.iter().rev() { + 'next_result: for tree_path in selected_rows.iter().rev() { let iter = model.iter(tree_path).unwrap(); let file_name = model.value(&iter, column_file_name).get::().unwrap(); @@ -331,7 +157,7 @@ fn move_with_list(tree_view: gtk::TreeView, column_file_name: i32, column_path: model.remove(&iter); moved_files += 1; } - entry_info.set_text(format!("Properly moved {}/{} files/folders", moved_files, selection_rows.len()).as_str()); + entry_info.set_text(format!("Properly moved {}/{} files/folders", moved_files, selected_rows.len()).as_str()); text_view_errors.buffer().unwrap().set_text(messages.as_str()); } diff --git a/czkawka_gui/src/connect_button_save.rs b/czkawka_gui/src/connect_button_save.rs index 3171516..553f259 100644 --- a/czkawka_gui/src/connect_button_save.rs +++ b/czkawka_gui/src/connect_button_save.rs @@ -2,10 +2,14 @@ use crate::gui_data::GuiData; use crate::notebook_enums::*; use czkawka_core::common_traits::SaveResults; use gtk::prelude::*; +use gtk::{Button, Entry}; +use std::cell::RefCell; +use std::collections::HashMap; +use std::rc::Rc; pub fn connect_button_save(gui_data: &GuiData) { - let gui_data = gui_data.clone(); let buttons_save = gui_data.bottom_buttons.buttons_save.clone(); + let buttons_save_clone = gui_data.bottom_buttons.buttons_save.clone(); let shared_duplication_state = gui_data.shared_duplication_state.clone(); let shared_empty_folders_state = gui_data.shared_empty_folders_state.clone(); let shared_big_files_state = gui_data.shared_big_files_state.clone(); @@ -16,6 +20,8 @@ pub fn connect_button_save(gui_data: &GuiData) { let shared_same_music_state = gui_data.shared_same_music_state.clone(); let shared_same_invalid_symlinks = gui_data.shared_same_invalid_symlinks.clone(); let shared_broken_files_state = gui_data.shared_broken_files_state.clone(); + let shared_buttons = gui_data.shared_buttons.clone(); + let entry_info = gui_data.entry_info.clone(); let notebook_main = gui_data.main_notebook.notebook_main.clone(); buttons_save.connect_clicked(move |_| { let file_name; @@ -72,14 +78,10 @@ pub fn connect_button_save(gui_data: &GuiData) { shared_broken_files_state.borrow_mut().save_results_to_file(file_name); } } - post_save_things(file_name, &to_notebook_main_enum(notebook_main.current_page().unwrap()), &gui_data); + post_save_things(file_name, &to_notebook_main_enum(notebook_main.current_page().unwrap()), &shared_buttons, &entry_info, &buttons_save_clone); }); } -fn post_save_things(file_name: &str, type_of_tab: &NotebookMainEnum, gui_data: &GuiData) { - let entry_info = gui_data.entry_info.clone(); - let buttons_save = gui_data.bottom_buttons.buttons_save.clone(); - let shared_buttons = gui_data.shared_buttons.clone(); - +fn post_save_things(file_name: &str, type_of_tab: &NotebookMainEnum, shared_buttons: &Rc>>>, entry_info: &Entry, buttons_save: &Button) { entry_info.set_text(format!("Saved results to file {}", file_name).as_str()); // Set state { diff --git a/czkawka_gui/src/connect_button_select.rs b/czkawka_gui/src/connect_button_select.rs index a6f7d7a..d2354b0 100644 --- a/czkawka_gui/src/connect_button_select.rs +++ b/czkawka_gui/src/connect_button_select.rs @@ -1,68 +1,61 @@ use crate::gui_data::GuiData; +use crate::gui_popovers::GuiPopovers; +use crate::help_functions::PopoverTypes; use crate::notebook_enums::*; use gtk::prelude::*; use std::collections::HashMap; -// TODO Replace `all`, `image_size` etc. with this -// pub enum PopoverType { -// All, -// ImageSize, -// Reverse, -// Custom, -// Date, -// } pub fn connect_button_select(gui_data: &GuiData) { - // let mode = ["all", "image_size", "reverse", "custom", "date"]; - let mut hashmap: HashMap> = Default::default(); + let mut hashmap: HashMap> = Default::default(); { - // Remember to update connect_popovers file, because this data are connected to each others - hashmap.insert(NotebookMainEnum::SimilarImages, vec!["all", "image_size", "reverse", "custom", "date"]); - hashmap.insert(NotebookMainEnum::SimilarVideos, vec!["all", "reverse", "custom", "date"]); - hashmap.insert(NotebookMainEnum::Duplicate, vec!["all", "reverse", "custom", "date"]); - hashmap.insert(NotebookMainEnum::SameMusic, vec!["all", "reverse", "custom", "date"]); + hashmap.insert(NotebookMainEnum::SimilarImages, vec![PopoverTypes::All, PopoverTypes::ImageSize, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::Date]); + hashmap.insert(NotebookMainEnum::SimilarVideos, vec![PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::Date]); + hashmap.insert(NotebookMainEnum::Duplicate, vec![PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::Date]); + hashmap.insert(NotebookMainEnum::SameMusic, vec![PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::Date]); - hashmap.insert(NotebookMainEnum::EmptyFiles, vec!["all", "reverse", "custom"]); - hashmap.insert(NotebookMainEnum::EmptyDirectories, vec!["all", "reverse", "custom"]); - hashmap.insert(NotebookMainEnum::BigFiles, vec!["all", "reverse", "custom"]); - hashmap.insert(NotebookMainEnum::Symlinks, vec!["all", "reverse", "custom"]); - hashmap.insert(NotebookMainEnum::Temporary, vec!["all", "reverse", "custom"]); - hashmap.insert(NotebookMainEnum::BrokenFiles, vec!["all", "reverse", "custom"]); + hashmap.insert(NotebookMainEnum::EmptyFiles, vec![PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom]); + hashmap.insert(NotebookMainEnum::EmptyDirectories, vec![PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom]); + hashmap.insert(NotebookMainEnum::BigFiles, vec![PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom]); + hashmap.insert(NotebookMainEnum::Symlinks, vec![PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom]); + hashmap.insert(NotebookMainEnum::Temporary, vec![PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom]); + hashmap.insert(NotebookMainEnum::BrokenFiles, vec![PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom]); } + assert_eq!(hashmap.len(), NUMBER_OF_NOTEBOOK_MAIN_TABS); - let gui_data = gui_data.clone(); + let popovers = gui_data.popovers.clone(); let notebook_main = gui_data.main_notebook.notebook_main.clone(); let buttons_select_clone = gui_data.bottom_buttons.buttons_select.clone(); let popover_select = gui_data.popovers.popover_select.clone(); let buttons_select = gui_data.bottom_buttons.buttons_select.clone(); buttons_select_clone.connect_clicked(move |_| { - show_required_popovers(&gui_data, &to_notebook_main_enum(notebook_main.current_page().unwrap()), &hashmap); + show_required_popovers(&popovers, &to_notebook_main_enum(notebook_main.current_page().unwrap()), &hashmap); popover_select.set_relative_to(Some(&buttons_select)); popover_select.popup(); }); } -fn show_required_popovers(gui_data: &GuiData, current_mode: &NotebookMainEnum, hashmap: &HashMap>) { - let buttons_popover_select_all = gui_data.popovers.buttons_popover_select_all.clone(); - let buttons_popover_unselect_all = gui_data.popovers.buttons_popover_unselect_all.clone(); - let buttons_popover_reverse = gui_data.popovers.buttons_popover_reverse.clone(); - let buttons_popover_select_all_except_oldest = gui_data.popovers.buttons_popover_select_all_except_oldest.clone(); - let buttons_popover_select_all_except_newest = gui_data.popovers.buttons_popover_select_all_except_newest.clone(); - let buttons_popover_select_one_oldest = gui_data.popovers.buttons_popover_select_one_oldest.clone(); - let buttons_popover_select_one_newest = gui_data.popovers.buttons_popover_select_one_newest.clone(); - let buttons_popover_select_custom = gui_data.popovers.buttons_popover_select_custom.clone(); - let buttons_popover_unselect_custom = gui_data.popovers.buttons_popover_unselect_custom.clone(); - let buttons_popover_select_all_images_except_biggest = gui_data.popovers.buttons_popover_select_all_images_except_biggest.clone(); - let buttons_popover_select_all_images_except_smallest = gui_data.popovers.buttons_popover_select_all_images_except_smallest.clone(); +fn show_required_popovers(popovers: &GuiPopovers, current_mode: &NotebookMainEnum, hashmap: &HashMap>) { + let buttons_popover_select_all = popovers.buttons_popover_select_all.clone(); + let buttons_popover_unselect_all = popovers.buttons_popover_unselect_all.clone(); + let buttons_popover_reverse = popovers.buttons_popover_reverse.clone(); + let buttons_popover_select_all_except_oldest = popovers.buttons_popover_select_all_except_oldest.clone(); + let buttons_popover_select_all_except_newest = popovers.buttons_popover_select_all_except_newest.clone(); + let buttons_popover_select_one_oldest = popovers.buttons_popover_select_one_oldest.clone(); + let buttons_popover_select_one_newest = popovers.buttons_popover_select_one_newest.clone(); + let buttons_popover_select_custom = popovers.buttons_popover_select_custom.clone(); + let buttons_popover_unselect_custom = popovers.buttons_popover_unselect_custom.clone(); + let buttons_popover_select_all_images_except_biggest = popovers.buttons_popover_select_all_images_except_biggest.clone(); + let buttons_popover_select_all_images_except_smallest = popovers.buttons_popover_select_all_images_except_smallest.clone(); - let separator_select_custom = gui_data.popovers.separator_select_custom.clone(); - let separator_select_date = gui_data.popovers.separator_select_date.clone(); - let separator_select_image_size = gui_data.popovers.separator_select_image_size.clone(); - let separator_select_reverse = gui_data.popovers.separator_select_reverse.clone(); + let separator_select_custom = popovers.separator_select_custom.clone(); + let separator_select_date = popovers.separator_select_date.clone(); + let separator_select_image_size = popovers.separator_select_image_size.clone(); + let separator_select_reverse = popovers.separator_select_reverse.clone(); let vec = hashmap.get(current_mode).unwrap(); - if vec.contains(&"all") { + if vec.contains(&PopoverTypes::All) { buttons_popover_select_all.show(); buttons_popover_unselect_all.show(); } else { @@ -70,7 +63,7 @@ fn show_required_popovers(gui_data: &GuiData, current_mode: &NotebookMainEnum, h buttons_popover_unselect_all.hide(); } - if vec.contains(&"image_size") { + if vec.contains(&PopoverTypes::ImageSize) { buttons_popover_select_all_images_except_biggest.show(); buttons_popover_select_all_images_except_smallest.show(); separator_select_image_size.show(); @@ -80,7 +73,7 @@ fn show_required_popovers(gui_data: &GuiData, current_mode: &NotebookMainEnum, h separator_select_image_size.hide(); } - if vec.contains(&"reverse") { + if vec.contains(&PopoverTypes::Reverse) { buttons_popover_reverse.show(); separator_select_reverse.show(); } else { @@ -88,7 +81,7 @@ fn show_required_popovers(gui_data: &GuiData, current_mode: &NotebookMainEnum, h separator_select_reverse.hide(); } - if vec.contains(&"custom") { + if vec.contains(&PopoverTypes::Custom) { buttons_popover_select_custom.show(); buttons_popover_unselect_custom.show(); separator_select_custom.show(); @@ -98,7 +91,7 @@ fn show_required_popovers(gui_data: &GuiData, current_mode: &NotebookMainEnum, h separator_select_custom.hide(); } - if vec.contains(&"date") { + if vec.contains(&PopoverTypes::Date) { buttons_popover_select_all_except_oldest.show(); buttons_popover_select_all_except_newest.show(); buttons_popover_select_one_oldest.show(); diff --git a/czkawka_gui/src/connect_button_symlink.rs b/czkawka_gui/src/connect_button_symlink.rs deleted file mode 100644 index a05115b..0000000 --- a/czkawka_gui/src/connect_button_symlink.rs +++ /dev/null @@ -1,70 +0,0 @@ -use crate::connect_button_hardlink::hardlink_symlink; -use crate::gui_data::GuiData; -use crate::help_functions::*; -use crate::notebook_enums::*; -use gtk::prelude::*; - -pub fn connect_button_symlink(gui_data: &GuiData) { - let gui_data = gui_data.clone(); - - let buttons_symlink = gui_data.bottom_buttons.buttons_symlink.clone(); - let notebook_main = gui_data.main_notebook.notebook_main.clone(); - - let tree_view_duplicate_finder = gui_data.main_notebook.tree_view_duplicate_finder.clone(); - let tree_view_similar_images_finder = gui_data.main_notebook.tree_view_similar_images_finder.clone(); - let tree_view_similar_videos_finder = gui_data.main_notebook.tree_view_similar_videos_finder.clone(); - let tree_view_same_music_finder = gui_data.main_notebook.tree_view_same_music_finder.clone(); - - let image_preview_similar_images = gui_data.main_notebook.image_preview_similar_images.clone(); - let image_preview_duplicates = gui_data.main_notebook.image_preview_duplicates.clone(); - - buttons_symlink.connect_clicked(move |_| match to_notebook_main_enum(notebook_main.current_page().unwrap()) { - NotebookMainEnum::Duplicate => { - hardlink_symlink( - tree_view_duplicate_finder.clone(), - ColumnsDuplicates::Name as i32, - ColumnsDuplicates::Path as i32, - ColumnsDuplicates::Color as i32, - ColumnsDuplicates::ActiveSelectButton as i32, - false, - &gui_data, - ); - image_preview_duplicates.hide(); - } - NotebookMainEnum::SameMusic => { - hardlink_symlink( - tree_view_same_music_finder.clone(), - ColumnsSameMusic::Name as i32, - ColumnsSameMusic::Path as i32, - ColumnsSameMusic::Color as i32, - ColumnsSameMusic::ActiveSelectButton as i32, - false, - &gui_data, - ); - } - NotebookMainEnum::SimilarImages => { - hardlink_symlink( - tree_view_similar_images_finder.clone(), - ColumnsSimilarImages::Name as i32, - ColumnsSimilarImages::Path as i32, - ColumnsSimilarImages::Color as i32, - ColumnsSimilarImages::ActiveSelectButton as i32, - false, - &gui_data, - ); - image_preview_similar_images.hide(); - } - NotebookMainEnum::SimilarVideos => { - hardlink_symlink( - tree_view_similar_videos_finder.clone(), - ColumnsSimilarVideos::Name as i32, - ColumnsSimilarVideos::Path as i32, - ColumnsSimilarVideos::Color as i32, - ColumnsSimilarVideos::ActiveSelectButton as i32, - false, - &gui_data, - ); - } - e => panic!("Not existent {:?}", e), - }); -} diff --git a/czkawka_gui/src/connect_popovers.rs b/czkawka_gui/src/connect_popovers.rs index 711a340..a955e60 100644 --- a/czkawka_gui/src/connect_popovers.rs +++ b/czkawka_gui/src/connect_popovers.rs @@ -1,27 +1,38 @@ use crate::gui_data::GuiData; use crate::help_functions::*; -use crate::notebook_enums::*; use czkawka_core::common::Common; use gtk::prelude::*; -use gtk::TreeIter; +use gtk::{TreeIter, Window}; // File length variable allows users to choose duplicates which have shorter file name // e.g. 'tar.gz' will be selected instead 'tar.gz (copy)' etc. -fn popover_select_all(popover: >k::Popover, tree_view: >k::TreeView, column_button_selection: u32) { +fn popover_select_all(popover: >k::Popover, tree_view: >k::TreeView, column_button_selection: u32, column_color: Option) { let model = get_list_store(tree_view); if let Some(iter) = model.iter_first() { - loop { - model.set_value(&iter, column_button_selection, &true.to_value()); + if let Some(column_color) = column_color { + loop { + if model.value(&iter, column_color).get::().unwrap() == MAIN_ROW_COLOR { + model.set_value(&iter, column_button_selection, &true.to_value()); + } + if !model.iter_next(&iter) { + break; + } + } + } else { + loop { + model.set_value(&iter, column_button_selection, &true.to_value()); - if !model.iter_next(&iter) { - break; + if !model.iter_next(&iter) { + break; + } } } } popover.popdown(); } + fn popover_unselect_all(popover: >k::Popover, tree_view: >k::TreeView, column_button_selection: u32) { let model = get_list_store(tree_view); @@ -36,367 +47,170 @@ fn popover_unselect_all(popover: >k::Popover, tree_view: >k::TreeView, colum } popover.popdown(); } -fn popover_reverse(popover: >k::Popover, tree_view: >k::TreeView, column_button_selection: u32) { +fn popover_reverse(popover: >k::Popover, tree_view: >k::TreeView, column_button_selection: u32, column_color: Option) { let model = get_list_store(tree_view); if let Some(iter) = model.iter_first() { - loop { - let current_value: bool = model.value(&iter, column_button_selection as i32).get::().unwrap(); - model.set_value(&iter, column_button_selection, &(!current_value).to_value()); - - if !model.iter_next(&iter) { - break; - } - } - } - popover.popdown(); -} - -fn popover_all_except_oldest(popover: >k::Popover, tree_view: >k::TreeView, column_color: i32, column_modification_as_secs: i32, column_file_name: i32, column_button_selection: u32) { - let model = get_list_store(tree_view); - - if let Some(iter) = model.iter_first() { - let mut end: bool = false; - loop { - let mut tree_iter_array: Vec = Vec::new(); - let mut oldest_index: Option = None; - let mut current_index: usize = 0; - let mut oldest_modification_time: u64 = u64::MAX; - - let mut file_length: usize = 0; - + if let Some(column_color) = column_color { loop { - let color = model.value(&iter, column_color).get::().unwrap(); - if color == HEADER_ROW_COLOR { - if !model.iter_next(&iter) { - end = true; - } - break; + if model.value(&iter, column_color).get::().unwrap() == MAIN_ROW_COLOR { + let current_value: bool = model.value(&iter, column_button_selection as i32).get::().unwrap(); + model.set_value(&iter, column_button_selection, &(!current_value).to_value()); } - tree_iter_array.push(iter.clone()); - let modification = model.value(&iter, column_modification_as_secs).get::().unwrap(); - let current_file_length = model.value(&iter, column_file_name).get::().unwrap().len(); - if modification < oldest_modification_time || (modification == oldest_modification_time && current_file_length < file_length) { - file_length = current_file_length; - oldest_modification_time = modification; - oldest_index = Some(current_index); - } - - current_index += 1; - if !model.iter_next(&iter) { - end = true; break; } } - if oldest_index == None { - continue; - } - for (index, tree_iter) in tree_iter_array.iter().enumerate() { - if index != oldest_index.unwrap() { - model.set_value(tree_iter, column_button_selection, &true.to_value()); - } else { - model.set_value(tree_iter, column_button_selection, &false.to_value()); - } - } - - if end { - break; - } - } - } - - popover.popdown(); -} -fn popover_all_except_newest(popover: >k::Popover, tree_view: >k::TreeView, column_color: i32, column_modification_as_secs: i32, column_file_name: i32, column_button_selection: u32) { - let model = get_list_store(tree_view); - - if let Some(iter) = model.iter_first() { - let mut end: bool = false; - loop { - let mut tree_iter_array: Vec = Vec::new(); - let mut newest_index: Option = None; - let mut current_index: usize = 0; - let mut newest_modification_time: u64 = 0; - - let mut file_length: usize = 0; - - loop { - let color = model.value(&iter, column_color).get::().unwrap(); - if color == HEADER_ROW_COLOR { - if !model.iter_next(&iter) { - end = true; - } - break; - } - tree_iter_array.push(iter.clone()); - let modification = model.value(&iter, column_modification_as_secs).get::().unwrap(); - let current_file_length = model.value(&iter, column_file_name).get::().unwrap().len(); - if modification > newest_modification_time || (modification == newest_modification_time && current_file_length < file_length) { - file_length = current_file_length; - newest_modification_time = modification; - newest_index = Some(current_index); - } - - current_index += 1; - - if !model.iter_next(&iter) { - end = true; - break; - } - } - if newest_index == None { - continue; - } - for (index, tree_iter) in tree_iter_array.iter().enumerate() { - if index != newest_index.unwrap() { - model.set_value(tree_iter, column_button_selection, &true.to_value()); - } else { - model.set_value(tree_iter, column_button_selection, &false.to_value()); - } - } - - if end { - break; - } - } - } - - popover.popdown(); -} -fn popover_one_oldest(popover: >k::Popover, tree_view: >k::TreeView, column_color: i32, column_modification_as_secs: i32, column_file_name: i32, column_button_selection: u32) { - let model = get_list_store(tree_view); - - if let Some(iter) = model.iter_first() { - let mut end: bool = false; - loop { - let mut tree_iter_array: Vec = Vec::new(); - let mut oldest_index: Option = None; - let mut current_index: usize = 0; - let mut oldest_modification_time: u64 = u64::MAX; - - let mut file_length: usize = 0; - - loop { - let color = model.value(&iter, column_color).get::().unwrap(); - if color == HEADER_ROW_COLOR { - if !model.iter_next(&iter) { - end = true; - } - break; - } - tree_iter_array.push(iter.clone()); - let modification = model.value(&iter, column_modification_as_secs).get::().unwrap(); - let current_file_length = model.value(&iter, column_file_name).get::().unwrap().len(); - if modification < oldest_modification_time || (modification == oldest_modification_time && current_file_length > file_length) { - file_length = current_file_length; - oldest_modification_time = modification; - oldest_index = Some(current_index); - } - - current_index += 1; - - if !model.iter_next(&iter) { - end = true; - break; - } - } - if oldest_index == None { - continue; - } - for (index, tree_iter) in tree_iter_array.iter().enumerate() { - if index == oldest_index.unwrap() { - model.set_value(tree_iter, column_button_selection, &true.to_value()); - } else { - model.set_value(tree_iter, column_button_selection, &false.to_value()); - } - } - - if end { - break; - } - } - } - - popover.popdown(); -} -fn popover_one_newest(popover: >k::Popover, tree_view: >k::TreeView, column_color: i32, column_modification_as_secs: i32, column_file_name: i32, column_button_selection: u32) { - let model = get_list_store(tree_view); - - if let Some(iter) = model.iter_first() { - let mut end: bool = false; - loop { - let mut tree_iter_array: Vec = Vec::new(); - let mut newest_index: Option = None; - let mut current_index: usize = 0; - let mut newest_modification_time: u64 = 0; - - let mut file_length: usize = 0; - loop { - let color = model.value(&iter, column_color).get::().unwrap(); - if color == HEADER_ROW_COLOR { - if !model.iter_next(&iter) { - end = true; - } - break; - } - tree_iter_array.push(iter.clone()); - let modification = model.value(&iter, column_modification_as_secs).get::().unwrap(); - let current_file_length = model.value(&iter, column_file_name).get::().unwrap().len(); - if modification > newest_modification_time || (modification == newest_modification_time && current_file_length > file_length) { - file_length = current_file_length; - newest_modification_time = modification; - newest_index = Some(current_index); - } - - current_index += 1; - - if !model.iter_next(&iter) { - end = true; - break; - } - } - if newest_index == None { - continue; - } - for (index, tree_iter) in tree_iter_array.iter().enumerate() { - if index == newest_index.unwrap() { - model.set_value(tree_iter, column_button_selection, &true.to_value()); - } else { - model.set_value(tree_iter, column_button_selection, &false.to_value()); - } - } - - if end { - break; - } - } - } - - popover.popdown(); -} - -fn popover_select_custom(popover: >k::Popover, gui_data: &GuiData, tree_view: >k::TreeView, column_color: Option, column_file_name: i32, column_path: i32, column_button_selection: u32) { - popover.popdown(); - - let wildcard: String; - enum WildcardType { - Path, - Name, - PathName, - } - let wildcard_type: WildcardType; - - // Accept Dialog - { - let window_main = gui_data.window_main.clone(); - let confirmation_dialog_delete = gtk::Dialog::with_buttons(Some("Select custom"), Some(&window_main), gtk::DialogFlags::MODAL, &[("Ok", gtk::ResponseType::Ok), ("Close", gtk::ResponseType::Cancel)]); - let label: gtk::Label = gtk::Label::new(Some("Usage: */folder-nr*/* or name-version-*.txt")); - - let radio_path = gtk::RadioButton::with_label("Path"); - let radio_name = gtk::RadioButton::with_label_from_widget(&radio_path, "Name"); - let radio_name_path = gtk::RadioButton::with_label_from_widget(&radio_path, "Path + Name"); - - let entry_path = gtk::Entry::new(); - let entry_name = gtk::Entry::new(); - let entry_name_path = gtk::Entry::new(); - - label.set_margin_bottom(5); - label.set_margin_end(5); - label.set_margin_start(5); - - // TODO Label should have const width, and rest should fill entry, but for now is 50%-50% - let grid = gtk::Grid::new(); - grid.set_row_homogeneous(true); - grid.set_column_homogeneous(true); - - grid.attach(&label, 0, 0, 2, 1); - - grid.attach(&radio_path, 0, 1, 1, 1); - grid.attach(&radio_name, 0, 2, 1, 1); - grid.attach(&radio_name_path, 0, 3, 1, 1); - - grid.attach(&entry_path, 1, 1, 1, 1); - grid.attach(&entry_name, 1, 2, 1, 1); - grid.attach(&entry_name_path, 1, 3, 1, 1); - - for widgets in confirmation_dialog_delete.children() { - // By default GtkBox is child of dialog, so we can easily add other things to it - widgets.downcast::().unwrap().add(&grid); - } - - confirmation_dialog_delete.show_all(); - - let response_type = confirmation_dialog_delete.run(); - if response_type == gtk::ResponseType::Ok { - if radio_path.is_active() { - wildcard_type = WildcardType::Path; - wildcard = entry_path.text().to_string(); - } else if radio_name.is_active() { - wildcard_type = WildcardType::Name; - wildcard = entry_name.text().to_string(); - } else if radio_name_path.is_active() { - wildcard_type = WildcardType::PathName; - wildcard = entry_name_path.text().to_string(); - } else { - panic!("Non handled option in select wildcard"); - } } else { - confirmation_dialog_delete.close(); - return; + loop { + let current_value: bool = model.value(&iter, column_button_selection as i32).get::().unwrap(); + model.set_value(&iter, column_button_selection, &(!current_value).to_value()); + + if !model.iter_next(&iter) { + break; + } + } } - confirmation_dialog_delete.close(); } - if !wildcard.is_empty() { - let wildcard = wildcard.trim(); + popover.popdown(); +} - #[cfg(target_family = "windows")] - let wildcard = wildcard.replace("/", "\\"); - #[cfg(target_family = "windows")] - let wildcard = wildcard.as_str(); - - let model = get_list_store(tree_view); - - let iter = model.iter_first().unwrap(); // Never should be available button where there is no available records +fn popover_all_except_oldest_newest(popover: >k::Popover, tree_view: >k::TreeView, column_color: i32, column_modification_as_secs: i32, column_file_name: i32, column_button_selection: u32, except_oldest: bool) { + let model = get_list_store(tree_view); + if let Some(iter) = model.iter_first() { + let mut end: bool = false; loop { - if let Some(column_color) = column_color { + let mut tree_iter_array: Vec = Vec::new(); + let mut used_index: Option = None; + let mut current_index: usize = 0; + let mut modification_time_min_max: u64 = match except_oldest { + true => u64::MAX, + false => 0, + }; + + let mut file_length: usize = 0; + + loop { let color = model.value(&iter, column_color).get::().unwrap(); if color == HEADER_ROW_COLOR { if !model.iter_next(&iter) { - break; + end = true; } - continue; + break; + } + tree_iter_array.push(iter.clone()); + let modification = model.value(&iter, column_modification_as_secs).get::().unwrap(); + let current_file_length = model.value(&iter, column_file_name).get::().unwrap().len(); + if except_oldest { + if modification < modification_time_min_max || (modification == modification_time_min_max && current_file_length < file_length) { + file_length = current_file_length; + modification_time_min_max = modification; + used_index = Some(current_index); + } + } else { + if modification > modification_time_min_max || (modification == modification_time_min_max && current_file_length < file_length) { + file_length = current_file_length; + modification_time_min_max = modification; + used_index = Some(current_index); + } + } + current_index += 1; + + if !model.iter_next(&iter) { + end = true; + break; + } + } + if used_index == None { + continue; + } + for (index, tree_iter) in tree_iter_array.iter().enumerate() { + if index != used_index.unwrap() { + model.set_value(tree_iter, column_button_selection, &true.to_value()); + } else { + model.set_value(tree_iter, column_button_selection, &false.to_value()); } } - let path = model.value(&iter, column_path).get::().unwrap(); - let name = model.value(&iter, column_file_name).get::().unwrap(); - match wildcard_type { - WildcardType::Path => { - if Common::regex_check(wildcard, path) { - model.set_value(&iter, column_button_selection, &true.to_value()); - } - } - WildcardType::Name => { - if Common::regex_check(wildcard, name) { - model.set_value(&iter, column_button_selection, &true.to_value()); - } - } - WildcardType::PathName => { - if Common::regex_check(wildcard, format!("{}/{}", path, name)) { - model.set_value(&iter, column_button_selection, &true.to_value()); - } - } - } - - if !model.iter_next(&iter) { + if end { break; } } } + + popover.popdown(); } -fn popover_unselect_custom(popover: >k::Popover, gui_data: &GuiData, tree_view: >k::TreeView, column_color: Option, column_file_name: i32, column_path: i32, column_button_selection: u32) { + +fn popover_one_oldest_newest(popover: >k::Popover, tree_view: >k::TreeView, column_color: i32, column_modification_as_secs: i32, column_file_name: i32, column_button_selection: u32, check_oldest: bool) { + let model = get_list_store(tree_view); + + if let Some(iter) = model.iter_first() { + let mut end: bool = false; + loop { + let mut tree_iter_array: Vec = Vec::new(); + let mut used_index: Option = None; + let mut current_index: usize = 0; + let mut modification_time_min_max: u64 = match check_oldest { + true => u64::MAX, + false => 0, + }; + + let mut file_length: usize = 0; + + loop { + let color = model.value(&iter, column_color).get::().unwrap(); + if color == HEADER_ROW_COLOR { + if !model.iter_next(&iter) { + end = true; + } + break; + } + tree_iter_array.push(iter.clone()); + let modification = model.value(&iter, column_modification_as_secs).get::().unwrap(); + let current_file_length = model.value(&iter, column_file_name).get::().unwrap().len(); + if check_oldest { + if modification < modification_time_min_max || (modification == modification_time_min_max && current_file_length > file_length) { + file_length = current_file_length; + modification_time_min_max = modification; + used_index = Some(current_index); + } + } else { + if modification > modification_time_min_max || (modification == modification_time_min_max && current_file_length > file_length) { + file_length = current_file_length; + modification_time_min_max = modification; + used_index = Some(current_index); + } + } + + current_index += 1; + + if !model.iter_next(&iter) { + end = true; + break; + } + } + if used_index == None { + continue; + } + for (index, tree_iter) in tree_iter_array.iter().enumerate() { + if index == used_index.unwrap() { + model.set_value(tree_iter, column_button_selection, &true.to_value()); + } else { + model.set_value(tree_iter, column_button_selection, &false.to_value()); + } + } + + if end { + break; + } + } + } + + popover.popdown(); +} + +fn popover_custom_select_unselect(popover: >k::Popover, window_main: &Window, tree_view: >k::TreeView, column_color: Option, column_file_name: i32, column_path: i32, column_button_selection: u32, select_things: bool) { popover.popdown(); let wildcard: String; @@ -407,10 +221,14 @@ fn popover_unselect_custom(popover: >k::Popover, gui_data: &GuiData, tree_view } let wildcard_type: WildcardType; + let window_title = match select_things { + false => "Unselect Custom", + true => "Select Custom", + }; + // Accept Dialog { - let window_main = gui_data.window_main.clone(); - let confirmation_dialog_delete = gtk::Dialog::with_buttons(Some("Unselect custom"), Some(&window_main), gtk::DialogFlags::MODAL, &[("Ok", gtk::ResponseType::Ok), ("Close", gtk::ResponseType::Cancel)]); + let confirmation_dialog_delete = gtk::Dialog::with_buttons(Some(window_title), Some(window_main), gtk::DialogFlags::MODAL, &[("Ok", gtk::ResponseType::Ok), ("Close", gtk::ResponseType::Cancel)]); let label: gtk::Label = gtk::Label::new(Some("Usage: */folder-nr*/* or name-version-*.txt")); let radio_path = gtk::RadioButton::with_label("Path"); @@ -457,7 +275,7 @@ fn popover_unselect_custom(popover: >k::Popover, gui_data: &GuiData, tree_view wildcard_type = WildcardType::PathName; wildcard = entry_name_path.text().to_string(); } else { - panic!("Non handled option in unselect wildcard"); + panic!("Non handled option in wildcard"); } } else { confirmation_dialog_delete.close(); @@ -493,17 +311,17 @@ fn popover_unselect_custom(popover: >k::Popover, gui_data: &GuiData, tree_view match wildcard_type { WildcardType::Path => { if Common::regex_check(wildcard, path) { - model.set_value(&iter, column_button_selection, &false.to_value()); + model.set_value(&iter, column_button_selection, &select_things.to_value()); } } WildcardType::Name => { if Common::regex_check(wildcard, name) { - model.set_value(&iter, column_button_selection, &false.to_value()); + model.set_value(&iter, column_button_selection, &select_things.to_value()); } } WildcardType::PathName => { if Common::regex_check(wildcard, format!("{}/{}", path, name)) { - model.set_value(&iter, column_button_selection, &false.to_value()); + model.set_value(&iter, column_button_selection, &select_things.to_value()); } } } @@ -515,17 +333,23 @@ fn popover_unselect_custom(popover: >k::Popover, gui_data: &GuiData, tree_view } } -fn popover_all_except_biggest(popover: >k::Popover, tree_view: >k::TreeView, column_color: i32, column_size_as_bytes: i32, column_dimensions: i32, column_button_selection: u32) { +fn popover_all_except_biggest_smallest(popover: >k::Popover, tree_view: >k::TreeView, column_color: i32, column_size_as_bytes: i32, column_dimensions: i32, column_button_selection: u32, except_biggest: bool) { let model = get_list_store(tree_view); if let Some(iter) = model.iter_first() { let mut end: bool = false; loop { let mut tree_iter_array: Vec = Vec::new(); - let mut biggest_index: Option = None; + let mut used_index: Option = None; let mut current_index: usize = 0; - let mut biggest_size_as_bytes: u64 = 0; - let mut biggest_number_of_pixels: u64 = 0; + let mut size_as_bytes_min_max: u64 = match except_biggest { + true => 0, + false => u64::MAX, + }; + let mut number_of_pixels_min_max: u64 = match except_biggest { + true => 0, + false => u64::MAX, + }; loop { let color = model.value(&iter, column_color).get::().unwrap(); @@ -542,69 +366,18 @@ fn popover_all_except_biggest(popover: >k::Popover, tree_view: >k::TreeView, let dimensions = change_dimension_to_krotka(dimensions_string); let number_of_pixels = dimensions.0 * dimensions.1; - if number_of_pixels > biggest_number_of_pixels || (number_of_pixels == biggest_number_of_pixels && size_as_bytes > biggest_size_as_bytes) { - biggest_number_of_pixels = number_of_pixels; - biggest_size_as_bytes = size_as_bytes; - biggest_index = Some(current_index); - } - - current_index += 1; - - if !model.iter_next(&iter) { - end = true; - break; - } - } - if biggest_index == None { - continue; - } - for (index, tree_iter) in tree_iter_array.iter().enumerate() { - if index != biggest_index.unwrap() { - model.set_value(tree_iter, column_button_selection, &true.to_value()); - } else { - model.set_value(tree_iter, column_button_selection, &false.to_value()); - } - } - - if end { - break; - } - } - } - - popover.popdown(); -} -fn popover_all_except_smallest(popover: >k::Popover, tree_view: >k::TreeView, column_color: i32, column_size_as_bytes: i32, column_dimensions: i32, column_button_selection: u32) { - let model = get_list_store(tree_view); - - if let Some(iter) = model.iter_first() { - let mut end: bool = false; - loop { - let mut tree_iter_array: Vec = Vec::new(); - let mut smallest_index: Option = None; - let mut current_index: usize = 0; - let mut smallest_size_as_bytes: u64 = u64::MAX; - let mut smallest_number_of_pixels: u64 = u64::MAX; - - loop { - let color = model.value(&iter, column_color).get::().unwrap(); - if color == HEADER_ROW_COLOR { - if !model.iter_next(&iter) { - end = true; + if except_biggest { + if number_of_pixels > number_of_pixels_min_max || (number_of_pixels == number_of_pixels_min_max && size_as_bytes > size_as_bytes_min_max) { + number_of_pixels_min_max = number_of_pixels; + size_as_bytes_min_max = size_as_bytes; + used_index = Some(current_index); + } + } else { + if number_of_pixels < number_of_pixels_min_max || (number_of_pixels == number_of_pixels_min_max && size_as_bytes < size_as_bytes_min_max) { + number_of_pixels_min_max = number_of_pixels; + size_as_bytes_min_max = size_as_bytes; + used_index = Some(current_index); } - break; - } - tree_iter_array.push(iter.clone()); - let size_as_bytes = model.value(&iter, column_size_as_bytes).get::().unwrap(); - let dimensions_string = model.value(&iter, column_dimensions).get::().unwrap(); - - let dimensions = change_dimension_to_krotka(dimensions_string); - let number_of_pixels = dimensions.0 * dimensions.1; - - if number_of_pixels < smallest_number_of_pixels || (number_of_pixels == smallest_number_of_pixels && size_as_bytes < smallest_size_as_bytes) { - smallest_number_of_pixels = number_of_pixels; - smallest_size_as_bytes = size_as_bytes; - smallest_index = Some(current_index); } current_index += 1; @@ -614,11 +387,11 @@ fn popover_all_except_smallest(popover: >k::Popover, tree_view: >k::TreeView break; } } - if smallest_index == None { + if used_index == None { continue; } for (index, tree_iter) in tree_iter_array.iter().enumerate() { - if index != smallest_index.unwrap() { + if index != used_index.unwrap() { model.set_value(tree_iter, column_button_selection, &true.to_value()); } else { model.set_value(tree_iter, column_button_selection, &false.to_value()); @@ -634,320 +407,205 @@ fn popover_all_except_smallest(popover: >k::Popover, tree_view: >k::TreeView popover.popdown(); } -#[derive(Clone)] -pub struct PopoverObject { - pub notebook_type: NotebookMainEnum, - pub available_modes: Vec, - pub tree_view: gtk::TreeView, - pub column_path: i32, - pub column_name: i32, - pub column_selection: u32, // TODo Change this to i32 after properly implement all things - pub column_color: Option, - pub column_dimensions: Option, - pub column_size: Option, - pub column_size_as_bytes: Option, - pub column_modification_as_secs: Option, -} - -pub fn find_name(notebook_type: &NotebookMainEnum, vec: &[PopoverObject]) -> Option { - for e in vec { - if e.notebook_type == *notebook_type { - return Some(e.clone()); - } - } - None -} - pub fn connect_popovers(gui_data: &GuiData) { - let popover_objects = vec![ - PopoverObject { - notebook_type: NotebookMainEnum::Duplicate, - available_modes: vec!["all", "reverse", "custom", "date"].iter().map(|e| e.to_string()).collect(), - tree_view: gui_data.main_notebook.tree_view_duplicate_finder.clone(), - column_path: ColumnsDuplicates::Path as i32, - column_name: ColumnsDuplicates::Name as i32, - column_selection: ColumnsDuplicates::ActiveSelectButton as u32, - column_color: Some(ColumnsDuplicates::Color as i32), - column_dimensions: None, - column_size: None, - column_size_as_bytes: None, - column_modification_as_secs: Some(ColumnsDuplicates::ModificationAsSecs as i32), - }, - PopoverObject { - notebook_type: NotebookMainEnum::SameMusic, - available_modes: vec!["all", "reverse", "custom", "date"].iter().map(|e| e.to_string()).collect(), - tree_view: gui_data.main_notebook.tree_view_same_music_finder.clone(), - column_path: ColumnsSameMusic::Path as i32, - column_name: ColumnsSameMusic::Name as i32, - column_selection: ColumnsSameMusic::ActiveSelectButton as u32, - column_color: Some(ColumnsSameMusic::Color as i32), - column_dimensions: None, - column_size: None, - column_size_as_bytes: Some(ColumnsSameMusic::SizeAsBytes as i32), - column_modification_as_secs: Some(ColumnsSameMusic::ModificationAsSecs as i32), - }, - PopoverObject { - notebook_type: NotebookMainEnum::SimilarImages, - available_modes: vec!["all", "reverse", "custom", "date"].iter().map(|e| e.to_string()).collect(), - tree_view: gui_data.main_notebook.tree_view_similar_images_finder.clone(), - column_path: ColumnsSimilarImages::Path as i32, - column_name: ColumnsSimilarImages::Name as i32, - column_selection: ColumnsSimilarImages::ActiveSelectButton as u32, - column_color: Some(ColumnsSimilarImages::Color as i32), - column_dimensions: Some(ColumnsSimilarImages::Dimensions as i32), - column_size: Some(ColumnsSimilarImages::Size as i32), - column_size_as_bytes: Some(ColumnsSimilarImages::SizeAsBytes as i32), - column_modification_as_secs: Some(ColumnsSimilarImages::ModificationAsSecs as i32), - }, - PopoverObject { - notebook_type: NotebookMainEnum::SimilarVideos, - available_modes: vec!["all", "reverse", "custom", "date"].iter().map(|e| e.to_string()).collect(), - tree_view: gui_data.main_notebook.tree_view_similar_videos_finder.clone(), - column_path: ColumnsSimilarVideos::Path as i32, - column_name: ColumnsSimilarVideos::Name as i32, - column_selection: ColumnsSimilarVideos::ActiveSelectButton as u32, - column_color: Some(ColumnsSimilarVideos::Color as i32), - column_dimensions: None, - column_size: Some(ColumnsSimilarVideos::Size as i32), - column_size_as_bytes: Some(ColumnsSimilarVideos::SizeAsBytes as i32), - column_modification_as_secs: Some(ColumnsSimilarVideos::ModificationAsSecs as i32), - }, - PopoverObject { - notebook_type: NotebookMainEnum::EmptyDirectories, - available_modes: vec!["all", "reverse", "custom"].iter().map(|e| e.to_string()).collect(), - tree_view: gui_data.main_notebook.tree_view_empty_folder_finder.clone(), - column_path: ColumnsEmptyFolders::Path as i32, - column_name: ColumnsEmptyFolders::Name as i32, - column_selection: ColumnsEmptyFolders::ActiveSelectButton as u32, - column_color: None, - column_dimensions: None, - column_size: None, - column_size_as_bytes: None, - column_modification_as_secs: None, - }, - PopoverObject { - notebook_type: NotebookMainEnum::EmptyFiles, - available_modes: vec!["all", "reverse", "custom"].iter().map(|e| e.to_string()).collect(), - tree_view: gui_data.main_notebook.tree_view_empty_files_finder.clone(), - column_path: ColumnsEmptyFiles::Path as i32, - column_name: ColumnsEmptyFiles::Name as i32, - column_selection: ColumnsEmptyFiles::ActiveSelectButton as u32, - column_color: None, - column_dimensions: None, - column_size: None, - column_size_as_bytes: None, - column_modification_as_secs: None, - }, - PopoverObject { - notebook_type: NotebookMainEnum::Temporary, - available_modes: vec!["all", "reverse", "custom"].iter().map(|e| e.to_string()).collect(), - tree_view: gui_data.main_notebook.tree_view_temporary_files_finder.clone(), - column_path: ColumnsTemporaryFiles::Path as i32, - column_name: ColumnsTemporaryFiles::Name as i32, - column_selection: ColumnsTemporaryFiles::ActiveSelectButton as u32, - column_color: None, - column_dimensions: None, - column_size: None, - column_size_as_bytes: None, - column_modification_as_secs: None, - }, - PopoverObject { - notebook_type: NotebookMainEnum::BigFiles, - available_modes: vec!["all", "reverse", "custom"].iter().map(|e| e.to_string()).collect(), - tree_view: gui_data.main_notebook.tree_view_big_files_finder.clone(), - column_path: ColumnsBigFiles::Path as i32, - column_name: ColumnsBigFiles::Name as i32, - column_selection: ColumnsBigFiles::ActiveSelectButton as u32, - column_color: None, - column_dimensions: None, - column_size: None, - column_size_as_bytes: None, - column_modification_as_secs: None, - }, - PopoverObject { - notebook_type: NotebookMainEnum::BrokenFiles, - available_modes: vec!["all", "reverse", "custom"].iter().map(|e| e.to_string()).collect(), - tree_view: gui_data.main_notebook.tree_view_broken_files.clone(), - column_path: ColumnsBrokenFiles::Path as i32, - column_name: ColumnsBrokenFiles::Name as i32, - column_selection: ColumnsBrokenFiles::ActiveSelectButton as u32, - column_color: None, - column_dimensions: None, - column_size: None, - column_size_as_bytes: None, - column_modification_as_secs: None, - }, - PopoverObject { - notebook_type: NotebookMainEnum::Symlinks, - available_modes: vec!["all", "reverse", "custom"].iter().map(|e| e.to_string()).collect(), - tree_view: gui_data.main_notebook.tree_view_invalid_symlinks.clone(), - column_path: ColumnsInvalidSymlinks::Path as i32, - column_name: ColumnsInvalidSymlinks::Name as i32, - column_selection: ColumnsInvalidSymlinks::ActiveSelectButton as u32, - column_color: None, - column_dimensions: None, - column_size: None, - column_size_as_bytes: None, - column_modification_as_secs: None, - }, - ]; - let popover_select = gui_data.popovers.popover_select.clone(); let buttons_popover_select_all = gui_data.popovers.buttons_popover_select_all.clone(); let notebook_main = gui_data.main_notebook.notebook_main.clone(); - let vec_popover_objects = popover_objects.clone(); + let main_tree_views = gui_data.main_notebook.get_main_tree_views(); + buttons_popover_select_all.connect_clicked(move |_| { - let object_popover = find_name(&to_notebook_main_enum(notebook_main.current_page().unwrap()), &vec_popover_objects).unwrap(); - popover_select_all(&popover_select, &object_popover.tree_view, object_popover.column_selection); + let nb_number = notebook_main.current_page().unwrap(); + let tree_view = &main_tree_views[nb_number as usize]; + let nb_object = &NOTEBOOKS_INFOS[nb_number as usize]; + + popover_select_all(&popover_select, tree_view, nb_object.column_selection as u32, nb_object.column_color); }); let popover_select = gui_data.popovers.popover_select.clone(); let buttons_popover_unselect_all = gui_data.popovers.buttons_popover_unselect_all.clone(); let notebook_main = gui_data.main_notebook.notebook_main.clone(); - let vec_popover_objects = popover_objects.clone(); + let main_tree_views = gui_data.main_notebook.get_main_tree_views(); buttons_popover_unselect_all.connect_clicked(move |_| { - let object_popover = find_name(&to_notebook_main_enum(notebook_main.current_page().unwrap()), &vec_popover_objects).unwrap(); - popover_unselect_all(&popover_select, &object_popover.tree_view, object_popover.column_selection); + let nb_number = notebook_main.current_page().unwrap(); + let tree_view = &main_tree_views[nb_number as usize]; + let nb_object = &NOTEBOOKS_INFOS[nb_number as usize]; + + popover_unselect_all(&popover_select, tree_view, nb_object.column_selection as u32); }); let popover_select = gui_data.popovers.popover_select.clone(); let buttons_popover_reverse = gui_data.popovers.buttons_popover_reverse.clone(); let notebook_main = gui_data.main_notebook.notebook_main.clone(); - let vec_popover_objects = popover_objects.clone(); + let main_tree_views = gui_data.main_notebook.get_main_tree_views(); buttons_popover_reverse.connect_clicked(move |_| { - let object_popover = find_name(&to_notebook_main_enum(notebook_main.current_page().unwrap()), &vec_popover_objects).unwrap(); - popover_reverse(&popover_select, &object_popover.tree_view, object_popover.column_selection); + let nb_number = notebook_main.current_page().unwrap(); + let tree_view = &main_tree_views[nb_number as usize]; + let nb_object = &NOTEBOOKS_INFOS[nb_number as usize]; + + popover_reverse(&popover_select, tree_view, nb_object.column_selection as u32, nb_object.column_color); }); let popover_select = gui_data.popovers.popover_select.clone(); let buttons_popover_select_all_except_oldest = gui_data.popovers.buttons_popover_select_all_except_oldest.clone(); let notebook_main = gui_data.main_notebook.notebook_main.clone(); - let vec_popover_objects = popover_objects.clone(); + let main_tree_views = gui_data.main_notebook.get_main_tree_views(); buttons_popover_select_all_except_oldest.connect_clicked(move |_| { - let object_popover = find_name(&to_notebook_main_enum(notebook_main.current_page().unwrap()), &vec_popover_objects).unwrap(); - popover_all_except_oldest( + let nb_number = notebook_main.current_page().unwrap(); + let tree_view = &main_tree_views[nb_number as usize]; + let nb_object = &NOTEBOOKS_INFOS[nb_number as usize]; + + popover_all_except_oldest_newest( &popover_select, - &object_popover.tree_view, - object_popover.column_color.unwrap(), - object_popover.column_modification_as_secs.unwrap(), - object_popover.column_name, - object_popover.column_selection, + tree_view, + nb_object.column_color.expect("AEO can't be used without headers"), + nb_object.column_modification_as_secs.expect("AEO needs modification as secs column"), + nb_object.column_name, + nb_object.column_selection as u32, + true, ); }); let popover_select = gui_data.popovers.popover_select.clone(); let buttons_popover_select_all_except_newest = gui_data.popovers.buttons_popover_select_all_except_newest.clone(); let notebook_main = gui_data.main_notebook.notebook_main.clone(); - let vec_popover_objects = popover_objects.clone(); + let main_tree_views = gui_data.main_notebook.get_main_tree_views(); buttons_popover_select_all_except_newest.connect_clicked(move |_| { - let object_popover = find_name(&to_notebook_main_enum(notebook_main.current_page().unwrap()), &vec_popover_objects).unwrap(); - popover_all_except_newest( + let nb_number = notebook_main.current_page().unwrap(); + let tree_view = &main_tree_views[nb_number as usize]; + let nb_object = &NOTEBOOKS_INFOS[nb_number as usize]; + + popover_all_except_oldest_newest( &popover_select, - &object_popover.tree_view, - object_popover.column_color.unwrap(), - object_popover.column_modification_as_secs.unwrap(), - object_popover.column_name, - object_popover.column_selection, + tree_view, + nb_object.column_color.expect("AEN can't be used without headers"), + nb_object.column_modification_as_secs.expect("AEN needs modification as secs column"), + nb_object.column_name, + nb_object.column_selection as u32, + false, ); }); let popover_select = gui_data.popovers.popover_select.clone(); let buttons_popover_select_one_oldest = gui_data.popovers.buttons_popover_select_one_oldest.clone(); let notebook_main = gui_data.main_notebook.notebook_main.clone(); - let vec_popover_objects = popover_objects.clone(); + let main_tree_views = gui_data.main_notebook.get_main_tree_views(); buttons_popover_select_one_oldest.connect_clicked(move |_| { - let object_popover = find_name(&to_notebook_main_enum(notebook_main.current_page().unwrap()), &vec_popover_objects).unwrap(); - popover_one_oldest( + let nb_number = notebook_main.current_page().unwrap(); + let tree_view = &main_tree_views[nb_number as usize]; + let nb_object = &NOTEBOOKS_INFOS[nb_number as usize]; + + popover_one_oldest_newest( &popover_select, - &object_popover.tree_view, - object_popover.column_color.unwrap(), - object_popover.column_modification_as_secs.unwrap(), - object_popover.column_name, - object_popover.column_selection, + tree_view, + nb_object.column_color.expect("OO can't be used without headers"), + nb_object.column_modification_as_secs.expect("OO needs modification as secs column"), + nb_object.column_name, + nb_object.column_selection as u32, + true, ); }); let popover_select = gui_data.popovers.popover_select.clone(); let buttons_popover_select_one_newest = gui_data.popovers.buttons_popover_select_one_newest.clone(); let notebook_main = gui_data.main_notebook.notebook_main.clone(); - let vec_popover_objects = popover_objects.clone(); + let main_tree_views = gui_data.main_notebook.get_main_tree_views(); buttons_popover_select_one_newest.connect_clicked(move |_| { - let object_popover = find_name(&to_notebook_main_enum(notebook_main.current_page().unwrap()), &vec_popover_objects).unwrap(); - popover_one_newest( + let nb_number = notebook_main.current_page().unwrap(); + let tree_view = &main_tree_views[nb_number as usize]; + let nb_object = &NOTEBOOKS_INFOS[nb_number as usize]; + + popover_one_oldest_newest( &popover_select, - &object_popover.tree_view, - object_popover.column_color.unwrap(), - object_popover.column_modification_as_secs.unwrap(), - object_popover.column_name, - object_popover.column_selection, + tree_view, + nb_object.column_color.expect("ON can't be used without headers"), + nb_object.column_modification_as_secs.expect("ON needs modification as secs column"), + nb_object.column_name, + nb_object.column_selection as u32, + false, ); }); let popover_select = gui_data.popovers.popover_select.clone(); let buttons_popover_select_custom = gui_data.popovers.buttons_popover_select_custom.clone(); let notebook_main = gui_data.main_notebook.notebook_main.clone(); - let vec_popover_objects = popover_objects.clone(); - let gui_data_clone = gui_data.clone(); + let main_tree_views = gui_data.main_notebook.get_main_tree_views(); + let window_main = gui_data.window_main.clone(); buttons_popover_select_custom.connect_clicked(move |_| { - let object_popover = find_name(&to_notebook_main_enum(notebook_main.current_page().unwrap()), &vec_popover_objects).unwrap(); - popover_select_custom( + let nb_number = notebook_main.current_page().unwrap(); + let tree_view = &main_tree_views[nb_number as usize]; + let nb_object = &NOTEBOOKS_INFOS[nb_number as usize]; + + popover_custom_select_unselect( &popover_select, - &gui_data_clone, - &object_popover.tree_view, - object_popover.column_color, - object_popover.column_name, - object_popover.column_path, - object_popover.column_selection, + &window_main, + tree_view, + nb_object.column_color, + nb_object.column_name, + nb_object.column_path, + nb_object.column_selection as u32, + true, ); }); let popover_select = gui_data.popovers.popover_select.clone(); let buttons_popover_unselect_custom = gui_data.popovers.buttons_popover_unselect_custom.clone(); let notebook_main = gui_data.main_notebook.notebook_main.clone(); - let vec_popover_objects = popover_objects.clone(); - let gui_data_clone = gui_data.clone(); + let main_tree_views = gui_data.main_notebook.get_main_tree_views(); + let window_main = gui_data.window_main.clone(); buttons_popover_unselect_custom.connect_clicked(move |_| { - let object_popover = find_name(&to_notebook_main_enum(notebook_main.current_page().unwrap()), &vec_popover_objects).unwrap(); - popover_unselect_custom( + let nb_number = notebook_main.current_page().unwrap(); + let tree_view = &main_tree_views[nb_number as usize]; + let nb_object = &NOTEBOOKS_INFOS[nb_number as usize]; + + popover_custom_select_unselect( &popover_select, - &gui_data_clone, - &object_popover.tree_view, - object_popover.column_color, - object_popover.column_name, - object_popover.column_path, - object_popover.column_selection, + &window_main, + tree_view, + nb_object.column_color, + nb_object.column_name, + nb_object.column_path, + nb_object.column_selection as u32, + false, ); }); let popover_select = gui_data.popovers.popover_select.clone(); let buttons_popover_select_all_images_except_biggest = gui_data.popovers.buttons_popover_select_all_images_except_biggest.clone(); let notebook_main = gui_data.main_notebook.notebook_main.clone(); - let vec_popover_objects = popover_objects.clone(); + let main_tree_views = gui_data.main_notebook.get_main_tree_views(); buttons_popover_select_all_images_except_biggest.connect_clicked(move |_| { - let object_popover = find_name(&to_notebook_main_enum(notebook_main.current_page().unwrap()), &vec_popover_objects).unwrap(); - popover_all_except_biggest( + let nb_number = notebook_main.current_page().unwrap(); + let tree_view = &main_tree_views[nb_number as usize]; + let nb_object = &NOTEBOOKS_INFOS[nb_number as usize]; + + popover_all_except_biggest_smallest( &popover_select, - &object_popover.tree_view, - object_popover.column_color.unwrap(), - object_popover.column_size_as_bytes.unwrap(), - object_popover.column_dimensions.unwrap(), - object_popover.column_selection, + tree_view, + nb_object.column_color.expect("AEB can't be used without headers"), + nb_object.column_size_as_bytes.expect("AEB needs size as bytes column"), + nb_object.column_dimensions.expect("AEB needs dimensions column"), + nb_object.column_selection as u32, + true, ); }); let popover_select = gui_data.popovers.popover_select.clone(); let buttons_popover_select_all_images_except_smallest = gui_data.popovers.buttons_popover_select_all_images_except_smallest.clone(); let notebook_main = gui_data.main_notebook.notebook_main.clone(); - let vec_popover_objects = popover_objects; //.clone(); + let main_tree_views = gui_data.main_notebook.get_main_tree_views(); buttons_popover_select_all_images_except_smallest.connect_clicked(move |_| { - let object_popover = find_name(&to_notebook_main_enum(notebook_main.current_page().unwrap()), &vec_popover_objects).unwrap(); - popover_all_except_smallest( + let nb_number = notebook_main.current_page().unwrap(); + let tree_view = &main_tree_views[nb_number as usize]; + let nb_object = &NOTEBOOKS_INFOS[nb_number as usize]; + + popover_all_except_biggest_smallest( &popover_select, - &object_popover.tree_view, - object_popover.column_color.unwrap(), - object_popover.column_size_as_bytes.unwrap(), - object_popover.column_dimensions.unwrap(), - object_popover.column_selection, + tree_view, + nb_object.column_color.expect("AES can't be used without headers"), + nb_object.column_size_as_bytes.expect("AES needs size as bytes column"), + nb_object.column_dimensions.expect("AES needs dimensions column"), + nb_object.column_selection as u32, + false, ); }); } diff --git a/czkawka_gui/src/connect_selection_of_directories.rs b/czkawka_gui/src/connect_selection_of_directories.rs index a83fcf6..1df4492 100644 --- a/czkawka_gui/src/connect_selection_of_directories.rs +++ b/czkawka_gui/src/connect_selection_of_directories.rs @@ -1,6 +1,7 @@ use crate::gui_data::GuiData; -use crate::help_functions::get_list_store; +use crate::help_functions::{get_list_store, ColumnsDirectory}; use gtk::prelude::*; +use gtk::{TreeView, Window}; #[cfg(target_family = "windows")] use czkawka_core::common::Common; @@ -12,34 +13,7 @@ pub fn connect_selection_of_directories(gui_data: &GuiData) { let window_main = gui_data.window_main.clone(); let buttons_manual_add_directory = gui_data.upper_notebook.buttons_manual_add_directory.clone(); buttons_manual_add_directory.connect_clicked(move |_| { - let dialog_manual_add_directory = gtk::Dialog::with_buttons(Some("Add directory manually"), Some(&window_main), gtk::DialogFlags::MODAL, &[("Ok", gtk::ResponseType::Ok), ("Close", gtk::ResponseType::Cancel)]); - let entry: gtk::Entry = gtk::Entry::new(); - - for widgets in dialog_manual_add_directory.children() { - // By default GtkBox is child of dialog, so we can easily add other things to it - widgets.clone().downcast::().unwrap().add(&entry); - } - - dialog_manual_add_directory.show_all(); - - let response_type = dialog_manual_add_directory.run(); - if response_type == gtk::ResponseType::Ok { - let text = entry.text().to_string().trim().to_string(); - - #[cfg(target_family = "windows")] - let text = Common::normalize_windows_path(text).to_string_lossy().to_string(); - - if !text.is_empty() { - let list_store = get_list_store(&tree_view_included_directories); - - let values: [(u32, &dyn ToValue); 1] = [(0, &text)]; - list_store.set(&list_store.append(), &values); - } - } else { - dialog_manual_add_directory.close(); - return; - } - dialog_manual_add_directory.close(); + add_manually_directories(&window_main, &tree_view_included_directories); }); } // Add manually excluded directory @@ -48,39 +22,7 @@ pub fn connect_selection_of_directories(gui_data: &GuiData) { let window_main = gui_data.window_main.clone(); let buttons_manual_add_excluded_directory = gui_data.upper_notebook.buttons_manual_add_excluded_directory.clone(); buttons_manual_add_excluded_directory.connect_clicked(move |_| { - let dialog_manual_add_directory = gtk::Dialog::with_buttons( - Some("Add excluded directory manually"), - Some(&window_main), - gtk::DialogFlags::MODAL, - &[("Ok", gtk::ResponseType::Ok), ("Close", gtk::ResponseType::Cancel)], - ); - let entry: gtk::Entry = gtk::Entry::new(); - - for widgets in dialog_manual_add_directory.children() { - // By default GtkBox is child of dialog, so we can easily add other things to it - widgets.clone().downcast::().unwrap().add(&entry); - } - - dialog_manual_add_directory.show_all(); - - let response_type = dialog_manual_add_directory.run(); - if response_type == gtk::ResponseType::Ok { - let text = entry.text().to_string().trim().to_string(); - - #[cfg(target_family = "windows")] - let text = Common::normalize_windows_path(text).to_string_lossy().to_string(); - - if !text.is_empty() { - let list_store = get_list_store(&tree_view_excluded_directories); - - let values: [(u32, &dyn ToValue); 1] = [(0, &text)]; - list_store.set(&list_store.append(), &values); - } - } else { - dialog_manual_add_directory.close(); - return; - } - dialog_manual_add_directory.close(); + add_manually_directories(&window_main, &tree_view_excluded_directories); }); } // Add included directory @@ -89,26 +31,7 @@ pub fn connect_selection_of_directories(gui_data: &GuiData) { let window_main = gui_data.window_main.clone(); let buttons_add_included_directory = gui_data.upper_notebook.buttons_add_included_directory.clone(); buttons_add_included_directory.connect_clicked(move |_| { - let chooser = gtk::FileChooserDialog::with_buttons( - Some("Folders to include"), - Some(&window_main), - gtk::FileChooserAction::SelectFolder, - &[("Ok", gtk::ResponseType::Ok), ("Close", gtk::ResponseType::Cancel)], - ); - chooser.set_select_multiple(true); - chooser.show_all(); - let response_type = chooser.run(); - if response_type == gtk::ResponseType::Ok { - let folder = chooser.filenames(); - - let list_store = get_list_store(&tree_view_included_directories); - - for file_entry in &folder { - let values: [(u32, &dyn ToValue); 1] = [(0, &file_entry.to_string_lossy().to_string())]; - list_store.set(&list_store.append(), &values); - } - } - chooser.close(); + add_chosen_directories(&window_main, &tree_view_included_directories, false); }); } // Add excluded directory @@ -117,26 +40,7 @@ pub fn connect_selection_of_directories(gui_data: &GuiData) { let window_main = gui_data.window_main.clone(); let buttons_add_excluded_directory = gui_data.upper_notebook.buttons_add_excluded_directory.clone(); buttons_add_excluded_directory.connect_clicked(move |_| { - let chooser = gtk::FileChooserDialog::with_buttons( - Some("Folders to exclude"), - Some(&window_main), - gtk::FileChooserAction::SelectFolder, - &[("Ok", gtk::ResponseType::Ok), ("Close", gtk::ResponseType::Cancel)], - ); - chooser.set_select_multiple(true); - chooser.show_all(); - let response_type = chooser.run(); - if response_type == gtk::ResponseType::Ok { - let folder = chooser.filenames(); - - let list_store = get_list_store(&tree_view_excluded_directories); - - for file_entry in &folder { - let values: [(u32, &dyn ToValue); 1] = [(0, &file_entry.to_string_lossy().to_string())]; - list_store.set(&list_store.append(), &values); - } - } - chooser.close(); + add_chosen_directories(&window_main, &tree_view_excluded_directories, true); }); } // Remove Excluded Folder @@ -170,3 +74,53 @@ pub fn connect_selection_of_directories(gui_data: &GuiData) { }); } } + +fn add_chosen_directories(window_main: &Window, tree_view: &TreeView, excluded_items: bool) { + let folders_to = if excluded_items { "Folders to exclude" } else { "Folders to include" }; + let chooser = gtk::FileChooserDialog::with_buttons(Some(folders_to), Some(window_main), gtk::FileChooserAction::SelectFolder, &[("Ok", gtk::ResponseType::Ok), ("Close", gtk::ResponseType::Cancel)]); + chooser.set_select_multiple(true); + chooser.show_all(); + let response_type = chooser.run(); + if response_type == gtk::ResponseType::Ok { + let folder = chooser.filenames(); + + let list_store = get_list_store(tree_view); + + for file_entry in &folder { + let values: [(u32, &dyn ToValue); 1] = [(ColumnsDirectory::Path as u32, &file_entry.to_string_lossy().to_string())]; + list_store.set(&list_store.append(), &values); + } + } + chooser.close(); +} + +fn add_manually_directories(window_main: &Window, tree_view: &TreeView) { + let dialog_manual_add_directory = gtk::Dialog::with_buttons(Some("Add directory manually"), Some(window_main), gtk::DialogFlags::MODAL, &[("Ok", gtk::ResponseType::Ok), ("Close", gtk::ResponseType::Cancel)]); + let entry: gtk::Entry = gtk::Entry::new(); + + for widgets in dialog_manual_add_directory.children() { + // By default GtkBox is child of dialog, so we can easily add other things to it + widgets.clone().downcast::().unwrap().add(&entry); + } + + dialog_manual_add_directory.show_all(); + + let response_type = dialog_manual_add_directory.run(); + if response_type == gtk::ResponseType::Ok { + let text = entry.text().to_string().trim().to_string(); + + #[cfg(target_family = "windows")] + let text = Common::normalize_windows_path(text).to_string_lossy().to_string(); + + if !text.is_empty() { + let list_store = get_list_store(tree_view); + + let values: [(u32, &dyn ToValue); 1] = [(ColumnsDirectory::Path as u32, &text)]; + list_store.set(&list_store.append(), &values); + } + } else { + dialog_manual_add_directory.close(); + return; + } + dialog_manual_add_directory.close(); +} diff --git a/czkawka_gui/src/connect_settings.rs b/czkawka_gui/src/connect_settings.rs index 613c812..984e828 100644 --- a/czkawka_gui/src/connect_settings.rs +++ b/czkawka_gui/src/connect_settings.rs @@ -29,26 +29,33 @@ pub fn connect_settings(gui_data: &GuiData) { // Connect save configuration button { - let gui_data = gui_data.clone(); + let upper_notebook = gui_data.upper_notebook.clone(); + let settings = gui_data.settings.clone(); + let text_view_errors = gui_data.text_view_errors.clone(); let button_settings_save_configuration = gui_data.settings.button_settings_save_configuration.clone(); button_settings_save_configuration.connect_clicked(move |_| { - save_configuration(&gui_data, true); + save_configuration(true, &upper_notebook, &settings, &text_view_errors); }); } // Connect load configuration button { - let gui_data = gui_data.clone(); + let upper_notebook = gui_data.upper_notebook.clone(); + let settings = gui_data.settings.clone(); + let text_view_errors = gui_data.text_view_errors.clone(); let button_settings_load_configuration = gui_data.settings.button_settings_load_configuration.clone(); + let scrolled_window_errors = gui_data.scrolled_window_errors.clone(); button_settings_load_configuration.connect_clicked(move |_| { - load_configuration(&gui_data, true); + load_configuration(true, &upper_notebook, &settings, &text_view_errors, &scrolled_window_errors); }); } // Connect reset configuration button { - let gui_data = gui_data.clone(); + let upper_notebook = gui_data.upper_notebook.clone(); + let settings = gui_data.settings.clone(); + let text_view_errors = gui_data.text_view_errors.clone(); let button_settings_reset_configuration = gui_data.settings.button_settings_reset_configuration.clone(); button_settings_reset_configuration.connect_clicked(move |_| { - reset_configuration(&gui_data, true); + reset_configuration(true, &upper_notebook, &settings, &text_view_errors); }); } } diff --git a/czkawka_gui/src/create_tree_view.rs b/czkawka_gui/src/create_tree_view.rs index 63f7c5f..40cb5a5 100644 --- a/czkawka_gui/src/create_tree_view.rs +++ b/czkawka_gui/src/create_tree_view.rs @@ -9,18 +9,18 @@ pub fn create_tree_view_duplicates(tree_view: &mut gtk::TreeView) { renderer.connect_toggled(move |_r, path| { let iter = model.iter(&path).unwrap(); let mut fixed = model - .value(&iter, ColumnsDuplicates::ActiveSelectButton as i32) + .value(&iter, ColumnsDuplicates::SelectionButton as i32) .get::() .unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err)); fixed = !fixed; - model.set_value(&iter, ColumnsDuplicates::ActiveSelectButton as u32, &fixed.to_value()); + model.set_value(&iter, ColumnsDuplicates::SelectionButton as u32, &fixed.to_value()); }); let column = gtk::TreeViewColumn::new(); column.pack_start(&renderer, true); column.set_resizable(false); column.set_fixed_width(30); column.add_attribute(&renderer, "activatable", ColumnsDuplicates::ActivatableSelectButton as i32); - column.add_attribute(&renderer, "active", ColumnsDuplicates::ActiveSelectButton as i32); + column.add_attribute(&renderer, "active", ColumnsDuplicates::SelectionButton as i32); column.add_attribute(&renderer, "cell-background", ColumnsDuplicates::Color as i32); tree_view.append_column(&column); @@ -67,17 +67,17 @@ pub fn create_tree_view_empty_folders(tree_view: &mut gtk::TreeView) { renderer.connect_toggled(move |_r, path| { let iter = model.iter(&path).unwrap(); let mut fixed = model - .value(&iter, ColumnsEmptyFolders::ActiveSelectButton as i32) + .value(&iter, ColumnsEmptyFolders::SelectionButton as i32) .get::() .unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err)); fixed = !fixed; - model.set_value(&iter, ColumnsEmptyFolders::ActiveSelectButton as u32, &fixed.to_value()); + model.set_value(&iter, ColumnsEmptyFolders::SelectionButton as u32, &fixed.to_value()); }); let column = gtk::TreeViewColumn::new(); column.pack_start(&renderer, true); column.set_resizable(false); column.set_fixed_width(30); - column.add_attribute(&renderer, "active", ColumnsEmptyFolders::ActiveSelectButton as i32); + column.add_attribute(&renderer, "active", ColumnsEmptyFolders::SelectionButton as i32); tree_view.append_column(&column); let renderer = gtk::CellRendererText::new(); @@ -117,17 +117,17 @@ pub fn create_tree_view_big_files(tree_view: &mut gtk::TreeView) { renderer.connect_toggled(move |_r, path| { let iter = model.iter(&path).unwrap(); let mut fixed = model - .value(&iter, ColumnsBigFiles::ActiveSelectButton as i32) + .value(&iter, ColumnsBigFiles::SelectionButton as i32) .get::() .unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err)); fixed = !fixed; - model.set_value(&iter, ColumnsBigFiles::ActiveSelectButton as u32, &fixed.to_value()); + model.set_value(&iter, ColumnsBigFiles::SelectionButton as u32, &fixed.to_value()); }); let column = gtk::TreeViewColumn::new(); column.pack_start(&renderer, true); column.set_resizable(false); column.set_fixed_width(30); - column.add_attribute(&renderer, "active", ColumnsBigFiles::ActiveSelectButton as i32); + column.add_attribute(&renderer, "active", ColumnsBigFiles::SelectionButton as i32); tree_view.append_column(&column); let renderer = gtk::CellRendererText::new(); @@ -176,17 +176,17 @@ pub fn create_tree_view_temporary_files(tree_view: &mut gtk::TreeView) { renderer.connect_toggled(move |_r, path| { let iter = model.iter(&path).unwrap(); let mut fixed = model - .value(&iter, ColumnsTemporaryFiles::ActiveSelectButton as i32) + .value(&iter, ColumnsTemporaryFiles::SelectionButton as i32) .get::() .unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err)); fixed = !fixed; - model.set_value(&iter, ColumnsTemporaryFiles::ActiveSelectButton as u32, &fixed.to_value()); + model.set_value(&iter, ColumnsTemporaryFiles::SelectionButton as u32, &fixed.to_value()); }); let column = gtk::TreeViewColumn::new(); column.pack_start(&renderer, true); column.set_resizable(false); column.set_fixed_width(30); - column.add_attribute(&renderer, "active", ColumnsTemporaryFiles::ActiveSelectButton as i32); + column.add_attribute(&renderer, "active", ColumnsTemporaryFiles::SelectionButton as i32); tree_view.append_column(&column); let renderer = gtk::CellRendererText::new(); @@ -226,17 +226,17 @@ pub fn create_tree_view_empty_files(tree_view: &mut gtk::TreeView) { renderer.connect_toggled(move |_r, path| { let iter = model.iter(&path).unwrap(); let mut fixed = model - .value(&iter, ColumnsEmptyFiles::ActiveSelectButton as i32) + .value(&iter, ColumnsEmptyFiles::SelectionButton as i32) .get::() .unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err)); fixed = !fixed; - model.set_value(&iter, ColumnsEmptyFiles::ActiveSelectButton as u32, &fixed.to_value()); + model.set_value(&iter, ColumnsEmptyFiles::SelectionButton as u32, &fixed.to_value()); }); let column = gtk::TreeViewColumn::new(); column.pack_start(&renderer, true); column.set_resizable(false); column.set_fixed_width(30); - column.add_attribute(&renderer, "active", ColumnsEmptyFiles::ActiveSelectButton as i32); + column.add_attribute(&renderer, "active", ColumnsEmptyFiles::SelectionButton as i32); tree_view.append_column(&column); let renderer = gtk::CellRendererText::new(); @@ -276,18 +276,18 @@ pub fn create_tree_view_similar_images(tree_view: &mut gtk::TreeView) { renderer.connect_toggled(move |_r, path| { let iter = model.iter(&path).unwrap(); let mut fixed = model - .value(&iter, ColumnsSimilarImages::ActiveSelectButton as i32) + .value(&iter, ColumnsSimilarImages::SelectionButton as i32) .get::() .unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err)); fixed = !fixed; - model.set_value(&iter, ColumnsSimilarImages::ActiveSelectButton as u32, &fixed.to_value()); + model.set_value(&iter, ColumnsSimilarImages::SelectionButton as u32, &fixed.to_value()); }); let column = gtk::TreeViewColumn::new(); column.pack_start(&renderer, true); column.set_resizable(false); column.set_fixed_width(30); column.add_attribute(&renderer, "activatable", ColumnsSimilarImages::ActivatableSelectButton as i32); - column.add_attribute(&renderer, "active", ColumnsSimilarImages::ActiveSelectButton as i32); + column.add_attribute(&renderer, "active", ColumnsSimilarImages::SelectionButton as i32); column.add_attribute(&renderer, "cell-background", ColumnsSimilarImages::Color as i32); tree_view.append_column(&column); @@ -367,18 +367,18 @@ pub fn create_tree_view_similar_videos(tree_view: &mut gtk::TreeView) { renderer.connect_toggled(move |_r, path| { let iter = model.iter(&path).unwrap(); let mut fixed = model - .value(&iter, ColumnsSimilarVideos::ActiveSelectButton as i32) + .value(&iter, ColumnsSimilarVideos::SelectionButton as i32) .get::() .unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err)); fixed = !fixed; - model.set_value(&iter, ColumnsSimilarVideos::ActiveSelectButton as u32, &fixed.to_value()); + model.set_value(&iter, ColumnsSimilarVideos::SelectionButton as u32, &fixed.to_value()); }); let column = gtk::TreeViewColumn::new(); column.pack_start(&renderer, true); column.set_resizable(false); column.set_fixed_width(30); column.add_attribute(&renderer, "activatable", ColumnsSimilarVideos::ActivatableSelectButton as i32); - column.add_attribute(&renderer, "active", ColumnsSimilarVideos::ActiveSelectButton as i32); + column.add_attribute(&renderer, "active", ColumnsSimilarVideos::SelectionButton as i32); column.add_attribute(&renderer, "cell-background", ColumnsSimilarVideos::Color as i32); tree_view.append_column(&column); @@ -446,18 +446,18 @@ pub fn create_tree_view_same_music(tree_view: &mut gtk::TreeView) { renderer.connect_toggled(move |_r, path| { let iter = model.iter(&path).unwrap(); let mut fixed = model - .value(&iter, ColumnsSameMusic::ActiveSelectButton as i32) + .value(&iter, ColumnsSameMusic::SelectionButton as i32) .get::() .unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err)); fixed = !fixed; - model.set_value(&iter, ColumnsSameMusic::ActiveSelectButton as u32, &fixed.to_value()); + model.set_value(&iter, ColumnsSameMusic::SelectionButton as u32, &fixed.to_value()); }); let column = gtk::TreeViewColumn::new(); column.pack_start(&renderer, true); column.set_resizable(false); column.set_fixed_width(30); column.add_attribute(&renderer, "activatable", ColumnsSameMusic::ActivatableSelectButton as i32); - column.add_attribute(&renderer, "active", ColumnsSameMusic::ActiveSelectButton as i32); + column.add_attribute(&renderer, "active", ColumnsSameMusic::SelectionButton as i32); column.add_attribute(&renderer, "cell-background", ColumnsSameMusic::Color as i32); tree_view.append_column(&column); @@ -570,17 +570,17 @@ pub fn create_tree_view_invalid_symlinks(tree_view: &mut gtk::TreeView) { renderer.connect_toggled(move |_r, path| { let iter = model.iter(&path).unwrap(); let mut fixed = model - .value(&iter, ColumnsInvalidSymlinks::ActiveSelectButton as i32) + .value(&iter, ColumnsInvalidSymlinks::SelectionButton as i32) .get::() .unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err)); fixed = !fixed; - model.set_value(&iter, ColumnsInvalidSymlinks::ActiveSelectButton as u32, &fixed.to_value()); + model.set_value(&iter, ColumnsInvalidSymlinks::SelectionButton as u32, &fixed.to_value()); }); let column = gtk::TreeViewColumn::new(); column.pack_start(&renderer, true); column.set_resizable(false); column.set_fixed_width(30); - column.add_attribute(&renderer, "active", ColumnsInvalidSymlinks::ActiveSelectButton as i32); + column.add_attribute(&renderer, "active", ColumnsInvalidSymlinks::SelectionButton as i32); tree_view.append_column(&column); let renderer = gtk::CellRendererText::new(); @@ -638,17 +638,17 @@ pub fn create_tree_view_broken_files(tree_view: &mut gtk::TreeView) { renderer.connect_toggled(move |_r, path| { let iter = model.iter(&path).unwrap(); let mut fixed = model - .value(&iter, ColumnsBrokenFiles::ActiveSelectButton as i32) + .value(&iter, ColumnsBrokenFiles::SelectionButton as i32) .get::() .unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err)); fixed = !fixed; - model.set_value(&iter, ColumnsBrokenFiles::ActiveSelectButton as u32, &fixed.to_value()); + model.set_value(&iter, ColumnsBrokenFiles::SelectionButton as u32, &fixed.to_value()); }); let column = gtk::TreeViewColumn::new(); column.pack_start(&renderer, true); column.set_resizable(false); column.set_fixed_width(30); - column.add_attribute(&renderer, "active", ColumnsBrokenFiles::ActiveSelectButton as i32); + column.add_attribute(&renderer, "active", ColumnsBrokenFiles::SelectionButton as i32); tree_view.append_column(&column); let renderer = gtk::CellRendererText::new(); diff --git a/czkawka_gui/src/double_click_opening.rs b/czkawka_gui/src/double_click_opening.rs deleted file mode 100644 index 4dba49f..0000000 --- a/czkawka_gui/src/double_click_opening.rs +++ /dev/null @@ -1,187 +0,0 @@ -use crate::help_functions::*; -use gtk::prelude::*; - -const KEY_ENTER: u16 = 36; -const KEY_SPACE: u16 = 65; - -// TODO add option to open files and folders from context menu activated by pressing ONCE with right mouse button - -pub fn opening_double_click_function_duplicates(tree_view: >k::TreeView, event: &gdk::EventButton) -> gtk::Inhibit { - if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 1 { - common_open_function(tree_view, ColumnsDuplicates::Name as i32, ColumnsDuplicates::Path as i32, OpenMode::PathAndName); - } else if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 3 { - common_open_function(tree_view, ColumnsDuplicates::Name as i32, ColumnsDuplicates::Path as i32, OpenMode::OnlyPath); - } - gtk::Inhibit(false) -} -pub fn opening_enter_function_duplicates(tree_view: >k::TreeView, event: &gdk::EventKey) -> gtk::Inhibit { - handle_tree_keypress(tree_view, event, ColumnsDuplicates::Name as u32, ColumnsDuplicates::Path as u32, ColumnsDuplicates::ActiveSelectButton as u32) -} - -pub fn opening_double_click_function_empty_folders(tree_view: >k::TreeView, event: &gdk::EventButton) -> gtk::Inhibit { - if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 1 { - common_open_function(tree_view, ColumnsEmptyFolders::Name as i32, ColumnsEmptyFolders::Path as i32, OpenMode::PathAndName); - } else if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 3 { - common_open_function(tree_view, ColumnsEmptyFolders::Name as i32, ColumnsEmptyFolders::Path as i32, OpenMode::OnlyPath); - } - gtk::Inhibit(false) -} -pub fn opening_enter_function_empty_folders(tree_view: >k::TreeView, event: &gdk::EventKey) -> gtk::Inhibit { - handle_tree_keypress(tree_view, event, ColumnsEmptyFolders::Name as u32, ColumnsEmptyFolders::Path as u32, ColumnsEmptyFolders::ActiveSelectButton as u32) -} - -pub fn opening_double_click_function_empty_files(tree_view: >k::TreeView, event: &gdk::EventButton) -> gtk::Inhibit { - if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 1 { - common_open_function(tree_view, ColumnsEmptyFiles::Name as i32, ColumnsEmptyFiles::Path as i32, OpenMode::PathAndName); - } else if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 3 { - common_open_function(tree_view, ColumnsEmptyFiles::Name as i32, ColumnsEmptyFiles::Path as i32, OpenMode::OnlyPath); - } - gtk::Inhibit(false) -} -pub fn opening_enter_function_empty_files(tree_view: >k::TreeView, event: &gdk::EventKey) -> gtk::Inhibit { - handle_tree_keypress(tree_view, event, ColumnsEmptyFiles::Name as u32, ColumnsEmptyFiles::Path as u32, ColumnsEmptyFiles::ActiveSelectButton as u32) -} - -pub fn opening_double_click_function_temporary_files(tree_view: >k::TreeView, event: &gdk::EventButton) -> gtk::Inhibit { - if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 1 { - common_open_function(tree_view, ColumnsTemporaryFiles::Name as i32, ColumnsTemporaryFiles::Path as i32, OpenMode::PathAndName); - } else if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 3 { - common_open_function(tree_view, ColumnsTemporaryFiles::Name as i32, ColumnsTemporaryFiles::Path as i32, OpenMode::OnlyPath); - } - gtk::Inhibit(false) -} -pub fn opening_enter_function_temporary_files(tree_view: >k::TreeView, event: &gdk::EventKey) -> gtk::Inhibit { - handle_tree_keypress(tree_view, event, ColumnsTemporaryFiles::Name as u32, ColumnsTemporaryFiles::Path as u32, ColumnsTemporaryFiles::ActiveSelectButton as u32) -} - -pub fn opening_double_click_function_big_files(tree_view: >k::TreeView, event: &gdk::EventButton) -> gtk::Inhibit { - if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 1 { - common_open_function(tree_view, ColumnsBigFiles::Name as i32, ColumnsBigFiles::Path as i32, OpenMode::PathAndName); - } else if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 3 { - common_open_function(tree_view, ColumnsBigFiles::Name as i32, ColumnsBigFiles::Path as i32, OpenMode::OnlyPath); - } - gtk::Inhibit(false) -} -pub fn opening_enter_function_big_files(tree_view: >k::TreeView, event: &gdk::EventKey) -> gtk::Inhibit { - handle_tree_keypress(tree_view, event, ColumnsBigFiles::Name as u32, ColumnsBigFiles::Path as u32, ColumnsBigFiles::ActiveSelectButton as u32) -} - -pub fn opening_double_click_function_same_music(tree_view: >k::TreeView, event: &gdk::EventButton) -> gtk::Inhibit { - if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 1 { - common_open_function(tree_view, ColumnsSameMusic::Name as i32, ColumnsSameMusic::Path as i32, OpenMode::PathAndName); - } else if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 3 { - common_open_function(tree_view, ColumnsSameMusic::Name as i32, ColumnsSameMusic::Path as i32, OpenMode::OnlyPath); - } - gtk::Inhibit(false) -} -pub fn opening_enter_function_same_music(tree_view: >k::TreeView, event: &gdk::EventKey) -> gtk::Inhibit { - handle_tree_keypress(tree_view, event, ColumnsSameMusic::Name as u32, ColumnsSameMusic::Path as u32, ColumnsSameMusic::ActiveSelectButton as u32) -} - -pub fn opening_double_click_function_similar_images(tree_view: >k::TreeView, event: &gdk::EventButton) -> gtk::Inhibit { - if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 1 { - common_open_function(tree_view, ColumnsSimilarImages::Name as i32, ColumnsSimilarImages::Path as i32, OpenMode::PathAndName); - } else if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 3 { - common_open_function(tree_view, ColumnsSimilarImages::Name as i32, ColumnsSimilarImages::Path as i32, OpenMode::OnlyPath); - } - gtk::Inhibit(false) -} - -pub fn opening_enter_function_similar_images(tree_view: >k::TreeView, event: &gdk::EventKey) -> gtk::Inhibit { - handle_tree_keypress(tree_view, event, ColumnsSimilarImages::Name as u32, ColumnsSimilarImages::Path as u32, ColumnsSimilarImages::ActiveSelectButton as u32) -} - -pub fn opening_double_click_function_similar_videos(tree_view: >k::TreeView, event: &gdk::EventButton) -> gtk::Inhibit { - if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 1 { - common_open_function(tree_view, ColumnsSimilarVideos::Name as i32, ColumnsSimilarVideos::Path as i32, OpenMode::PathAndName); - } else if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 3 { - common_open_function(tree_view, ColumnsSimilarVideos::Name as i32, ColumnsSimilarVideos::Path as i32, OpenMode::OnlyPath); - } - gtk::Inhibit(false) -} - -pub fn opening_enter_function_similar_videos(tree_view: >k::TreeView, event: &gdk::EventKey) -> gtk::Inhibit { - handle_tree_keypress(tree_view, event, ColumnsSimilarVideos::Name as u32, ColumnsSimilarVideos::Path as u32, ColumnsSimilarVideos::ActiveSelectButton as u32) -} - -pub fn opening_double_click_function_invalid_symlinks(tree_view: >k::TreeView, event: &gdk::EventButton) -> gtk::Inhibit { - if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 1 { - common_open_function(tree_view, ColumnsInvalidSymlinks::Name as i32, ColumnsInvalidSymlinks::Path as i32, OpenMode::PathAndName); - } else if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 3 { - common_open_function(tree_view, ColumnsInvalidSymlinks::Name as i32, ColumnsInvalidSymlinks::Path as i32, OpenMode::OnlyPath); - } - gtk::Inhibit(false) -} -pub fn opening_enter_function_invalid_symlinks(tree_view: >k::TreeView, event: &gdk::EventKey) -> gtk::Inhibit { - handle_tree_keypress(tree_view, event, ColumnsInvalidSymlinks::Name as u32, ColumnsInvalidSymlinks::Path as u32, ColumnsInvalidSymlinks::ActiveSelectButton as u32) -} - -pub fn opening_double_click_function_broken_files(tree_view: >k::TreeView, event: &gdk::EventButton) -> gtk::Inhibit { - if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 1 { - common_open_function(tree_view, ColumnsBrokenFiles::Name as i32, ColumnsBrokenFiles::Path as i32, OpenMode::PathAndName); - } else if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 3 { - common_open_function(tree_view, ColumnsBrokenFiles::Name as i32, ColumnsBrokenFiles::Path as i32, OpenMode::OnlyPath); - } - gtk::Inhibit(false) -} -pub fn opening_enter_function_broken_files(tree_view: >k::TreeView, event: &gdk::EventKey) -> gtk::Inhibit { - handle_tree_keypress(tree_view, event, ColumnsBrokenFiles::Name as u32, ColumnsBrokenFiles::Path as u32, ColumnsBrokenFiles::ActiveSelectButton as u32) -} - -enum OpenMode { - OnlyPath, - PathAndName, -} - -fn common_mark_function(tree_view: >k::TreeView, column_name: u32) { - let selection = tree_view.selection(); - let (selection_rows, tree_model) = selection.selected_rows(); - - let model = get_list_store(tree_view); - - for tree_path in selection_rows.iter().rev() { - let value = !tree_model.value(&tree_model.iter(tree_path).unwrap(), column_name as i32).get::().unwrap(); - model.set_value(&tree_model.iter(tree_path).unwrap(), column_name, &value.to_value()); - } -} - -fn common_open_function(tree_view: >k::TreeView, column_name: i32, column_path: i32, opening_mode: OpenMode) { - let selection = tree_view.selection(); - let (selection_rows, tree_model) = selection.selected_rows(); - - for tree_path in selection_rows.iter().rev() { - let end_path; - let name = tree_model.value(&tree_model.iter(tree_path).unwrap(), column_name).get::().unwrap(); - let path = tree_model.value(&tree_model.iter(tree_path).unwrap(), column_path).get::().unwrap(); - - match opening_mode { - OpenMode::OnlyPath => { - end_path = path; - } - OpenMode::PathAndName => { - end_path = format!("{}/{}", path, name); - } - } - - open::that_in_background(&end_path); - - // if let Err(e) = open::that(&end_path) { - // println!("Failed to open {} - Error {}", end_path, e); - // } - } -} - -fn handle_tree_keypress(tree_view: >k::TreeView, event: &gdk::EventKey, name_column: u32, path_column: u32, mark_column: u32) -> gtk::Inhibit { - match event.keycode() { - Some(KEY_ENTER) => { - // Enter - common_open_function(tree_view, name_column as i32, path_column as i32, OpenMode::PathAndName); - } - Some(KEY_SPACE) => { - // Space - common_mark_function(tree_view, mark_column); - } - _ => {} - } - gtk::Inhibit(false) -} diff --git a/czkawka_gui/src/gui_main_notebook.rs b/czkawka_gui/src/gui_main_notebook.rs index 80b3c66..8912ac4 100644 --- a/czkawka_gui/src/gui_main_notebook.rs +++ b/czkawka_gui/src/gui_main_notebook.rs @@ -1,3 +1,4 @@ +use crate::notebook_enums::NUMBER_OF_NOTEBOOK_MAIN_TABS; use gtk::prelude::*; use gtk::TreeView; @@ -217,4 +218,19 @@ impl GuiMainNotebook { image_preview_duplicates, } } + + pub fn get_main_tree_views(&self) -> [TreeView; NUMBER_OF_NOTEBOOK_MAIN_TABS] { + [ + self.tree_view_duplicate_finder.clone(), + self.tree_view_empty_folder_finder.clone(), + self.tree_view_big_files_finder.clone(), + self.tree_view_empty_files_finder.clone(), + self.tree_view_temporary_files_finder.clone(), + self.tree_view_similar_images_finder.clone(), + self.tree_view_similar_videos_finder.clone(), + self.tree_view_same_music_finder.clone(), + self.tree_view_invalid_symlinks.clone(), + self.tree_view_broken_files.clone(), + ] + } } diff --git a/czkawka_gui/src/help_functions.rs b/czkawka_gui/src/help_functions.rs index f4074d9..a0181c3 100644 --- a/czkawka_gui/src/help_functions.rs +++ b/czkawka_gui/src/help_functions.rs @@ -1,3 +1,4 @@ +use crate::notebook_enums::{NotebookMainEnum, NUMBER_OF_NOTEBOOK_MAIN_TABS}; use czkawka_core::big_file::BigFile; use czkawka_core::broken_files::BrokenFiles; use czkawka_core::common_messages::Messages; @@ -15,6 +16,163 @@ use gtk::{ListStore, TextView}; use std::collections::HashMap; use std::path::{Path, PathBuf}; +#[derive(Eq, PartialEq)] +pub enum PopoverTypes { + All, + ImageSize, + Reverse, + Custom, + Date, + None, +} + +pub struct NotebookObject { + pub notebook_type: NotebookMainEnum, + pub available_modes: [PopoverTypes; 4], + pub column_activatable_button: Option, + pub column_path: i32, + pub column_name: i32, + pub column_selection: i32, + pub column_color: Option, + pub column_dimensions: Option, + pub column_size: Option, + pub column_size_as_bytes: Option, + pub column_modification_as_secs: Option, +} + +pub static NOTEBOOKS_INFOS: [NotebookObject; NUMBER_OF_NOTEBOOK_MAIN_TABS] = [ + NotebookObject { + notebook_type: NotebookMainEnum::Duplicate, + available_modes: [PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::Date], + column_activatable_button: Some(ColumnsDuplicates::ActivatableSelectButton as i32), + column_path: ColumnsDuplicates::Path as i32, + column_name: ColumnsDuplicates::Name as i32, + column_selection: ColumnsDuplicates::SelectionButton as i32, + column_color: Some(ColumnsDuplicates::Color as i32), + column_dimensions: None, + column_size: None, + column_size_as_bytes: None, + column_modification_as_secs: Some(ColumnsDuplicates::ModificationAsSecs as i32), + }, + NotebookObject { + notebook_type: NotebookMainEnum::EmptyDirectories, + available_modes: [PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::None], + column_activatable_button: None, + column_path: ColumnsEmptyFolders::Path as i32, + column_name: ColumnsEmptyFolders::Name as i32, + column_selection: ColumnsEmptyFolders::SelectionButton as i32, + column_color: None, + column_dimensions: None, + column_size: None, + column_size_as_bytes: None, + column_modification_as_secs: None, + }, + NotebookObject { + notebook_type: NotebookMainEnum::BigFiles, + available_modes: [PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::None], + column_activatable_button: None, + column_path: ColumnsBigFiles::Path as i32, + column_name: ColumnsBigFiles::Name as i32, + column_selection: ColumnsBigFiles::SelectionButton as i32, + column_color: None, + column_dimensions: None, + column_size: None, + column_size_as_bytes: None, + column_modification_as_secs: None, + }, + NotebookObject { + notebook_type: NotebookMainEnum::EmptyFiles, + available_modes: [PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::None], + column_activatable_button: None, + column_path: ColumnsEmptyFiles::Path as i32, + column_name: ColumnsEmptyFiles::Name as i32, + column_selection: ColumnsEmptyFiles::SelectionButton as i32, + column_color: None, + column_dimensions: None, + column_size: None, + column_size_as_bytes: None, + column_modification_as_secs: None, + }, + NotebookObject { + notebook_type: NotebookMainEnum::Temporary, + available_modes: [PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::None], + column_activatable_button: None, + column_path: ColumnsTemporaryFiles::Path as i32, + column_name: ColumnsTemporaryFiles::Name as i32, + column_selection: ColumnsTemporaryFiles::SelectionButton as i32, + column_color: None, + column_dimensions: None, + column_size: None, + column_size_as_bytes: None, + column_modification_as_secs: None, + }, + NotebookObject { + notebook_type: NotebookMainEnum::SimilarImages, + available_modes: [PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::Date], + column_activatable_button: Some(ColumnsSimilarImages::ActivatableSelectButton as i32), + column_path: ColumnsSimilarImages::Path as i32, + column_name: ColumnsSimilarImages::Name as i32, + column_selection: ColumnsSimilarImages::SelectionButton as i32, + column_color: Some(ColumnsSimilarImages::Color as i32), + column_dimensions: Some(ColumnsSimilarImages::Dimensions as i32), + column_size: Some(ColumnsSimilarImages::Size as i32), + column_size_as_bytes: Some(ColumnsSimilarImages::SizeAsBytes as i32), + column_modification_as_secs: Some(ColumnsSimilarImages::ModificationAsSecs as i32), + }, + NotebookObject { + notebook_type: NotebookMainEnum::SimilarVideos, + available_modes: [PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::Date], + column_activatable_button: Some(ColumnsSimilarVideos::ActivatableSelectButton as i32), + column_path: ColumnsSimilarVideos::Path as i32, + column_name: ColumnsSimilarVideos::Name as i32, + column_selection: ColumnsSimilarVideos::SelectionButton as i32, + column_color: Some(ColumnsSimilarVideos::Color as i32), + column_dimensions: None, + column_size: Some(ColumnsSimilarVideos::Size as i32), + column_size_as_bytes: Some(ColumnsSimilarVideos::SizeAsBytes as i32), + column_modification_as_secs: Some(ColumnsSimilarVideos::ModificationAsSecs as i32), + }, + NotebookObject { + notebook_type: NotebookMainEnum::SameMusic, + available_modes: [PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::Date], + column_activatable_button: Some(ColumnsSameMusic::ActivatableSelectButton as i32), + column_path: ColumnsSameMusic::Path as i32, + column_name: ColumnsSameMusic::Name as i32, + column_selection: ColumnsSameMusic::SelectionButton as i32, + column_color: Some(ColumnsSameMusic::Color as i32), + column_dimensions: None, + column_size: None, + column_size_as_bytes: Some(ColumnsSameMusic::SizeAsBytes as i32), + column_modification_as_secs: Some(ColumnsSameMusic::ModificationAsSecs as i32), + }, + NotebookObject { + notebook_type: NotebookMainEnum::Symlinks, + available_modes: [PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::None], + column_activatable_button: None, + column_path: ColumnsInvalidSymlinks::Path as i32, + column_name: ColumnsInvalidSymlinks::Name as i32, + column_selection: ColumnsInvalidSymlinks::SelectionButton as i32, + column_color: None, + column_dimensions: None, + column_size: None, + column_size_as_bytes: None, + column_modification_as_secs: None, + }, + NotebookObject { + notebook_type: NotebookMainEnum::BrokenFiles, + available_modes: [PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::None], + column_activatable_button: None, + column_path: ColumnsBrokenFiles::Path as i32, + column_name: ColumnsBrokenFiles::Name as i32, + column_selection: ColumnsBrokenFiles::SelectionButton as i32, + column_color: None, + column_dimensions: None, + column_size: None, + column_size_as_bytes: None, + column_modification_as_secs: None, + }, +]; + pub enum Message { Duplicates(DuplicateFinder), EmptyFolders(EmptyFolder), @@ -28,11 +186,10 @@ pub enum Message { BrokenFiles(BrokenFiles), } -#[derive(Debug)] pub enum ColumnsDuplicates { // Columns for duplicate treeview ActivatableSelectButton = 0, - ActiveSelectButton, + SelectionButton, Name, Path, Modification, @@ -43,7 +200,7 @@ pub enum ColumnsDuplicates { pub enum ColumnsEmptyFolders { // Columns for empty folder treeview - ActiveSelectButton = 0, + SelectionButton = 0, Name, Path, Modification, @@ -53,27 +210,27 @@ pub enum ColumnsDirectory { Path = 0, } pub enum ColumnsBigFiles { - ActiveSelectButton = 0, + SelectionButton = 0, Size, Name, Path, Modification, } pub enum ColumnsEmptyFiles { - ActiveSelectButton = 0, + SelectionButton = 0, Name, Path, Modification, } pub enum ColumnsTemporaryFiles { - ActiveSelectButton = 0, + SelectionButton = 0, Name, Path, Modification, } pub enum ColumnsSimilarImages { ActivatableSelectButton = 0, - ActiveSelectButton, + SelectionButton, Similarity, Size, SizeAsBytes, @@ -88,7 +245,7 @@ pub enum ColumnsSimilarImages { pub enum ColumnsSimilarVideos { ActivatableSelectButton = 0, - ActiveSelectButton, + SelectionButton, Size, SizeAsBytes, Name, @@ -100,7 +257,7 @@ pub enum ColumnsSimilarVideos { } pub enum ColumnsSameMusic { ActivatableSelectButton = 0, - ActiveSelectButton, + SelectionButton, Size, SizeAsBytes, Name, @@ -116,7 +273,7 @@ pub enum ColumnsSameMusic { TextColor, } pub enum ColumnsInvalidSymlinks { - ActiveSelectButton = 0, + SelectionButton = 0, Name, Path, DestinationPath, @@ -125,7 +282,7 @@ pub enum ColumnsInvalidSymlinks { } pub enum ColumnsBrokenFiles { - ActiveSelectButton = 0, + SelectionButton = 0, Name, Path, ErrorType, @@ -217,46 +374,6 @@ pub fn add_text_to_text_view(text_view: &TextView, string_to_append: &str) { buffer.set_text(format!("{}\n{}", current_text, string_to_append).as_str()); } -pub fn select_function_duplicates(_tree_selection: >k::TreeSelection, tree_model: >k::TreeModel, tree_path: >k::TreePath, _is_path_currently_selected: bool) -> bool { - // let name = tree_model.value(&tree_model.iter(tree_path).unwrap(),ColumnsDuplicates::Name as i32).get::().unwrap(); - // let path = tree_model.value(&tree_model.iter(tree_path).unwrap(), ColumnsDuplicates::Path as i32).get::().unwrap(); - // let modification = tree_model.value(&tree_model.iter(tree_path).unwrap(),ColumnsDuplicates::Modification as i32).get::().unwrap(); - let color = tree_model.value(&tree_model.iter(tree_path).unwrap(), ColumnsDuplicates::Color as i32).get::().unwrap(); - - if color == HEADER_ROW_COLOR { - return false; - } - - true -} -pub fn select_function_same_music(_tree_selection: >k::TreeSelection, tree_model: >k::TreeModel, tree_path: >k::TreePath, _is_path_currently_selected: bool) -> bool { - let color = tree_model.value(&tree_model.iter(tree_path).unwrap(), ColumnsSameMusic::Color as i32).get::().unwrap(); - - if color == HEADER_ROW_COLOR { - return false; - } - - true -} -pub fn select_function_similar_images(_tree_selection: >k::TreeSelection, tree_model: >k::TreeModel, tree_path: >k::TreePath, _is_path_currently_selected: bool) -> bool { - let color = tree_model.value(&tree_model.iter(tree_path).unwrap(), ColumnsSimilarImages::Color as i32).get::().unwrap(); - - if color == HEADER_ROW_COLOR { - return false; - } - - true -} -pub fn select_function_similar_videos(_tree_selection: >k::TreeSelection, tree_model: >k::TreeModel, tree_path: >k::TreePath, _is_path_currently_selected: bool) -> bool { - let color = tree_model.value(&tree_model.iter(tree_path).unwrap(), ColumnsSimilarVideos::Color as i32).get::().unwrap(); - - if color == HEADER_ROW_COLOR { - return false; - } - - true -} - pub fn set_buttons(hashmap: &mut HashMap, buttons_array: &[gtk::Button], button_names: &[String]) { for (index, button) in buttons_array.iter().enumerate() { if *hashmap.get_mut(button_names[index].as_str()).unwrap() { @@ -294,3 +411,96 @@ pub fn change_dimension_to_krotka(dimensions: String) -> (u64, u64) { let number2 = vec[1].parse::().expect("Invalid data in image dimension in position 1"); (number1, number2) } + +pub fn get_notebook_enum_from_tree_view(tree_view: >k::TreeView) -> NotebookMainEnum { + match (*tree_view).widget_name().to_string().as_str() { + "tree_view_duplicate_finder" => NotebookMainEnum::Duplicate, + "tree_view_empty_folder_finder" => NotebookMainEnum::EmptyDirectories, + "tree_view_empty_files_finder" => NotebookMainEnum::EmptyFiles, + "tree_view_temporary_files_finder" => NotebookMainEnum::Temporary, + "tree_view_big_files_finder" => NotebookMainEnum::BigFiles, + "tree_view_similar_images_finder" => NotebookMainEnum::SimilarImages, + "tree_view_similar_videos_finder" => NotebookMainEnum::SimilarVideos, + "tree_view_same_music_finder" => NotebookMainEnum::SameMusic, + "tree_view_invalid_symlinks" => NotebookMainEnum::Symlinks, + "tree_view_broken_files" => NotebookMainEnum::BrokenFiles, + _ => panic!(), + } +} + +pub fn get_notebook_object_from_tree_view(tree_view: >k::TreeView) -> &NotebookObject { + let nb_enum = get_notebook_enum_from_tree_view(tree_view); + &NOTEBOOKS_INFOS[nb_enum as usize] +} + +// After e.g. deleting files, header may become orphan or have one child, so should be deleted in this case +pub fn clean_invalid_headers(model: >k::ListStore, column_color: i32) { + // Remove only child from header + if let Some(first_iter) = model.iter_first() { + let mut vec_tree_path_to_delete: Vec = Vec::new(); + let mut current_iter = first_iter; + if model.value(¤t_iter, column_color).get::().unwrap() != HEADER_ROW_COLOR { + panic!("First deleted element, should be a header"); // First element should be header + }; + + let mut next_iter; + let mut next_next_iter; + 'main: loop { + if model.value(¤t_iter, column_color).get::().unwrap() != HEADER_ROW_COLOR { + panic!("First deleted element, should be a header"); // First element should be header + }; + + next_iter = current_iter.clone(); + if !model.iter_next(&next_iter) { + // There is only single header left (H1 -> END) -> (NOTHING) + vec_tree_path_to_delete.push(model.path(¤t_iter).unwrap()); + break 'main; + } + + if model.value(&next_iter, column_color).get::().unwrap() == HEADER_ROW_COLOR { + // There are two headers each others(we remove just first) -> (H1 -> H2) -> (H2) + vec_tree_path_to_delete.push(model.path(¤t_iter).unwrap()); + current_iter = next_iter.clone(); + continue 'main; + } + + next_next_iter = next_iter.clone(); + if !model.iter_next(&next_next_iter) { + // There is only one child of header left, so we remove it with header (H1 -> C1 -> END) -> (NOTHING) + vec_tree_path_to_delete.push(model.path(¤t_iter).unwrap()); + vec_tree_path_to_delete.push(model.path(&next_iter).unwrap()); + break 'main; + } + + if model.value(&next_next_iter, column_color).get::().unwrap() == HEADER_ROW_COLOR { + // One child between two headers, we can remove them (H1 -> C1 -> H2) -> (H2) + vec_tree_path_to_delete.push(model.path(¤t_iter).unwrap()); + vec_tree_path_to_delete.push(model.path(&next_iter).unwrap()); + current_iter = next_next_iter.clone(); + continue 'main; + } + + loop { + // (H1 -> C1 -> C2 -> Cn -> END) -> (NO CHANGE, BECAUSE IS GOOD) + if !model.iter_next(&next_next_iter) { + break 'main; + } + // Move to next header + if model.value(&next_next_iter, column_color).get::().unwrap() == HEADER_ROW_COLOR { + current_iter = next_next_iter.clone(); + continue 'main; + } + } + } + for tree_path in vec_tree_path_to_delete.iter().rev() { + model.remove(&model.iter(tree_path).unwrap()); + } + } + + // Last step, remove orphan header if exists + if let Some(iter) = model.iter_first() { + if !model.iter_next(&iter) { + model.clear(); + } + } +} diff --git a/czkawka_gui/src/initialize_gui.rs b/czkawka_gui/src/initialize_gui.rs index e6959b5..9c85192 100644 --- a/czkawka_gui/src/initialize_gui.rs +++ b/czkawka_gui/src/initialize_gui.rs @@ -1,8 +1,9 @@ use crate::connect_button_delete::{basic_remove, check_if_can_delete_files, check_if_deleting_all_files_in_group, empty_folder_remover, tree_remove}; use crate::create_tree_view::*; -use crate::double_click_opening::*; use crate::gui_data::*; use crate::help_functions::*; +use crate::notebook_enums::NotebookMainEnum; +use crate::opening_selecting_records::*; use czkawka_core::similar_images::SIMILAR_VALUES; use czkawka_core::similar_videos::MAX_TOLERANCE; use directories_next::ProjectDirs; @@ -14,6 +15,8 @@ use std::cmp::Ordering; use std::fs; use std::path::Path; +const KEY_DELETE: u16 = 119; + pub fn initialize_gui(gui_data: &mut GuiData) { //// Initialize button { @@ -99,55 +102,57 @@ pub fn initialize_gui(gui_data: &mut GuiData) { create_tree_view_duplicates(&mut tree_view); - tree_view.connect_button_press_event(opening_double_click_function_duplicates); - tree_view.connect_key_press_event(opening_enter_function_duplicates); + tree_view.connect_button_press_event(opening_double_click_function); + tree_view.connect_key_press_event(opening_enter_function); tree_view.connect_button_release_event(move |tree_view, _event| { + let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::Duplicate as usize]; show_preview( tree_view, &text_view_errors_cloned, &check_button_settings_show_preview_duplicates_cloned, &image_preview_duplicates_cloned, - ColumnsDuplicates::Path as i32, - ColumnsDuplicates::Name as i32, + nb_object.column_path, + nb_object.column_name, ); gtk::Inhibit(false) }); + tree_view.set_widget_name("tree_view_duplicate_finder"); gui_data.main_notebook.tree_view_duplicate_finder = tree_view.clone(); scrolled_window_duplicate_finder.add(&tree_view); scrolled_window_duplicate_finder.show_all(); let text_view_errors_cloned = text_view_errors.clone(); - let gui_data = gui_data.clone(); + let check_button_settings_confirm_group_deletion = gui_data.settings.check_button_settings_confirm_group_deletion.clone(); + let check_button_settings_confirm_deletion = gui_data.settings.check_button_settings_confirm_deletion.clone(); + let window_main = gui_data.window_main.clone(); + + let check_button_settings_use_trash = gui_data.settings.check_button_settings_use_trash.clone(); tree_view.connect_key_release_event(move |tree_view, e| { + let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::Duplicate as usize]; if let Some(button_number) = e.keycode() { // Handle delete button - if button_number == 119 { + if button_number == KEY_DELETE { if tree_view.selection().selected_rows().0.is_empty() { return gtk::Inhibit(false); } - if !check_if_can_delete_files(&gui_data.settings.check_button_settings_confirm_deletion, &gui_data.window_main) { + if !check_if_can_delete_files(&check_button_settings_confirm_deletion, &window_main) { return gtk::Inhibit(false); } - if gui_data.settings.check_button_settings_confirm_group_deletion.is_active() - && check_if_deleting_all_files_in_group( - &tree_view.clone(), - ColumnsDuplicates::Color as i32, - ColumnsDuplicates::ActiveSelectButton as i32, - &gui_data.window_main, - &gui_data.settings.check_button_settings_confirm_group_deletion, - ) + if check_button_settings_confirm_group_deletion.is_active() + && check_if_deleting_all_files_in_group(&tree_view.clone(), nb_object.column_color.unwrap(), nb_object.column_selection, &window_main, &check_button_settings_confirm_group_deletion) { return gtk::Inhibit(false); } tree_remove( tree_view, - ColumnsDuplicates::Name as i32, - ColumnsDuplicates::Path as i32, - ColumnsDuplicates::Color as i32, - ColumnsDuplicates::ActiveSelectButton as i32, - &gui_data, + nb_object.column_name, + nb_object.column_path, + nb_object.column_color.unwrap(), + nb_object.column_selection, + &check_button_settings_use_trash, + &text_view_errors, ); image_preview_duplicates.hide(); } @@ -157,8 +162,8 @@ pub fn initialize_gui(gui_data: &mut GuiData) { &text_view_errors_cloned, &check_button_settings_show_preview_duplicates, &image_preview_duplicates, - ColumnsDuplicates::Path as i32, - ColumnsDuplicates::Name as i32, + nb_object.column_path, + nb_object.column_name, ); gtk::Inhibit(false) }); @@ -174,19 +179,22 @@ pub fn initialize_gui(gui_data: &mut GuiData) { create_tree_view_empty_folders(&mut tree_view); - tree_view.connect_button_press_event(opening_double_click_function_empty_folders); - tree_view.connect_key_press_event(opening_enter_function_empty_folders); + tree_view.connect_button_press_event(opening_double_click_function); + tree_view.connect_key_press_event(opening_enter_function); + tree_view.set_widget_name("tree_view_empty_folder_finder"); gui_data.main_notebook.tree_view_empty_folder_finder = tree_view.clone(); scrolled_window_empty_folder_finder.add(&tree_view); scrolled_window_empty_folder_finder.show_all(); - let gui_data = gui_data.clone(); + let check_button_settings_use_trash = gui_data.settings.check_button_settings_use_trash.clone(); + let text_view_errors = gui_data.text_view_errors.clone(); tree_view.connect_key_release_event(move |tree_view, e| { if let Some(button_number) = e.keycode() { // Handle delete button - if button_number == 119 { - empty_folder_remover(tree_view, ColumnsEmptyFolders::Name as i32, ColumnsEmptyFolders::Path as i32, ColumnsEmptyFolders::ActiveSelectButton as i32, &gui_data); + if button_number == KEY_DELETE { + let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::EmptyDirectories as usize]; + empty_folder_remover(tree_view, nb_object.column_name, nb_object.column_path, nb_object.column_selection, &check_button_settings_use_trash, &text_view_errors); } } gtk::Inhibit(false) @@ -203,19 +211,22 @@ pub fn initialize_gui(gui_data: &mut GuiData) { create_tree_view_empty_files(&mut tree_view); - tree_view.connect_button_press_event(opening_double_click_function_empty_files); - tree_view.connect_key_press_event(opening_enter_function_empty_files); + tree_view.connect_button_press_event(opening_double_click_function); + tree_view.connect_key_press_event(opening_enter_function); + tree_view.set_widget_name("tree_view_empty_files_finder"); gui_data.main_notebook.tree_view_empty_files_finder = tree_view.clone(); scrolled_window_empty_files_finder.add(&tree_view); scrolled_window_empty_files_finder.show_all(); - let gui_data = gui_data.clone(); + let check_button_settings_use_trash = gui_data.settings.check_button_settings_use_trash.clone(); + let text_view_errors = gui_data.text_view_errors.clone(); tree_view.connect_key_release_event(move |tree_view, e| { if let Some(button_number) = e.keycode() { // Handle delete button - if button_number == 119 { - basic_remove(tree_view, ColumnsEmptyFiles::Name as i32, ColumnsEmptyFiles::Path as i32, ColumnsEmptyFiles::ActiveSelectButton as i32, &gui_data); + if button_number == KEY_DELETE { + let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::EmptyFiles as usize]; + basic_remove(tree_view, nb_object.column_name, nb_object.column_path, nb_object.column_selection, &check_button_settings_use_trash, &text_view_errors); } } gtk::Inhibit(false) @@ -232,19 +243,22 @@ pub fn initialize_gui(gui_data: &mut GuiData) { create_tree_view_temporary_files(&mut tree_view); - tree_view.connect_button_press_event(opening_double_click_function_temporary_files); - tree_view.connect_key_press_event(opening_enter_function_temporary_files); + tree_view.connect_button_press_event(opening_double_click_function); + tree_view.connect_key_press_event(opening_enter_function); + tree_view.set_widget_name("tree_view_temporary_files_finder"); gui_data.main_notebook.tree_view_temporary_files_finder = tree_view.clone(); scrolled_window_temporary_files_finder.add(&tree_view); scrolled_window_temporary_files_finder.show_all(); - let gui_data = gui_data.clone(); + let check_button_settings_use_trash = gui_data.settings.check_button_settings_use_trash.clone(); + let text_view_errors = gui_data.text_view_errors.clone(); tree_view.connect_key_release_event(move |tree_view, e| { if let Some(button_number) = e.keycode() { // Handle delete button - if button_number == 119 { - basic_remove(tree_view, ColumnsTemporaryFiles::Name as i32, ColumnsTemporaryFiles::Path as i32, ColumnsTemporaryFiles::ActiveSelectButton as i32, &gui_data); + if button_number == KEY_DELETE { + let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::Temporary as usize]; + basic_remove(tree_view, nb_object.column_name, nb_object.column_path, nb_object.column_selection, &check_button_settings_use_trash, &text_view_errors); } } gtk::Inhibit(false) @@ -261,19 +275,22 @@ pub fn initialize_gui(gui_data: &mut GuiData) { create_tree_view_big_files(&mut tree_view); - tree_view.connect_button_press_event(opening_double_click_function_big_files); - tree_view.connect_key_press_event(opening_enter_function_big_files); + tree_view.connect_button_press_event(opening_double_click_function); + tree_view.connect_key_press_event(opening_enter_function); + tree_view.set_widget_name("tree_view_big_files_finder"); gui_data.main_notebook.tree_view_big_files_finder = tree_view.clone(); scrolled_window_big_files_finder.add(&tree_view); scrolled_window_big_files_finder.show_all(); - let gui_data = gui_data.clone(); + let check_button_settings_use_trash = gui_data.settings.check_button_settings_use_trash.clone(); + let text_view_errors = gui_data.text_view_errors.clone(); tree_view.connect_key_release_event(move |tree_view, e| { if let Some(button_number) = e.keycode() { // Handle delete button - if button_number == 119 { - basic_remove(tree_view, ColumnsBigFiles::Name as i32, ColumnsBigFiles::Path as i32, ColumnsBigFiles::ActiveSelectButton as i32, &gui_data); + if button_number == KEY_DELETE { + let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::BigFiles as usize]; + basic_remove(tree_view, nb_object.column_name, nb_object.column_path, nb_object.column_selection, &check_button_settings_use_trash, &text_view_errors); } } gtk::Inhibit(false) @@ -307,56 +324,58 @@ pub fn initialize_gui(gui_data: &mut GuiData) { create_tree_view_similar_images(&mut tree_view); - tree_view.connect_button_press_event(opening_double_click_function_similar_images); - tree_view.connect_key_press_event(opening_enter_function_similar_images); + tree_view.connect_button_press_event(opening_double_click_function); + tree_view.connect_key_press_event(opening_enter_function); + let text_view_errors = gui_data.text_view_errors.clone(); tree_view.connect_button_release_event(move |tree_view, _event| { + let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::SimilarImages as usize]; show_preview( tree_view, &text_view_errors, &check_button_settings_show_preview_similar_images, &image_preview_similar_images, - ColumnsSimilarImages::Path as i32, - ColumnsSimilarImages::Name as i32, + nb_object.column_path, + nb_object.column_name, ); gtk::Inhibit(false) }); + tree_view.set_widget_name("tree_view_similar_images_finder"); gui_data.main_notebook.tree_view_similar_images_finder = tree_view.clone(); scrolled_window_similar_images_finder.add(&tree_view); scrolled_window_similar_images_finder.show_all(); let image_preview_similar_images = image_preview_similar_images_clone.clone(); - let text_view_errors = gui_data.text_view_errors.clone(); let check_button_settings_show_preview_similar_images = gui_data.settings.check_button_settings_show_preview_similar_images.clone(); - let gui_data = gui_data.clone(); + let check_button_settings_confirm_group_deletion = gui_data.settings.check_button_settings_confirm_group_deletion.clone(); + let check_button_settings_confirm_deletion = gui_data.settings.check_button_settings_confirm_deletion.clone(); + let window_main = gui_data.window_main.clone(); + let check_button_settings_use_trash = gui_data.settings.check_button_settings_use_trash.clone(); + let text_view_errors = gui_data.text_view_errors.clone(); tree_view.connect_key_release_event(move |tree_view, e| { + let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::SimilarImages as usize]; if let Some(button_number) = e.keycode() { // Handle delete button - if button_number == 119 { + if button_number == KEY_DELETE { if tree_view.selection().selected_rows().0.is_empty() { return gtk::Inhibit(false); } - if !check_if_can_delete_files(&gui_data.settings.check_button_settings_confirm_deletion, &gui_data.window_main) { + if !check_if_can_delete_files(&check_button_settings_confirm_deletion, &window_main) { return gtk::Inhibit(false); } - if gui_data.settings.check_button_settings_confirm_group_deletion.is_active() - && check_if_deleting_all_files_in_group( - &tree_view.clone(), - ColumnsSimilarImages::Color as i32, - ColumnsSimilarImages::ActiveSelectButton as i32, - &gui_data.window_main, - &gui_data.settings.check_button_settings_confirm_group_deletion, - ) + if check_button_settings_confirm_group_deletion.is_active() + && check_if_deleting_all_files_in_group(&tree_view.clone(), nb_object.column_color.unwrap(), nb_object.column_selection, &window_main, &check_button_settings_confirm_group_deletion) { return gtk::Inhibit(false); } tree_remove( tree_view, - ColumnsSimilarImages::Name as i32, - ColumnsSimilarImages::Path as i32, - ColumnsSimilarImages::Color as i32, - ColumnsSimilarImages::ActiveSelectButton as i32, - &gui_data, + nb_object.column_name, + nb_object.column_path, + nb_object.column_color.unwrap(), + nb_object.column_selection, + &check_button_settings_use_trash, + &text_view_errors, ); image_preview_similar_images_clone.hide(); } @@ -366,8 +385,8 @@ pub fn initialize_gui(gui_data: &mut GuiData) { &text_view_errors, &check_button_settings_show_preview_similar_images, &image_preview_similar_images, - ColumnsSimilarImages::Path as i32, - ColumnsSimilarImages::Name as i32, + nb_object.column_path, + nb_object.column_name, ); gtk::Inhibit(false) }); @@ -376,7 +395,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) { { let col_types: [glib::types::Type; 10] = [ glib::types::Type::BOOL, // ActivatableSelectButton - glib::types::Type::BOOL, // ActiveSelectButton + glib::types::Type::BOOL, // SelectionButton glib::types::Type::STRING, // Size glib::types::Type::U64, // SizeAsBytes glib::types::Type::STRING, // Name @@ -395,42 +414,43 @@ pub fn initialize_gui(gui_data: &mut GuiData) { create_tree_view_similar_videos(&mut tree_view); - tree_view.connect_button_press_event(opening_double_click_function_similar_videos); - tree_view.connect_key_press_event(opening_enter_function_similar_videos); + tree_view.connect_button_press_event(opening_double_click_function); + tree_view.connect_key_press_event(opening_enter_function); + tree_view.set_widget_name("tree_view_similar_videos_finder"); gui_data.main_notebook.tree_view_similar_videos_finder = tree_view.clone(); scrolled_window_similar_videos_finder.add(&tree_view); scrolled_window_similar_videos_finder.show_all(); - let gui_data = gui_data.clone(); + let check_button_settings_confirm_deletion = gui_data.settings.check_button_settings_confirm_deletion.clone(); + let check_button_settings_confirm_group_deletion = gui_data.settings.check_button_settings_confirm_group_deletion.clone(); + let window_main = gui_data.window_main.clone(); + let check_button_settings_use_trash = gui_data.settings.check_button_settings_use_trash.clone(); + let text_view_errors = gui_data.text_view_errors.clone(); tree_view.connect_key_release_event(move |tree_view, e| { if let Some(button_number) = e.keycode() { // Handle delete button - if button_number == 119 { + if button_number == KEY_DELETE { + let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::SimilarVideos as usize]; if tree_view.selection().selected_rows().0.is_empty() { return gtk::Inhibit(false); } - if !check_if_can_delete_files(&gui_data.settings.check_button_settings_confirm_deletion, &gui_data.window_main) { + if !check_if_can_delete_files(&check_button_settings_confirm_deletion, &window_main) { return gtk::Inhibit(false); } - if gui_data.settings.check_button_settings_confirm_group_deletion.is_active() - && check_if_deleting_all_files_in_group( - &tree_view.clone(), - ColumnsSimilarVideos::Color as i32, - ColumnsSimilarVideos::ActiveSelectButton as i32, - &gui_data.window_main, - &gui_data.settings.check_button_settings_confirm_group_deletion, - ) + if check_button_settings_confirm_group_deletion.is_active() + && check_if_deleting_all_files_in_group(&tree_view.clone(), nb_object.column_color.unwrap(), nb_object.column_selection, &window_main, &check_button_settings_confirm_group_deletion) { return gtk::Inhibit(false); } tree_remove( tree_view, - ColumnsSimilarVideos::Name as i32, - ColumnsSimilarVideos::Path as i32, - ColumnsSimilarVideos::Color as i32, - ColumnsSimilarVideos::ActiveSelectButton as i32, - &gui_data, + nb_object.column_name, + nb_object.column_path, + nb_object.column_color.unwrap(), + nb_object.column_selection, + &check_button_settings_use_trash, + &text_view_errors, ); } } @@ -465,42 +485,43 @@ pub fn initialize_gui(gui_data: &mut GuiData) { create_tree_view_same_music(&mut tree_view); tree_view.selection().set_select_function(Some(Box::new(select_function_same_music))); - tree_view.connect_button_press_event(opening_double_click_function_same_music); - tree_view.connect_key_press_event(opening_enter_function_same_music); + tree_view.connect_button_press_event(opening_double_click_function); + tree_view.connect_key_press_event(opening_enter_function); + tree_view.set_widget_name("tree_view_same_music_finder"); gui_data.main_notebook.tree_view_same_music_finder = tree_view.clone(); scrolled_window_same_music_finder.add(&tree_view); scrolled_window_same_music_finder.show_all(); - let gui_data = gui_data.clone(); + let check_button_settings_confirm_group_deletion = gui_data.settings.check_button_settings_confirm_group_deletion.clone(); + let window_main = gui_data.window_main.clone(); + let check_button_settings_use_trash = gui_data.settings.check_button_settings_use_trash.clone(); + let text_view_errors = gui_data.text_view_errors.clone(); tree_view.connect_key_release_event(move |tree_view, e| { if let Some(button_number) = e.keycode() { // Handle delete button - if button_number == 119 { + if button_number == KEY_DELETE { + let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::SameMusic as usize]; + if tree_view.selection().selected_rows().0.is_empty() { return gtk::Inhibit(false); } - if !check_if_can_delete_files(&gui_data.settings.check_button_settings_confirm_deletion, &gui_data.window_main) { + if !check_if_can_delete_files(&check_button_settings_confirm_group_deletion, &window_main) { return gtk::Inhibit(false); } - if gui_data.settings.check_button_settings_confirm_group_deletion.is_active() - && check_if_deleting_all_files_in_group( - &tree_view.clone(), - ColumnsSameMusic::Color as i32, - ColumnsSameMusic::ActiveSelectButton as i32, - &gui_data.window_main, - &gui_data.settings.check_button_settings_confirm_group_deletion, - ) + if check_button_settings_confirm_group_deletion.is_active() + && check_if_deleting_all_files_in_group(&tree_view.clone(), nb_object.column_color.unwrap(), nb_object.column_selection, &window_main, &check_button_settings_confirm_group_deletion) { return gtk::Inhibit(false); } tree_remove( tree_view, - ColumnsSameMusic::Name as i32, - ColumnsSameMusic::Path as i32, - ColumnsSameMusic::Color as i32, - ColumnsSameMusic::ActiveSelectButton as i32, - &gui_data, + nb_object.column_name, + nb_object.column_path, + nb_object.column_color.unwrap(), + nb_object.column_selection, + &check_button_settings_use_trash, + &text_view_errors, ); } } @@ -525,19 +546,22 @@ pub fn initialize_gui(gui_data: &mut GuiData) { create_tree_view_invalid_symlinks(&mut tree_view); - tree_view.connect_button_press_event(opening_double_click_function_invalid_symlinks); - tree_view.connect_key_press_event(opening_enter_function_invalid_symlinks); + tree_view.connect_button_press_event(opening_double_click_function); + tree_view.connect_key_press_event(opening_enter_function); + tree_view.set_widget_name("tree_view_invalid_symlinks"); gui_data.main_notebook.tree_view_invalid_symlinks = tree_view.clone(); scrolled_window_invalid_symlinks.add(&tree_view); scrolled_window_invalid_symlinks.show_all(); - let gui_data = gui_data.clone(); + let check_button_settings_use_trash = gui_data.settings.check_button_settings_use_trash.clone(); + let text_view_errors = gui_data.text_view_errors.clone(); tree_view.connect_key_release_event(move |tree_view, e| { if let Some(button_number) = e.keycode() { // Handle delete button - if button_number == 119 { - basic_remove(tree_view, ColumnsInvalidSymlinks::Name as i32, ColumnsInvalidSymlinks::Path as i32, ColumnsInvalidSymlinks::ActiveSelectButton as i32, &gui_data); + if button_number == KEY_DELETE { + let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::Symlinks as usize]; + basic_remove(tree_view, nb_object.column_name, nb_object.column_path, nb_object.column_selection, &check_button_settings_use_trash, &text_view_errors); } } gtk::Inhibit(false) @@ -554,19 +578,22 @@ pub fn initialize_gui(gui_data: &mut GuiData) { create_tree_view_broken_files(&mut tree_view); - tree_view.connect_button_press_event(opening_double_click_function_broken_files); - tree_view.connect_key_press_event(opening_enter_function_broken_files); + tree_view.connect_button_press_event(opening_double_click_function); + tree_view.connect_key_press_event(opening_enter_function); + tree_view.set_widget_name("tree_view_broken_files"); gui_data.main_notebook.tree_view_broken_files = tree_view.clone(); scrolled_window_broken_files.add(&tree_view); scrolled_window_broken_files.show_all(); - let gui_data = gui_data.clone(); + let check_button_settings_use_trash = gui_data.settings.check_button_settings_use_trash.clone(); + let text_view_errors = gui_data.text_view_errors.clone(); tree_view.connect_key_release_event(move |tree_view, e| { if let Some(button_number) = e.keycode() { // Handle delete button - if button_number == 119 { - basic_remove(tree_view, ColumnsBrokenFiles::Name as i32, ColumnsBrokenFiles::Path as i32, ColumnsBrokenFiles::ActiveSelectButton as i32, &gui_data); + if button_number == KEY_DELETE { + let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::BrokenFiles as usize]; + basic_remove(tree_view, nb_object.column_name, nb_object.column_path, nb_object.column_selection, &check_button_settings_use_trash, &text_view_errors); } } gtk::Inhibit(false) @@ -598,7 +625,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) { tree_view.connect_key_release_event(move |tree_view, e| { if let Some(button_number) = e.keycode() { // Handle delete button - if button_number == 119 { + if button_number == KEY_DELETE { let list_store = get_list_store(tree_view); let selection = tree_view.selection(); @@ -630,7 +657,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) { tree_view.connect_key_release_event(move |tree_view, e| { if let Some(button_number) = e.keycode() { // Handle delete button - if button_number == 119 { + if button_number == KEY_DELETE { let list_store = get_list_store(tree_view); let selection = tree_view.selection(); @@ -659,6 +686,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) { }); } } + fn show_preview(tree_view: &TreeView, text_view_errors: &TextView, check_button_settings_show_preview: &CheckButton, image_preview_similar_images: &Image, column_path: i32, column_name: i32) { let (selected_rows, tree_model) = tree_view.selection().selected_rows(); diff --git a/czkawka_gui/src/main.rs b/czkawka_gui/src/main.rs index edce87e..2b613d4 100644 --- a/czkawka_gui/src/main.rs +++ b/czkawka_gui/src/main.rs @@ -1,7 +1,9 @@ // Remove console window in Windows OS #![windows_subsystem = "windows"] #![allow(clippy::collapsible_else_if)] +#![allow(clippy::too_many_arguments)] +mod compute_results; mod connect_about_buttons; mod connect_button_delete; mod connect_button_hardlink; @@ -10,8 +12,6 @@ mod connect_button_save; mod connect_button_search; mod connect_button_select; mod connect_button_stop; -mod connect_button_symlink; -mod connect_compute_results; mod connect_header_buttons; mod connect_hide_text_view_errors; mod connect_notebook_tabs; @@ -21,7 +21,6 @@ mod connect_selection_of_directories; mod connect_settings; mod connect_similar_image_size_change; mod create_tree_view; -mod double_click_opening; mod gui_about; mod gui_bottom_buttons; mod gui_data; @@ -34,15 +33,18 @@ mod gui_upper_notepad; mod help_functions; mod initialize_gui; mod notebook_enums; +mod opening_selecting_records; mod saving_loading; mod taskbar_progress; #[cfg(not(target_os = "windows"))] mod taskbar_progress_dummy; #[cfg(target_os = "windows")] mod taskbar_progress_win; +mod tests; use czkawka_core::*; +use crate::compute_results::*; use crate::connect_about_buttons::*; use crate::connect_button_delete::*; use crate::connect_button_hardlink::*; @@ -51,8 +53,6 @@ use crate::connect_button_save::*; use crate::connect_button_search::*; use crate::connect_button_select::*; use crate::connect_button_stop::*; -use crate::connect_button_symlink::*; -use crate::connect_compute_results::*; use crate::connect_header_buttons::*; use crate::connect_hide_text_view_errors::*; use crate::connect_notebook_tabs::*; @@ -64,6 +64,7 @@ use crate::connect_similar_image_size_change::*; use crate::gui_data::*; use crate::initialize_gui::*; use crate::saving_loading::*; +use crate::tests::validate_notebook_data; use gtk::prelude::*; use std::{env, process}; @@ -107,8 +108,9 @@ fn main() { let (futures_sender_broken_files, futures_receiver_broken_files): (futures::channel::mpsc::UnboundedSender, futures::channel::mpsc::UnboundedReceiver) = futures::channel::mpsc::unbounded(); initialize_gui(&mut gui_data); - reset_configuration(&gui_data, false); // Fallback for invalid loading setting project - load_configuration(&gui_data, false); + validate_notebook_data(&gui_data); // Must be run after initialization of gui, to check if everything was properly setup + reset_configuration(false, &gui_data.upper_notebook, &gui_data.settings, &gui_data.text_view_errors); // Fallback for invalid loading setting project + load_configuration(false, &gui_data.upper_notebook, &gui_data.settings, &gui_data.text_view_errors, &gui_data.scrolled_window_errors); connect_button_delete(&gui_data); connect_button_save(&gui_data); @@ -128,8 +130,7 @@ fn main() { ); connect_button_select(&gui_data); connect_button_stop(&gui_data); - connect_button_symlink(&gui_data); - connect_button_hardlink(&gui_data); + connect_button_hardlink_symlink(&gui_data); connect_button_move(&gui_data); connect_notebook_tabs(&gui_data); connect_selection_of_directories(&gui_data); @@ -159,7 +160,7 @@ fn main() { let window_main = gui_data.window_main.clone(); let taskbar_state = gui_data.taskbar_state.clone(); window_main.connect_delete_event(move |_, _| { - save_configuration(&gui_data, false); // Save configuration at exit + save_configuration(false, &gui_data.upper_notebook, &gui_data.settings, &gui_data.text_view_errors); // Save configuration at exit gtk::main_quit(); taskbar_state.borrow_mut().release(); Inhibit(false) diff --git a/czkawka_gui/src/opening_selecting_records.rs b/czkawka_gui/src/opening_selecting_records.rs new file mode 100644 index 0000000..5264659 --- /dev/null +++ b/czkawka_gui/src/opening_selecting_records.rs @@ -0,0 +1,119 @@ +use crate::help_functions::*; +use gtk::prelude::*; + +const KEY_ENTER: u16 = 36; +const KEY_SPACE: u16 = 65; + +// TODO add option to open files and folders from context menu activated by pressing ONCE with right mouse button + +pub fn opening_double_click_function(tree_view: >k::TreeView, event: &gdk::EventButton) -> gtk::Inhibit { + let nt_object = get_notebook_object_from_tree_view(tree_view); + if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 1 { + common_open_function(tree_view, nt_object.column_name, nt_object.column_path, OpenMode::PathAndName); + } else if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 3 { + common_open_function(tree_view, nt_object.column_name, nt_object.column_path, OpenMode::OnlyPath); + } + gtk::Inhibit(false) +} +pub fn opening_enter_function(tree_view: >k::TreeView, event: &gdk::EventKey) -> gtk::Inhibit { + let nt_object = get_notebook_object_from_tree_view(tree_view); + handle_tree_keypress(tree_view, event, nt_object.column_name, nt_object.column_path, nt_object.column_selection) +} + +enum OpenMode { + OnlyPath, + PathAndName, +} + +fn common_mark_function(tree_view: >k::TreeView, column_name: i32) { + let selection = tree_view.selection(); + let (selected_rows, tree_model) = selection.selected_rows(); + + let model = get_list_store(tree_view); + + for tree_path in selected_rows.iter().rev() { + let value = !tree_model.value(&tree_model.iter(tree_path).unwrap(), column_name).get::().unwrap(); + model.set_value(&tree_model.iter(tree_path).unwrap(), column_name as u32, &value.to_value()); + } +} + +fn common_open_function(tree_view: >k::TreeView, column_name: i32, column_path: i32, opening_mode: OpenMode) { + let selection = tree_view.selection(); + let (selected_rows, tree_model) = selection.selected_rows(); + + for tree_path in selected_rows.iter().rev() { + let end_path; + let name = tree_model.value(&tree_model.iter(tree_path).unwrap(), column_name).get::().unwrap(); + let path = tree_model.value(&tree_model.iter(tree_path).unwrap(), column_path).get::().unwrap(); + + match opening_mode { + OpenMode::OnlyPath => { + end_path = path; + } + OpenMode::PathAndName => { + end_path = format!("{}/{}", path, name); + } + } + + open::that_in_background(&end_path); + + // if let Err(e) = open::that(&end_path) { + // println!("Failed to open {} - Error {}", end_path, e); + // } + } +} + +fn handle_tree_keypress(tree_view: >k::TreeView, event: &gdk::EventKey, name_column: i32, path_column: i32, mark_column: i32) -> gtk::Inhibit { + match event.keycode() { + Some(KEY_ENTER) => { + // Enter + common_open_function(tree_view, name_column, path_column, OpenMode::PathAndName); + } + Some(KEY_SPACE) => { + // Space + common_mark_function(tree_view, mark_column); + } + _ => {} + } + gtk::Inhibit(false) +} + +pub fn select_function_duplicates(_tree_selection: >k::TreeSelection, tree_model: >k::TreeModel, tree_path: >k::TreePath, _is_path_currently_selected: bool) -> bool { + // let name = tree_model.value(&tree_model.iter(tree_path).unwrap(),ColumnsDuplicates::Name as i32).get::().unwrap(); + // let path = tree_model.value(&tree_model.iter(tree_path).unwrap(), ColumnsDuplicates::Path as i32).get::().unwrap(); + // let modification = tree_model.value(&tree_model.iter(tree_path).unwrap(),ColumnsDuplicates::Modification as i32).get::().unwrap(); + let color = tree_model.value(&tree_model.iter(tree_path).unwrap(), ColumnsDuplicates::Color as i32).get::().unwrap(); + + if color == HEADER_ROW_COLOR { + return false; + } + + true +} +pub fn select_function_same_music(_tree_selection: >k::TreeSelection, tree_model: >k::TreeModel, tree_path: >k::TreePath, _is_path_currently_selected: bool) -> bool { + let color = tree_model.value(&tree_model.iter(tree_path).unwrap(), ColumnsSameMusic::Color as i32).get::().unwrap(); + + if color == HEADER_ROW_COLOR { + return false; + } + + true +} +pub fn select_function_similar_images(_tree_selection: >k::TreeSelection, tree_model: >k::TreeModel, tree_path: >k::TreePath, _is_path_currently_selected: bool) -> bool { + let color = tree_model.value(&tree_model.iter(tree_path).unwrap(), ColumnsSimilarImages::Color as i32).get::().unwrap(); + + if color == HEADER_ROW_COLOR { + return false; + } + + true +} +pub fn select_function_similar_videos(_tree_selection: >k::TreeSelection, tree_model: >k::TreeModel, tree_path: >k::TreePath, _is_path_currently_selected: bool) -> bool { + let color = tree_model.value(&tree_model.iter(tree_path).unwrap(), ColumnsSimilarVideos::Color as i32).get::().unwrap(); + + if color == HEADER_ROW_COLOR { + return false; + } + + true +} diff --git a/czkawka_gui/src/saving_loading.rs b/czkawka_gui/src/saving_loading.rs index bfdd492..2da788d 100644 --- a/czkawka_gui/src/saving_loading.rs +++ b/czkawka_gui/src/saving_loading.rs @@ -1,7 +1,9 @@ -use crate::gui_data::*; +use crate::gui_settings::GuiSettings; +use crate::gui_upper_notepad::GuiUpperNotebook; use crate::help_functions::*; use directories_next::ProjectDirs; use gtk::prelude::*; +use gtk::{ScrolledWindow, TextView}; use std::fs::File; use std::io::Write; use std::path::Path; @@ -11,9 +13,9 @@ 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.settings.check_button_settings_save_at_exit.clone(); - let text_view_errors = gui_data.text_view_errors.clone(); +pub fn save_configuration(manual_execution: bool, upper_notebook: &GuiUpperNotebook, settings: &GuiSettings, text_view_errors: &TextView) { + let check_button_settings_save_at_exit = settings.check_button_settings_save_at_exit.clone(); + let text_view_errors = text_view_errors.clone(); reset_text_view(&text_view_errors); @@ -40,7 +42,7 @@ pub fn save_configuration(gui_data: &GuiData, manual_execution: bool) { //// Included Directories data_to_save.push("--included_directories:".to_string()); - let tree_view_included_directories = gui_data.upper_notebook.tree_view_included_directories.clone(); + let tree_view_included_directories = upper_notebook.tree_view_included_directories.clone(); let list_store = get_list_store(&tree_view_included_directories); if let Some(iter) = list_store.iter_first() { loop { @@ -53,7 +55,7 @@ pub fn save_configuration(gui_data: &GuiData, manual_execution: bool) { //// Excluded Directories data_to_save.push("--excluded_directories:".to_string()); - let tree_view_excluded_directories = gui_data.upper_notebook.tree_view_excluded_directories.clone(); + let tree_view_excluded_directories = upper_notebook.tree_view_excluded_directories.clone(); let list_store = get_list_store(&tree_view_excluded_directories); if let Some(iter) = list_store.iter_first() { loop { @@ -67,7 +69,7 @@ pub fn save_configuration(gui_data: &GuiData, manual_execution: bool) { { //// Excluded Items data_to_save.push("--excluded_items:".to_string()); - let entry_excluded_items = gui_data.upper_notebook.entry_excluded_items.clone(); + let entry_excluded_items = upper_notebook.entry_excluded_items.clone(); for item in entry_excluded_items.text().split(',') { if item.trim().is_empty() { continue; @@ -77,7 +79,7 @@ pub fn save_configuration(gui_data: &GuiData, manual_execution: bool) { //// Allowed extensions data_to_save.push("--allowed_extensions:".to_string()); - let entry_allowed_extensions = gui_data.upper_notebook.entry_allowed_extensions.clone(); + let entry_allowed_extensions = upper_notebook.entry_allowed_extensions.clone(); for extension in entry_allowed_extensions.text().split(',') { if extension.trim().is_empty() { continue; @@ -87,57 +89,57 @@ pub fn save_configuration(gui_data: &GuiData, manual_execution: bool) { //// Save at exit data_to_save.push("--save_at_exit:".to_string()); - let check_button_settings_save_at_exit = gui_data.settings.check_button_settings_save_at_exit.clone(); + let check_button_settings_save_at_exit = settings.check_button_settings_save_at_exit.clone(); data_to_save.push(check_button_settings_save_at_exit.is_active().to_string()); //// Load at start data_to_save.push("--load_at_start:".to_string()); - let check_button_settings_load_at_start = gui_data.settings.check_button_settings_load_at_start.clone(); + let check_button_settings_load_at_start = settings.check_button_settings_load_at_start.clone(); data_to_save.push(check_button_settings_load_at_start.is_active().to_string()); //// Confirm deletion of files data_to_save.push("--confirm_deletion:".to_string()); - let check_button_settings_confirm_deletion = gui_data.settings.check_button_settings_confirm_deletion.clone(); + let check_button_settings_confirm_deletion = settings.check_button_settings_confirm_deletion.clone(); data_to_save.push(check_button_settings_confirm_deletion.is_active().to_string()); //// Confirm deletion of all files in group data_to_save.push("--confirm_group_deletion:".to_string()); - let check_button_settings_confirm_group_deletion = gui_data.settings.check_button_settings_confirm_group_deletion.clone(); + let check_button_settings_confirm_group_deletion = settings.check_button_settings_confirm_group_deletion.clone(); data_to_save.push(check_button_settings_confirm_group_deletion.is_active().to_string()); //// Show image previews in similar images data_to_save.push("--show_previews_similar_images:".to_string()); - let check_button_settings_show_preview_similar_images = gui_data.settings.check_button_settings_show_preview_similar_images.clone(); + let check_button_settings_show_preview_similar_images = settings.check_button_settings_show_preview_similar_images.clone(); data_to_save.push(check_button_settings_show_preview_similar_images.is_active().to_string()); //// Show image previews in duplicates data_to_save.push("--show_previews_duplicates:".to_string()); - let check_button_settings_show_preview_duplicates = gui_data.settings.check_button_settings_show_preview_duplicates.clone(); + let check_button_settings_show_preview_duplicates = settings.check_button_settings_show_preview_duplicates.clone(); data_to_save.push(check_button_settings_show_preview_duplicates.is_active().to_string()); //// Show bottom text panel with errors data_to_save.push("--bottom_text_panel:".to_string()); - let check_button_settings_show_text_view = gui_data.settings.check_button_settings_show_text_view.clone(); + let check_button_settings_show_text_view = settings.check_button_settings_show_text_view.clone(); data_to_save.push(check_button_settings_show_text_view.is_active().to_string()); //// Hide/Show hard linked files, with same inodes data_to_save.push("--hide_hard_links:".to_string()); - let check_button_settings_hide_hard_links = gui_data.settings.check_button_settings_hide_hard_links.clone(); + let check_button_settings_hide_hard_links = settings.check_button_settings_hide_hard_links.clone(); data_to_save.push(check_button_settings_hide_hard_links.is_active().to_string()); //// Use cache system data_to_save.push("--use_cache:".to_string()); - let check_button_settings_use_cache = gui_data.settings.check_button_settings_use_cache.clone(); + let check_button_settings_use_cache = settings.check_button_settings_use_cache.clone(); data_to_save.push(check_button_settings_use_cache.is_active().to_string()); //// Delete to trash data_to_save.push("--use_trash:".to_string()); - let check_button_settings_use_trash = gui_data.settings.check_button_settings_use_trash.clone(); + let check_button_settings_use_trash = settings.check_button_settings_use_trash.clone(); data_to_save.push(check_button_settings_use_trash.is_active().to_string()); //// minimal cache file size data_to_save.push("--cache_minimal_file_size:".to_string()); - let entry_settings_cache_file_minimal_size = gui_data.settings.entry_settings_cache_file_minimal_size.clone(); + let entry_settings_cache_file_minimal_size = settings.entry_settings_cache_file_minimal_size.clone(); data_to_save.push(entry_settings_cache_file_minimal_size.text().as_str().parse::().unwrap_or(2 * 1024 * 1024).to_string()); } @@ -194,8 +196,8 @@ enum TypeOfLoadedData { CacheMinimalSize, } -pub fn load_configuration(gui_data: &GuiData, manual_execution: bool) { - let text_view_errors = gui_data.text_view_errors.clone(); +pub fn load_configuration(manual_execution: bool, upper_notebook: &GuiUpperNotebook, settings: &GuiSettings, text_view_errors: &TextView, scrolled_window_errors: &ScrolledWindow) { + let text_view_errors = text_view_errors.clone(); reset_text_view(&text_view_errors); @@ -450,7 +452,7 @@ pub fn load_configuration(gui_data: &GuiData, manual_execution: bool) { // Setting data if manual_execution || loading_at_start { //// Included Directories - let tree_view_included_directories = gui_data.upper_notebook.tree_view_included_directories.clone(); + let tree_view_included_directories = upper_notebook.tree_view_included_directories.clone(); let list_store = get_list_store(&tree_view_included_directories); list_store.clear(); @@ -460,7 +462,7 @@ pub fn load_configuration(gui_data: &GuiData, manual_execution: bool) { } //// Exclude Directories - let tree_view_excluded_directories = gui_data.upper_notebook.tree_view_excluded_directories.clone(); + let tree_view_excluded_directories = upper_notebook.tree_view_excluded_directories.clone(); let list_store = get_list_store(&tree_view_excluded_directories); list_store.clear(); @@ -470,33 +472,33 @@ pub fn load_configuration(gui_data: &GuiData, manual_execution: bool) { } //// Excluded Items - let entry_excluded_items = gui_data.upper_notebook.entry_excluded_items.clone(); + let entry_excluded_items = upper_notebook.entry_excluded_items.clone(); entry_excluded_items.set_text(excluded_items.iter().map(|e| e.to_string() + ",").collect::().as_str()); //// Allowed extensions - let entry_allowed_extensions = gui_data.upper_notebook.entry_allowed_extensions.clone(); + let entry_allowed_extensions = upper_notebook.entry_allowed_extensions.clone(); entry_allowed_extensions.set_text(allowed_extensions.iter().map(|e| e.to_string() + ",").collect::().as_str()); //// Buttons - gui_data.settings.check_button_settings_load_at_start.set_active(loading_at_start); - gui_data.settings.check_button_settings_save_at_exit.set_active(saving_at_exit); - gui_data.settings.check_button_settings_confirm_deletion.set_active(confirm_deletion); - gui_data.settings.check_button_settings_confirm_group_deletion.set_active(confirm_group_deletion); - gui_data.settings.check_button_settings_show_preview_similar_images.set_active(show_previews_similar_images); - gui_data.settings.check_button_settings_show_preview_duplicates.set_active(show_previews_duplicates); + settings.check_button_settings_load_at_start.set_active(loading_at_start); + settings.check_button_settings_save_at_exit.set_active(saving_at_exit); + settings.check_button_settings_confirm_deletion.set_active(confirm_deletion); + settings.check_button_settings_confirm_group_deletion.set_active(confirm_group_deletion); + settings.check_button_settings_show_preview_similar_images.set_active(show_previews_similar_images); + settings.check_button_settings_show_preview_duplicates.set_active(show_previews_duplicates); - gui_data.settings.check_button_settings_show_text_view.set_active(bottom_text_panel); + settings.check_button_settings_show_text_view.set_active(bottom_text_panel); if !bottom_text_panel { - gui_data.scrolled_window_errors.hide(); + scrolled_window_errors.hide(); } else { - gui_data.scrolled_window_errors.show(); + scrolled_window_errors.show(); } - gui_data.settings.check_button_settings_hide_hard_links.set_active(hide_hard_links); - gui_data.settings.check_button_settings_use_cache.set_active(use_cache); - gui_data.settings.check_button_settings_use_trash.set_active(use_trash); - gui_data.settings.entry_settings_cache_file_minimal_size.set_text(cache_minimal_size.to_string().as_str()); + settings.check_button_settings_hide_hard_links.set_active(hide_hard_links); + settings.check_button_settings_use_cache.set_active(use_cache); + settings.check_button_settings_use_trash.set_active(use_trash); + settings.entry_settings_cache_file_minimal_size.set_text(cache_minimal_size.to_string().as_str()); } else { - gui_data.settings.check_button_settings_load_at_start.set_active(false); + settings.check_button_settings_load_at_start.set_active(false); } if manual_execution { @@ -507,15 +509,15 @@ pub fn load_configuration(gui_data: &GuiData, manual_execution: bool) { } } -pub fn reset_configuration(gui_data: &GuiData, manual_clearing: bool) { +pub fn reset_configuration(manual_clearing: bool, upper_notebook: &GuiUpperNotebook, settings: &GuiSettings, text_view_errors: &TextView) { // TODO Maybe add popup dialog to confirm resetting - let text_view_errors = gui_data.text_view_errors.clone(); + let text_view_errors = text_view_errors.clone(); reset_text_view(&text_view_errors); // Resetting included directories { - let tree_view_included_directories = gui_data.upper_notebook.tree_view_included_directories.clone(); + let tree_view_included_directories = upper_notebook.tree_view_included_directories.clone(); let list_store = get_list_store(&tree_view_included_directories); list_store.clear(); @@ -539,7 +541,7 @@ pub fn reset_configuration(gui_data: &GuiData, manual_clearing: bool) { } // Resetting excluded directories { - let tree_view_excluded_directories = gui_data.upper_notebook.tree_view_excluded_directories.clone(); + let tree_view_excluded_directories = upper_notebook.tree_view_excluded_directories.clone(); let list_store = get_list_store(&tree_view_excluded_directories); list_store.clear(); if cfg!(target_family = "unix") { @@ -551,7 +553,7 @@ pub fn reset_configuration(gui_data: &GuiData, manual_clearing: bool) { } // Resetting excluded items { - let entry_excluded_items = gui_data.upper_notebook.entry_excluded_items.clone(); + let entry_excluded_items = upper_notebook.entry_excluded_items.clone(); if cfg!(target_family = "unix") { entry_excluded_items.set_text("*/.git/*,*/node_modules/*,*/lost+found/*,*/Trash/*,*/.Trash-*/*,*/snap/*,/home/*/.cache/*"); } @@ -561,23 +563,23 @@ pub fn reset_configuration(gui_data: &GuiData, manual_clearing: bool) { } // Resetting allowed extensions { - let entry_allowed_extensions = gui_data.upper_notebook.entry_allowed_extensions.clone(); + let entry_allowed_extensions = upper_notebook.entry_allowed_extensions.clone(); entry_allowed_extensions.set_text(""); } // Set settings { - gui_data.settings.check_button_settings_save_at_exit.set_active(true); - gui_data.settings.check_button_settings_load_at_start.set_active(true); - gui_data.settings.check_button_settings_confirm_deletion.set_active(true); - gui_data.settings.check_button_settings_confirm_group_deletion.set_active(true); - gui_data.settings.check_button_settings_show_preview_similar_images.set_active(true); - gui_data.settings.check_button_settings_show_preview_duplicates.set_active(true); - gui_data.settings.check_button_settings_show_text_view.set_active(true); - gui_data.settings.check_button_settings_hide_hard_links.set_active(true); - gui_data.settings.check_button_settings_use_cache.set_active(true); - gui_data.settings.check_button_settings_use_trash.set_active(false); - gui_data.settings.entry_settings_cache_file_minimal_size.set_text("2097152"); + settings.check_button_settings_save_at_exit.set_active(true); + settings.check_button_settings_load_at_start.set_active(true); + settings.check_button_settings_confirm_deletion.set_active(true); + settings.check_button_settings_confirm_group_deletion.set_active(true); + settings.check_button_settings_show_preview_similar_images.set_active(true); + settings.check_button_settings_show_preview_duplicates.set_active(true); + settings.check_button_settings_show_text_view.set_active(true); + settings.check_button_settings_hide_hard_links.set_active(true); + settings.check_button_settings_use_cache.set_active(true); + settings.check_button_settings_use_trash.set_active(false); + settings.entry_settings_cache_file_minimal_size.set_text("2097152"); } if manual_clearing { add_text_to_text_view(&text_view_errors, "Current configuration was cleared."); diff --git a/czkawka_gui/src/tests.rs b/czkawka_gui/src/tests.rs new file mode 100644 index 0000000..a4c8b2c --- /dev/null +++ b/czkawka_gui/src/tests.rs @@ -0,0 +1,37 @@ +use crate::help_functions::{get_notebook_enum_from_tree_view, NOTEBOOKS_INFOS}; +use crate::notebook_enums::{to_notebook_main_enum, NUMBER_OF_NOTEBOOK_MAIN_TABS}; +use crate::GuiData; + +pub fn validate_notebook_data(gui_data: &GuiData) { + // Test treeviews names, each treeview should have set name same as variable name + let tree_view_arr: [>k::TreeView; NUMBER_OF_NOTEBOOK_MAIN_TABS] = [ + &gui_data.main_notebook.tree_view_duplicate_finder, + &gui_data.main_notebook.tree_view_similar_videos_finder, + &gui_data.main_notebook.tree_view_temporary_files_finder, + &gui_data.main_notebook.tree_view_big_files_finder, + &gui_data.main_notebook.tree_view_empty_files_finder, + &gui_data.main_notebook.tree_view_broken_files, + &gui_data.main_notebook.tree_view_empty_folder_finder, + &gui_data.main_notebook.tree_view_same_music_finder, + &gui_data.main_notebook.tree_view_similar_images_finder, + &gui_data.main_notebook.tree_view_invalid_symlinks, + ]; + for (_i, item) in tree_view_arr.iter().enumerate() { + // println!("Checking {} element", i); + + get_notebook_enum_from_tree_view(item); + } + + // This test main info about notebooks + // Should have same order as notebook enum types + for (i, item) in NOTEBOOKS_INFOS.iter().enumerate() { + let en = to_notebook_main_enum(i as u32); + assert_eq!(item.notebook_type, en); + } + + // Tests if data returned from array get_notebook_enum_from_tree_view are in right + for (i, item) in gui_data.main_notebook.get_main_tree_views().iter().enumerate() { + let nb_en = get_notebook_enum_from_tree_view(item); + assert_eq!(to_notebook_main_enum(i as u32), nb_en); + } +}