diff --git a/czkawka_gui/src/gui_main_notebook.rs b/czkawka_gui/src/gui_main_notebook.rs index c6d5e63..8648c98 100644 --- a/czkawka_gui/src/gui_main_notebook.rs +++ b/czkawka_gui/src/gui_main_notebook.rs @@ -57,6 +57,7 @@ pub struct GuiMainNotebook { pub radio_button_hash_type_xxh3: gtk::RadioButton, pub image_preview_similar_images: gtk::Image, + pub image_preview_duplicates: gtk::Image, } impl GuiMainNotebook { @@ -114,6 +115,7 @@ impl GuiMainNotebook { let radio_button_hash_type_xxh3: gtk::RadioButton = builder.object("radio_button_hash_type_xxh3").unwrap(); let image_preview_similar_images: gtk::Image = builder.object("image_preview_similar_images").unwrap(); + let image_preview_duplicates: gtk::Image = builder.object("image_preview_duplicates").unwrap(); Self { notebook_main, @@ -158,6 +160,7 @@ impl GuiMainNotebook { image_preview_similar_images, entry_duplicate_maximal_size, entry_same_music_maximal_size, + image_preview_duplicates, } } } diff --git a/czkawka_gui/src/gui_settings.rs b/czkawka_gui/src/gui_settings.rs index 0682cac..10128df 100644 --- a/czkawka_gui/src/gui_settings.rs +++ b/czkawka_gui/src/gui_settings.rs @@ -17,6 +17,7 @@ pub struct GuiSettings { // Duplicates pub check_button_settings_hide_hard_links: gtk::CheckButton, pub entry_settings_cache_file_minimal_size: gtk::Entry, + pub check_button_settings_show_preview_duplicates: gtk::CheckButton, // Similar Images pub check_button_settings_show_preview_similar_images: gtk::CheckButton, @@ -47,6 +48,7 @@ impl GuiSettings { // Duplicates let check_button_settings_hide_hard_links: gtk::CheckButton = builder.object("check_button_settings_hide_hard_links").unwrap(); let entry_settings_cache_file_minimal_size: gtk::Entry = builder.object("entry_settings_cache_file_minimal_size").unwrap(); + let check_button_settings_show_preview_duplicates: gtk::CheckButton = builder.object("check_button_settings_show_preview_duplicates").unwrap(); // Similar Images let check_button_settings_show_preview_similar_images: gtk::CheckButton = builder.object("check_button_settings_show_preview_similar_images").unwrap(); @@ -67,6 +69,7 @@ impl GuiSettings { check_button_settings_use_trash, check_button_settings_hide_hard_links, entry_settings_cache_file_minimal_size, + check_button_settings_show_preview_duplicates, check_button_settings_show_preview_similar_images, button_settings_save_configuration, button_settings_load_configuration, diff --git a/czkawka_gui/src/initialize_gui.rs b/czkawka_gui/src/initialize_gui.rs index 978e38c..7af0615 100644 --- a/czkawka_gui/src/initialize_gui.rs +++ b/czkawka_gui/src/initialize_gui.rs @@ -45,7 +45,9 @@ pub fn initialize_gui(gui_data: &mut GuiData) { let scrolled_window_broken_files = gui_data.main_notebook.scrolled_window_broken_files.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 check_button_settings_show_preview_similar_images = gui_data.settings.check_button_settings_show_preview_similar_images.clone(); + let check_button_settings_show_preview_duplicates = gui_data.settings.check_button_settings_show_preview_duplicates.clone(); let text_view_errors = gui_data.text_view_errors.clone(); let scale_similarity = gui_data.main_notebook.scale_similarity.clone(); @@ -60,6 +62,11 @@ pub fn initialize_gui(gui_data: &mut GuiData) { { // Duplicate Files { + let image_preview_duplicates_cloned = image_preview_duplicates.clone(); + image_preview_duplicates.hide(); + let text_view_errors_cloned = text_view_errors.clone(); + let check_button_settings_show_preview_duplicates_cloned = check_button_settings_show_preview_duplicates.clone(); + let col_types: [glib::types::Type; 8] = [ glib::types::Type::BOOL, glib::types::Type::BOOL, @@ -81,9 +88,15 @@ pub fn initialize_gui(gui_data: &mut GuiData) { 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_release_event(move |_tree_view, _e| { - // println!("{}", e.button()); + tree_view.connect_button_release_event(move |tree_view, _event| { + 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, + ); gtk::Inhibit(false) }); @@ -91,6 +104,8 @@ pub fn initialize_gui(gui_data: &mut GuiData) { 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(); tree_view.connect_key_release_event(move |tree_view, e| { if let Some(button_number) = e.keycode() { @@ -121,8 +136,17 @@ pub fn initialize_gui(gui_data: &mut GuiData) { ColumnsDuplicates::ActiveSelectButton as i32, &gui_data, ); + image_preview_duplicates.hide(); } } + show_preview( + tree_view, + &text_view_errors_cloned, + &check_button_settings_show_preview_duplicates, + &image_preview_duplicates, + ColumnsDuplicates::Path as i32, + ColumnsDuplicates::Name as i32, + ); gtk::Inhibit(false) }); } @@ -273,7 +297,14 @@ pub fn initialize_gui(gui_data: &mut GuiData) { 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_release_event(move |tree_view, _event| { - show_preview(tree_view, &text_view_errors, &check_button_settings_show_preview_similar_images, &image_preview_similar_images); + 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, + ); gtk::Inhibit(false) }); @@ -317,7 +348,14 @@ pub fn initialize_gui(gui_data: &mut GuiData) { image_preview_similar_images_clone.hide(); } } - show_preview(tree_view, &text_view_errors, &check_button_settings_show_preview_similar_images, &image_preview_similar_images); + 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, + ); gtk::Inhibit(false) }); } @@ -579,13 +617,13 @@ pub fn initialize_gui(gui_data: &mut GuiData) { }); } } -fn show_preview(tree_view: &TreeView, text_view_errors: &TextView, check_button_settings_show_preview_similar_images: &CheckButton, image_preview_similar_images: &Image) { +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(); let mut created_image = false; // Only show preview when selected is only one item, because there is no method to recognize current clicked item in multiselection - if selected_rows.len() == 1 && check_button_settings_show_preview_similar_images.is_active() { + if selected_rows.len() == 1 && check_button_settings_show_preview.is_active() { let tree_path = selected_rows[0].clone(); if let Some(proj_dirs) = ProjectDirs::from("pl", "Qarmin", "Czkawka") { // TODO labels on {} are in testing stage, so we just ignore for now this warning until found better idea how to fix this @@ -601,13 +639,17 @@ fn show_preview(tree_view: &TreeView, text_view_errors: &TextView, check_button_ add_text_to_text_view(text_view_errors, format!("Failed to create dir {} needed by image preview", cache_dir.display()).as_str()); break 'dir; } - let path = tree_model.value(&tree_model.iter(&tree_path).unwrap(), ColumnsSimilarImages::Path as i32).get::().unwrap(); - let name = tree_model.value(&tree_model.iter(&tree_path).unwrap(), ColumnsSimilarImages::Name as i32).get::().unwrap(); + let path = tree_model.value(&tree_model.iter(&tree_path).unwrap(), column_path).get::().unwrap(); + let name = tree_model.value(&tree_model.iter(&tree_path).unwrap(), column_name).get::().unwrap(); let file_name = format!("{}/{}", path, name); let file_name = file_name.as_str(); if let Some(extension) = Path::new(file_name).extension() { + if !["jpg", "jpeg", "png", "bmp", "tiff", "tif", "pnm", "tga", "ff", "gif", "jif", "jfi", "webp"].contains(&extension.to_string_lossy().to_string().to_lowercase().as_str()) { + break 'dir; + } + let img = match image::open(&file_name) { Ok(t) => t, Err(_) => { diff --git a/czkawka_gui/src/saving_loading.rs b/czkawka_gui/src/saving_loading.rs index b4913ba..e3f1563 100644 --- a/czkawka_gui/src/saving_loading.rs +++ b/czkawka_gui/src/saving_loading.rs @@ -106,10 +106,15 @@ pub fn save_configuration(gui_data: &GuiData, manual_execution: bool) { 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:".to_string()); + 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(); 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(); + 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(); @@ -180,7 +185,8 @@ enum TypeOfLoadedData { SavingAtExit, ConfirmDeletion, ConfirmGroupDeletion, - ShowPreviews, + ShowPreviewSimilarImages, + ShowPreviewDuplicates, BottomTextPanel, HideHardLinks, UseCache, @@ -217,7 +223,7 @@ pub fn load_configuration(gui_data: &GuiData, manual_execution: bool) { } }; - // Parsing Data + // Parsing Data - this are default values let mut included_directories: Vec = Vec::new(); let mut excluded_directories: Vec = Vec::new(); @@ -227,7 +233,8 @@ pub fn load_configuration(gui_data: &GuiData, manual_execution: bool) { let mut saving_at_exit: bool = true; let mut confirm_deletion: bool = true; let mut confirm_group_deletion: bool = true; - let mut show_previews: bool = true; + let mut show_previews_similar_images: bool = true; + let mut show_previews_duplicates: bool = true; let mut bottom_text_panel: bool = true; let mut hide_hard_links: bool = true; let mut use_cache: bool = true; @@ -256,8 +263,10 @@ pub fn load_configuration(gui_data: &GuiData, manual_execution: bool) { current_type = TypeOfLoadedData::ConfirmDeletion; } else if line.starts_with("--confirm_group_deletion") { current_type = TypeOfLoadedData::ConfirmGroupDeletion; - } else if line.starts_with("--show_previews") { - current_type = TypeOfLoadedData::ShowPreviews; + } else if line.starts_with("--show_previews_similar_images") { + current_type = TypeOfLoadedData::ShowPreviewSimilarImages; + } else if line.starts_with("--show_previews_duplicates") { + current_type = TypeOfLoadedData::ShowPreviewDuplicates; } else if line.starts_with("--bottom_text_panel") { current_type = TypeOfLoadedData::BottomTextPanel; } else if line.starts_with("--hide_hard_links") { @@ -346,12 +355,25 @@ pub fn load_configuration(gui_data: &GuiData, manual_execution: bool) { ); } } - TypeOfLoadedData::ShowPreviews => { + TypeOfLoadedData::ShowPreviewSimilarImages => { let line = line.to_lowercase(); if line == "1" || line == "true" { - show_previews = true; + show_previews_similar_images = true; } else if line == "0" || line == "false" { - show_previews = false; + show_previews_similar_images = false; + } else { + add_text_to_text_view( + &text_view_errors, + format!("Found invalid data in line {} \"{}\" isn't proper value(0/1/true/false) when loading file {:?}", line_number, line, config_file).as_str(), + ); + } + } + TypeOfLoadedData::ShowPreviewDuplicates => { + let line = line.to_lowercase(); + if line == "1" || line == "true" { + show_previews_duplicates = true; + } else if line == "0" || line == "false" { + show_previews_duplicates = false; } else { add_text_to_text_view( &text_view_errors, @@ -460,7 +482,8 @@ pub fn load_configuration(gui_data: &GuiData, manual_execution: bool) { 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); + 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); gui_data.settings.check_button_settings_show_text_view.set_active(bottom_text_panel); if !bottom_text_panel { @@ -549,6 +572,7 @@ pub fn reset_configuration(gui_data: &GuiData, manual_clearing: bool) { 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); diff --git a/czkawka_gui/ui/main_window.glade b/czkawka_gui/ui/main_window.glade index f833d92..7454aeb 100644 --- a/czkawka_gui/ui/main_window.glade +++ b/czkawka_gui/ui/main_window.glade @@ -648,17 +648,87 @@ Author: Rafał Mikrut True False - vertical True False - 8 + vertical - + True False - Size(bytes) + + + True + False + Check method: + + + False + True + 0 + + + + + Hash + True + True + False + True + True + + + False + True + 1 + + + + + HashMb + True + True + False + True + radio_button_duplicates_hash + + + False + True + 2 + + + + + Size + True + True + False + True + radio_button_duplicates_hash + + + False + True + 3 + + + + + Name + True + True + False + True + radio_button_duplicates_hash + + + False + True + 4 + + False @@ -667,10 +737,66 @@ Author: Rafał Mikrut - + True False - Min: + + + True + False + Hash type: + + + False + True + 0 + + + + + Blake3 + True + True + False + True + True + + + False + True + 2 + + + + + CRC32 + True + True + False + True + radio_button_hash_type_blake3 + + + False + True + 2 + + + + + XXH3 + True + True + False + True + radio_button_hash_type_blake3 + + + False + True + 3 + + False @@ -679,220 +805,118 @@ Author: Rafał Mikrut - + + True + False + 8 + + + True + False + Size(bytes) + + + False + True + 0 + + + + + True + False + Min: + + + False + True + 1 + + + + + True + True + 15 + 8192 + False + number + + + True + True + 2 + + + + + True + False + Max: + + + False + True + 3 + + + + + True + True + 15 + 1099512000000 + False + number + + + True + True + 4 + + + + + False + True + 2 + + + + True True - 15 - 8192 - False - number + in + + + True True - 2 - - - - - True - False - Max: - - - False - True 3 - - - True - True - 15 - 1099512000000 - False - number - - - True - True - 4 - - - - - False - True - 0 - - - - - True - False - - - True - False - Check method: - - - False - True - 0 - - - - - Hash - True - True - False - True - True - - - False - True - 1 - - - - - HashMb - True - True - False - True - radio_button_duplicates_hash - - - False - True - 2 - - - - - Size - True - True - False - True - radio_button_duplicates_hash - - - False - True - 3 - - - - - Name - True - True - False - True - radio_button_duplicates_hash - - - False - True - 4 - - - - - False - True - 1 - - - - - True - False - - - True - False - Hash type: - - - False - True - 0 - - - - - Blake3 - True - True - False - True - True - - - False - True - 1 - - - - - CRC32 - True - True - False - True - True - radio_button_hash_type_blake3 - - - False - True - 2 - - - - - XXH3 - True - True - False - True - True - radio_button_hash_type_blake3 - - - False - True - 3 - - - - - False - True - 2 - - - - - True - True - in - - - True True - 3 + 0 + + + + + 100 + 80 + True + False + center + gtk-missing-image + + + False + True + 1 @@ -1232,6 +1256,7 @@ Author: Rafał Mikrut True False center + gtk-missing-image False diff --git a/czkawka_gui/ui/settings.glade b/czkawka_gui/ui/settings.glade index 60df232..927cefb 100644 --- a/czkawka_gui/ui/settings.glade +++ b/czkawka_gui/ui/settings.glade @@ -222,6 +222,21 @@ Author: Rafał Mikrut 0 + + + Show image preview + True + True + False + True + True + + + False + True + 1 + + True