From 81b0afffc215d46de38cd653523bf35fcb06fb27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mikrut?= Date: Sat, 3 Feb 2024 20:18:24 +0100 Subject: [PATCH] Hashes --- Changelog.md | 1 + czkawka_core/src/common.rs | 1 - czkawka_core/src/similar_images.rs | 128 ++++++-------- czkawka_gui/src/saving_loading.rs | 253 ++++++++++------------------ krokiet/src/connect_show_preview.rs | 18 +- 5 files changed, 155 insertions(+), 246 deletions(-) diff --git a/Changelog.md b/Changelog.md index 604ae79..1683e22 100644 --- a/Changelog.md +++ b/Changelog.md @@ -32,6 +32,7 @@ - Decrease memory usage when collecting files by removing unused fields in custom file entries structs - [#1159](https://github.com/qarmin/czkawka/pull/1159) - Decrease a little size of cache by few percents and improve loading/saving speed - [#1159](https://github.com/qarmin/czkawka/pull/1159) - Added ability to remove from scan files with excluded extensions - [#1184](https://github.com/qarmin/czkawka/pull/1102) +- Fixed not showing in similar images results, files with same hashes when using reference folders - [#1184](https://github.com/qarmin/czkawka/pull/1102) ## Version 6.1.0 - 15.10.2023r - BREAKING CHANGE - Changed cache saving method, deduplicated, optimized and simplified procedure(all files needs to be hashed again) - [#1072](https://github.com/qarmin/czkawka/pull/1072), [#1086](https://github.com/qarmin/czkawka/pull/1086) diff --git a/czkawka_core/src/common.rs b/czkawka_core/src/common.rs index cf9e931..6c47810 100644 --- a/czkawka_core/src/common.rs +++ b/czkawka_core/src/common.rs @@ -269,7 +269,6 @@ pub fn get_dynamic_image_from_raw_image(path: impl AsRef) -> Option>(); - debug!("hash_images - end hashing images"); + debug!("hash_images - end hashing {} images", vec_file_entry.len()); send_info_and_wait_for_ending_all_threads(&progress_thread_run, progress_thread_handle); @@ -457,54 +457,21 @@ impl SimilarImages { collected_similar_images: &mut HashMap>, hashes_similarity: HashMap, ) { - if self.common_data.use_reference_folders { - // This is same step as without reference folders, but also checks if children are inside/outside reference directories, because may happen, that one file is inside reference folder and other outside + // Collecting results to vector + for (parent_hash, child_number) in hashes_parents { + // If hash contains other hasher OR multiple images are available for checked hash + if child_number > 0 || hashes_with_multiple_images.contains(&parent_hash) { + let vec_fe = all_hashed_images[&parent_hash].clone(); + collected_similar_images.insert(parent_hash.clone(), vec_fe); + } + } - // Collecting results to vector - for (parent_hash, child_number) in hashes_parents { - // If hash contains other hasher OR multiple images are available for checked hash - if child_number > 0 || hashes_with_multiple_images.contains(&parent_hash) { - let vec_fe = all_hashed_images - .get(&parent_hash) - .unwrap() - .iter() - .filter(|e| is_in_reference_folder(&self.common_data.directories.reference_directories, &e.path)) - .cloned() - .collect(); - collected_similar_images.insert(parent_hash.clone(), vec_fe); - } - } - - for (child_hash, (parent_hash, similarity)) in hashes_similarity { - let mut vec_fe: Vec<_> = all_hashed_images - .get(&child_hash) - .unwrap() - .iter() - .filter(|e| !is_in_reference_folder(&self.common_data.directories.reference_directories, &e.path)) - .cloned() - .collect(); - for fe in &mut vec_fe { - fe.similarity = similarity; - } - collected_similar_images.get_mut(&parent_hash).unwrap().append(&mut vec_fe); - } - } else { - // Collecting results to vector - for (parent_hash, child_number) in hashes_parents { - // If hash contains other hasher OR multiple images are available for checked hash - if child_number > 0 || hashes_with_multiple_images.contains(&parent_hash) { - let vec_fe = all_hashed_images.get(&parent_hash).unwrap().clone(); - collected_similar_images.insert(parent_hash.clone(), vec_fe); - } - } - - for (child_hash, (parent_hash, similarity)) in hashes_similarity { - let mut vec_fe = all_hashed_images.get(&child_hash).unwrap().clone(); - for fe in &mut vec_fe { - fe.similarity = similarity; - } - collected_similar_images.get_mut(&parent_hash).unwrap().append(&mut vec_fe); + for (child_hash, (parent_hash, similarity)) in hashes_similarity { + let mut vec_fe = all_hashed_images[&child_hash].clone(); + for fe in &mut vec_fe { + fe.similarity = similarity; } + collected_similar_images.get_mut(&parent_hash).unwrap().append(&mut vec_fe); } } @@ -770,7 +737,7 @@ impl SimilarImages { } } } - assert!(!found, "Found Invalid entries, verify errors before"); // TODO crashes with empty result with reference folder, verify why + assert!(!found, "Found Invalid entries, verify errors before"); } fn delete_files(&mut self) { @@ -1004,12 +971,12 @@ fn debug_check_for_duplicated_things( for (hash, number_of_children) in hashes_parents { if *number_of_children > 0 { if hashmap_hashes.contains(hash) { - println!("------1--HASH--{} {:?}", numm, all_hashed_images.get(hash).unwrap()); + println!("------1--HASH--{} {:?}", numm, all_hashed_images[hash]); found_broken_thing = true; } hashmap_hashes.insert((*hash).clone()); - for i in all_hashed_images.get(hash).unwrap() { + for i in &all_hashed_images[hash] { let name = i.path.to_string_lossy().to_string(); if hashmap_names.contains(&name) { println!("------1--NAME--{numm} {name:?}"); @@ -1021,12 +988,12 @@ fn debug_check_for_duplicated_things( } for hash in hashes_similarity.keys() { if hashmap_hashes.contains(hash) { - println!("------2--HASH--{} {:?}", numm, all_hashed_images.get(hash).unwrap()); + println!("------2--HASH--{} {:?}", numm, all_hashed_images[hash]); found_broken_thing = true; } hashmap_hashes.insert((*hash).clone()); - for i in all_hashed_images.get(hash).unwrap() { + for i in &all_hashed_images[hash] { let name = i.path.to_string_lossy().to_string(); if hashmap_names.contains(&name) { println!("------2--NAME--{numm} {name:?}"); @@ -1194,34 +1161,6 @@ mod tests { } } - // TODO this not works yet, - // Need to find a way to - // #[test] - // fn test_similar_similarity() { - // for _ in 0..100 { - // let mut similar_images = SimilarImages { - // similarity: 10, - // common_data: CommonToolData { - // tool_type: ToolType::SimilarImages, - // ..Default::default() - // }, - // use_reference_folders: false, - // ..Default::default() - // }; - // - // let fe1 = create_random_file_entry(vec![1, 1, 1, 1, 1, 1, 1, 0b0000_0001], "abc.txt"); - // let fe2 = create_random_file_entry(vec![1, 1, 1, 1, 1, 1, 1, 0b0000_0010], "bcd.txt"); - // let fe3 = create_random_file_entry(vec![1, 1, 1, 1, 1, 1, 1, 0b0000_0100], "rrd.txt"); - // let fe4 = create_random_file_entry(vec![1, 1, 1, 1, 1, 1, 1, 0b0111_1111], "rdd.txt"); - // - // add_hashes(&mut similar_images.image_hashes, vec![fe1, fe2, fe3, fe4]); - // - // similar_images.find_similar_hashes(None, None); - // assert_eq!(similar_images.get_similar_images().len(), 1); - // assert_eq!(similar_images.get_similar_images()[0].len(), 4); - // } - // } - #[test] fn test_simple_referenced_same_group() { for _ in 0..100 { @@ -1466,6 +1405,35 @@ mod tests { } } + #[test] + fn test_reference_same() { + for _ in 0..100 { + let mut similar_images = SimilarImages { + similarity: 1, + common_data: CommonToolData { + tool_type: ToolType::SimilarImages, + directories: Directories { + reference_directories: vec![PathBuf::from("/home/rr/")], + ..Default::default() + }, + use_reference_folders: true, + ..Default::default() + }, + ..Default::default() + }; + + let fe1 = create_random_file_entry(vec![1, 1, 1, 1, 1, 1, 1, 1], "/home/rr/abc.txt"); + let fe2 = create_random_file_entry(vec![1, 1, 1, 1, 1, 1, 1, 1], "/home/kk/bcd.txt"); + + add_hashes(&mut similar_images.image_hashes, vec![fe1, fe2]); + + similar_images.find_similar_hashes(None, None); + let res = similar_images.get_similar_images_referenced(); + assert_eq!(res.len(), 1); + assert_eq!(res[0].1.len(), 1); + } + } + #[test] fn test_reference_union() { for _ in 0..100 { diff --git a/czkawka_gui/src/saving_loading.rs b/czkawka_gui/src/saving_loading.rs index 072cd2a..c9a958a 100644 --- a/czkawka_gui/src/saving_loading.rs +++ b/czkawka_gui/src/saving_loading.rs @@ -81,7 +81,7 @@ impl LoadSaveStruct { pub fn get_vector_string(&self, key: &str, default_value: Vec) -> Vec { if self.loaded_items.contains_key(key) { let mut new_vector = Vec::new(); - for i in self.loaded_items.get(key).unwrap() { + for i in &self.loaded_items[key] { if !i.trim().is_empty() { new_vector.push(i.trim().to_string()); } @@ -104,7 +104,7 @@ impl LoadSaveStruct { } pub fn get_string(&self, key: String, default_value: String) -> String { if self.loaded_items.contains_key(&key) { - let item = self.loaded_items.get(&key).unwrap().clone().into_iter().filter(|e| !e.is_empty()).collect::>(); + let item = &self.loaded_items[&key].clone().into_iter().filter(|e| !e.is_empty()).collect::>(); return if item.len() == 1 { item[0].clone() } else if item.is_empty() { @@ -119,7 +119,7 @@ impl LoadSaveStruct { } pub fn get_object(&self, key: String, default_value: T) -> T { if self.loaded_items.contains_key(&key) { - let item = self.loaded_items.get(&key).unwrap().clone().into_iter().filter(|e| !e.is_empty()).collect::>(); + let item = &self.loaded_items[&key].clone().into_iter().filter(|e| !e.is_empty()).collect::>(); return if item.len() == 1 { if let Ok(t) = item[0].parse::() { @@ -138,7 +138,7 @@ impl LoadSaveStruct { } pub fn get_bool(&self, key: String, default_value: bool) -> bool { if self.loaded_items.contains_key(&key) { - let item = self.loaded_items.get(&key).unwrap().clone().into_iter().filter(|e| !e.is_empty()).collect::>(); + let item = &self.loaded_items[&key].clone().into_iter().filter(|e| !e.is_empty()).collect::>(); return if item.len() == 1 { let text = item[0].trim().to_lowercase(); if text == "false" || text == "0" { @@ -462,183 +462,138 @@ pub fn save_configuration(manual_execution: bool, upper_notebook: &GuiUpperNoteb // Upper notebook saving_struct.save_list_store( - hashmap_ls.get(&LoadText::IncludedDirectories).unwrap().to_string(), + hashmap_ls[&LoadText::IncludedDirectories].clone(), &upper_notebook.tree_view_included_directories.clone(), ColumnsIncludedDirectory::Path as i32, ); saving_struct.save_list_store( - hashmap_ls.get(&LoadText::ExcludedDirectories).unwrap().to_string(), + hashmap_ls[&LoadText::ExcludedDirectories].clone(), &upper_notebook.tree_view_excluded_directories.clone(), ColumnsExcludedDirectory::Path as i32, ); - saving_struct.save_var(hashmap_ls.get(&LoadText::ExcludedItems).unwrap().to_string(), &upper_notebook.entry_excluded_items.text()); - saving_struct.save_var( - hashmap_ls.get(&LoadText::AllowedExtensions).unwrap().to_string(), - &upper_notebook.entry_allowed_extensions.text(), - ); - saving_struct.save_var( - hashmap_ls.get(&LoadText::MinimalFileSize).unwrap().to_string(), - &upper_notebook.entry_general_minimal_size.text(), - ); - saving_struct.save_var( - hashmap_ls.get(&LoadText::MaximalFileSize).unwrap().to_string(), - &upper_notebook.entry_general_maximal_size.text(), - ); + saving_struct.save_var(hashmap_ls[&LoadText::ExcludedItems].clone(), &upper_notebook.entry_excluded_items.text()); + saving_struct.save_var(hashmap_ls[&LoadText::AllowedExtensions].clone(), &upper_notebook.entry_allowed_extensions.text()); + saving_struct.save_var(hashmap_ls[&LoadText::MinimalFileSize].clone(), &upper_notebook.entry_general_minimal_size.text()); + saving_struct.save_var(hashmap_ls[&LoadText::MaximalFileSize].clone(), &upper_notebook.entry_general_maximal_size.text()); // Check buttons + saving_struct.save_var(hashmap_ls[&LoadText::SaveAtExit].clone(), &settings.check_button_settings_save_at_exit.is_active()); + saving_struct.save_var(hashmap_ls[&LoadText::LoadAtStart].clone(), &settings.check_button_settings_load_at_start.is_active()); saving_struct.save_var( - hashmap_ls.get(&LoadText::SaveAtExit).unwrap().to_string(), - &settings.check_button_settings_save_at_exit.is_active(), - ); - saving_struct.save_var( - hashmap_ls.get(&LoadText::LoadAtStart).unwrap().to_string(), - &settings.check_button_settings_load_at_start.is_active(), - ); - saving_struct.save_var( - hashmap_ls.get(&LoadText::ConfirmDeletionFiles).unwrap().to_string(), + hashmap_ls[&LoadText::ConfirmDeletionFiles].clone(), &settings.check_button_settings_confirm_deletion.is_active(), ); saving_struct.save_var( - hashmap_ls.get(&LoadText::ConfirmDeletionAllFilesInGroup).unwrap().to_string(), + hashmap_ls[&LoadText::ConfirmDeletionAllFilesInGroup].clone(), &settings.check_button_settings_confirm_group_deletion.is_active(), ); saving_struct.save_var( - hashmap_ls.get(&LoadText::ImagePreviewImage).unwrap().to_string(), + hashmap_ls[&LoadText::ImagePreviewImage].clone(), &settings.check_button_settings_show_preview_similar_images.is_active(), ); saving_struct.save_var( - hashmap_ls.get(&LoadText::DuplicatePreviewImage).unwrap().to_string(), + hashmap_ls[&LoadText::DuplicatePreviewImage].clone(), &settings.check_button_settings_show_preview_duplicates.is_active(), ); + saving_struct.save_var(hashmap_ls[&LoadText::HideHardLinks].clone(), &settings.check_button_settings_hide_hard_links.is_active()); + saving_struct.save_var(hashmap_ls[&LoadText::UseCache].clone(), &settings.check_button_settings_use_cache.is_active()); + saving_struct.save_var(hashmap_ls[&LoadText::UseJsonCacheFile].clone(), &settings.check_button_settings_save_also_json.is_active()); + saving_struct.save_var(hashmap_ls[&LoadText::DeleteToTrash].clone(), &settings.check_button_settings_use_trash.is_active()); saving_struct.save_var( - hashmap_ls.get(&LoadText::HideHardLinks).unwrap().to_string(), - &settings.check_button_settings_hide_hard_links.is_active(), - ); - saving_struct.save_var( - hashmap_ls.get(&LoadText::UseCache).unwrap().to_string(), - &settings.check_button_settings_use_cache.is_active(), - ); - saving_struct.save_var( - hashmap_ls.get(&LoadText::UseJsonCacheFile).unwrap().to_string(), - &settings.check_button_settings_save_also_json.is_active(), - ); - saving_struct.save_var( - hashmap_ls.get(&LoadText::DeleteToTrash).unwrap().to_string(), - &settings.check_button_settings_use_trash.is_active(), - ); - saving_struct.save_var( - hashmap_ls.get(&LoadText::ImageDeleteOutdatedCacheEntries).unwrap().to_string(), + hashmap_ls[&LoadText::ImageDeleteOutdatedCacheEntries].clone(), &settings.check_button_settings_similar_images_delete_outdated_cache.is_active(), ); saving_struct.save_var( - hashmap_ls.get(&LoadText::DuplicateDeleteOutdatedCacheEntries).unwrap().to_string(), + hashmap_ls[&LoadText::DuplicateDeleteOutdatedCacheEntries].clone(), &settings.check_button_settings_duplicates_delete_outdated_cache.is_active(), ); saving_struct.save_var( - hashmap_ls.get(&LoadText::VideoDeleteOutdatedCacheEntries).unwrap().to_string(), + hashmap_ls[&LoadText::VideoDeleteOutdatedCacheEntries].clone(), &settings.check_button_settings_similar_videos_delete_outdated_cache.is_active(), ); saving_struct.save_var( - hashmap_ls.get(&LoadText::UsePrehashCache).unwrap().to_string(), + hashmap_ls[&LoadText::UsePrehashCache].clone(), &settings.check_button_duplicates_use_prehash_cache.is_active(), ); saving_struct.save_var( - hashmap_ls.get(&LoadText::ShowBottomTextPanel).unwrap().to_string(), + hashmap_ls[&LoadText::ShowBottomTextPanel].clone(), &settings.check_button_settings_show_text_view.is_active(), ); saving_struct.save_var( - hashmap_ls.get(&LoadText::GeneralIgnoreOtherFilesystems).unwrap().to_string(), + hashmap_ls[&LoadText::GeneralIgnoreOtherFilesystems].clone(), &settings.check_button_settings_one_filesystem.is_active(), ); saving_struct.save_var( - hashmap_ls.get(&LoadText::BrokenFilesArchive).unwrap().to_string(), + hashmap_ls[&LoadText::BrokenFilesArchive].clone(), &main_notebook.check_button_broken_files_archive.is_active(), ); - saving_struct.save_var( - hashmap_ls.get(&LoadText::BrokenFilesImage).unwrap().to_string(), - &main_notebook.check_button_broken_files_image.is_active(), - ); - saving_struct.save_var( - hashmap_ls.get(&LoadText::BrokenFilesAudio).unwrap().to_string(), - &main_notebook.check_button_broken_files_audio.is_active(), - ); - saving_struct.save_var( - hashmap_ls.get(&LoadText::BrokenFilesPdf).unwrap().to_string(), - &main_notebook.check_button_broken_files_pdf.is_active(), - ); + saving_struct.save_var(hashmap_ls[&LoadText::BrokenFilesImage].clone(), &main_notebook.check_button_broken_files_image.is_active()); + saving_struct.save_var(hashmap_ls[&LoadText::BrokenFilesAudio].clone(), &main_notebook.check_button_broken_files_audio.is_active()); + saving_struct.save_var(hashmap_ls[&LoadText::BrokenFilesPdf].clone(), &main_notebook.check_button_broken_files_pdf.is_active()); // Others + saving_struct.save_var(hashmap_ls[&LoadText::ThreadNumber].clone(), &settings.scale_settings_number_of_threads.value().round()); + saving_struct.save_var(hashmap_ls[&LoadText::MinimalCacheSize].clone(), &settings.entry_settings_cache_file_minimal_size.text()); saving_struct.save_var( - hashmap_ls.get(&LoadText::ThreadNumber).unwrap().to_string(), - &settings.scale_settings_number_of_threads.value().round(), - ); - saving_struct.save_var( - hashmap_ls.get(&LoadText::MinimalCacheSize).unwrap().to_string(), - &settings.entry_settings_cache_file_minimal_size.text(), - ); - saving_struct.save_var( - hashmap_ls.get(&LoadText::MinimalPrehashCacheSize).unwrap().to_string(), + hashmap_ls[&LoadText::MinimalPrehashCacheSize].clone(), &settings.entry_settings_prehash_cache_file_minimal_size.text(), ); saving_struct.save_var( - hashmap_ls.get(&LoadText::Language).unwrap().to_string(), + hashmap_ls[&LoadText::Language].clone(), &get_language_from_combo_box_text(&settings.combo_box_settings_language.active_text().unwrap()).short_text, ); // Comboboxes main notebook saving_struct.save_var( - hashmap_ls.get(&LoadText::ComboBoxDuplicateHashType).unwrap().to_string(), + hashmap_ls[&LoadText::ComboBoxDuplicateHashType].clone(), &main_notebook.combo_box_duplicate_hash_type.active().unwrap_or(0), ); saving_struct.save_var( - hashmap_ls.get(&LoadText::ComboBoxDuplicateCheckMethod).unwrap().to_string(), + hashmap_ls[&LoadText::ComboBoxDuplicateCheckMethod].clone(), &main_notebook.combo_box_duplicate_check_method.active().unwrap_or(0), ); saving_struct.save_var( - hashmap_ls.get(&LoadText::ComboBoxImageResizeAlgorithm).unwrap().to_string(), + hashmap_ls[&LoadText::ComboBoxImageResizeAlgorithm].clone(), &main_notebook.combo_box_image_resize_algorithm.active().unwrap_or(0), ); saving_struct.save_var( - hashmap_ls.get(&LoadText::ComboBoxImageHashType).unwrap().to_string(), + hashmap_ls[&LoadText::ComboBoxImageHashType].clone(), &main_notebook.combo_box_image_hash_algorithm.active().unwrap_or(0), ); saving_struct.save_var( - hashmap_ls.get(&LoadText::ComboBoxImageHashSize).unwrap().to_string(), + hashmap_ls[&LoadText::ComboBoxImageHashSize].clone(), &main_notebook.combo_box_image_hash_size.active().unwrap_or(0), ); saving_struct.save_var( - hashmap_ls.get(&LoadText::ComboBoxBigFiles).unwrap().to_string(), + hashmap_ls[&LoadText::ComboBoxBigFiles].clone(), &main_notebook.combo_box_big_files_mode.active().unwrap_or(0), ); // Other2 saving_struct.save_var( - hashmap_ls.get(&LoadText::DuplicateNameCaseSensitive).unwrap().to_string(), + hashmap_ls[&LoadText::DuplicateNameCaseSensitive].clone(), &main_notebook.check_button_duplicate_case_sensitive_name.is_active(), ); + saving_struct.save_var(hashmap_ls[&LoadText::NumberOfBiggestFiles].clone(), &main_notebook.entry_big_files_number.text()); saving_struct.save_var( - hashmap_ls.get(&LoadText::NumberOfBiggestFiles).unwrap().to_string(), - &main_notebook.entry_big_files_number.text(), - ); - saving_struct.save_var( - hashmap_ls.get(&LoadText::SimilarImagesSimilarity).unwrap().to_string(), + hashmap_ls[&LoadText::SimilarImagesSimilarity].clone(), &main_notebook.scale_similarity_similar_images.value(), ); saving_struct.save_var( - hashmap_ls.get(&LoadText::SimilarImagesIgnoreSameSize).unwrap().to_string(), + hashmap_ls[&LoadText::SimilarImagesIgnoreSameSize].clone(), &main_notebook.check_button_image_ignore_same_size.is_active(), ); saving_struct.save_var( - hashmap_ls.get(&LoadText::SimilarVideosSimilarity).unwrap().to_string(), + hashmap_ls[&LoadText::SimilarVideosSimilarity].clone(), &main_notebook.scale_similarity_similar_videos.value(), ); saving_struct.save_var( - hashmap_ls.get(&LoadText::SimilarVideosIgnoreSameSize).unwrap().to_string(), + hashmap_ls[&LoadText::SimilarVideosIgnoreSameSize].clone(), &main_notebook.check_button_video_ignore_same_size.is_active(), ); saving_struct.save_var( - hashmap_ls.get(&LoadText::MusicApproximateComparison).unwrap().to_string(), + hashmap_ls[&LoadText::MusicApproximateComparison].clone(), &main_notebook.check_button_music_approximate_comparison.is_active(), ); @@ -672,83 +627,59 @@ pub fn load_configuration( // Loading data from hashmaps let (hashmap_ls, _hashmap_sl) = create_hash_map(); - let mut included_directories: Vec = loaded_entries.get_vector_string(hashmap_ls.get(&LoadText::IncludedDirectories).unwrap(), included_directories); - let mut excluded_directories: Vec = loaded_entries.get_vector_string(hashmap_ls.get(&LoadText::ExcludedDirectories).unwrap(), excluded_directories); - let excluded_items: String = loaded_entries.get_string( - hashmap_ls.get(&LoadText::ExcludedItems).unwrap().clone(), - upper_notebook.entry_excluded_items.text().to_string(), - ); - let allowed_extensions: String = loaded_entries.get_string(hashmap_ls.get(&LoadText::AllowedExtensions).unwrap().clone(), String::new()); - let minimal_file_size: String = loaded_entries.get_integer_string(hashmap_ls.get(&LoadText::MinimalFileSize).unwrap().clone(), DEFAULT_MINIMAL_FILE_SIZE.to_string()); - let maximal_file_size: String = loaded_entries.get_integer_string(hashmap_ls.get(&LoadText::MaximalFileSize).unwrap().clone(), DEFAULT_MAXIMAL_FILE_SIZE.to_string()); + let mut included_directories: Vec = loaded_entries.get_vector_string(&hashmap_ls[&LoadText::IncludedDirectories], included_directories); + let mut excluded_directories: Vec = loaded_entries.get_vector_string(&hashmap_ls[&LoadText::ExcludedDirectories], excluded_directories); + let excluded_items: String = loaded_entries.get_string(hashmap_ls[&LoadText::ExcludedItems].clone(), upper_notebook.entry_excluded_items.text().to_string()); + let allowed_extensions: String = loaded_entries.get_string(hashmap_ls[&LoadText::AllowedExtensions].clone(), String::new()); + let minimal_file_size: String = loaded_entries.get_integer_string(hashmap_ls[&LoadText::MinimalFileSize].clone(), DEFAULT_MINIMAL_FILE_SIZE.to_string()); + let maximal_file_size: String = loaded_entries.get_integer_string(hashmap_ls[&LoadText::MaximalFileSize].clone(), DEFAULT_MAXIMAL_FILE_SIZE.to_string()); - let loading_at_start: bool = loaded_entries.get_bool(hashmap_ls.get(&LoadText::LoadAtStart).unwrap().clone(), DEFAULT_LOAD_AT_START); - let mut saving_at_exit: bool = loaded_entries.get_bool(hashmap_ls.get(&LoadText::SaveAtExit).unwrap().clone(), DEFAULT_SAVE_ON_EXIT); - let confirm_deletion: bool = loaded_entries.get_bool(hashmap_ls.get(&LoadText::ConfirmDeletionFiles).unwrap().clone(), DEFAULT_CONFIRM_DELETION); - let confirm_group_deletion: bool = loaded_entries.get_bool(hashmap_ls.get(&LoadText::ConfirmDeletionAllFilesInGroup).unwrap().clone(), DEFAULT_CONFIRM_GROUP_DELETION); - let show_previews_similar_images: bool = loaded_entries.get_bool(hashmap_ls.get(&LoadText::ImagePreviewImage).unwrap().clone(), DEFAULT_SHOW_IMAGE_PREVIEW); - let show_previews_duplicates: bool = loaded_entries.get_bool(hashmap_ls.get(&LoadText::DuplicatePreviewImage).unwrap().clone(), DEFAULT_SHOW_DUPLICATE_IMAGE_PREVIEW); - let bottom_text_panel: bool = loaded_entries.get_bool(hashmap_ls.get(&LoadText::ShowBottomTextPanel).unwrap().clone(), DEFAULT_BOTTOM_TEXT_VIEW); - let hide_hard_links: bool = loaded_entries.get_bool(hashmap_ls.get(&LoadText::HideHardLinks).unwrap().clone(), DEFAULT_HIDE_HARD_LINKS); - let use_cache: bool = loaded_entries.get_bool(hashmap_ls.get(&LoadText::UseCache).unwrap().clone(), DEFAULT_USE_CACHE); - let use_json_cache: bool = loaded_entries.get_bool(hashmap_ls.get(&LoadText::UseJsonCacheFile).unwrap().clone(), DEFAULT_SAVE_ALSO_AS_JSON); - let use_trash: bool = loaded_entries.get_bool(hashmap_ls.get(&LoadText::DeleteToTrash).unwrap().clone(), DEFAULT_USE_TRASH); - let ignore_other_fs: bool = loaded_entries.get_bool( - hashmap_ls.get(&LoadText::GeneralIgnoreOtherFilesystems).unwrap().clone(), - DEFAULT_GENERAL_IGNORE_OTHER_FILESYSTEMS, - ); + let loading_at_start: bool = loaded_entries.get_bool(hashmap_ls[&LoadText::LoadAtStart].clone(), DEFAULT_LOAD_AT_START); + let mut saving_at_exit: bool = loaded_entries.get_bool(hashmap_ls[&LoadText::SaveAtExit].clone(), DEFAULT_SAVE_ON_EXIT); + let confirm_deletion: bool = loaded_entries.get_bool(hashmap_ls[&LoadText::ConfirmDeletionFiles].clone(), DEFAULT_CONFIRM_DELETION); + let confirm_group_deletion: bool = loaded_entries.get_bool(hashmap_ls[&LoadText::ConfirmDeletionAllFilesInGroup].clone(), DEFAULT_CONFIRM_GROUP_DELETION); + let show_previews_similar_images: bool = loaded_entries.get_bool(hashmap_ls[&LoadText::ImagePreviewImage].clone(), DEFAULT_SHOW_IMAGE_PREVIEW); + let show_previews_duplicates: bool = loaded_entries.get_bool(hashmap_ls[&LoadText::DuplicatePreviewImage].clone(), DEFAULT_SHOW_DUPLICATE_IMAGE_PREVIEW); + let bottom_text_panel: bool = loaded_entries.get_bool(hashmap_ls[&LoadText::ShowBottomTextPanel].clone(), DEFAULT_BOTTOM_TEXT_VIEW); + let hide_hard_links: bool = loaded_entries.get_bool(hashmap_ls[&LoadText::HideHardLinks].clone(), DEFAULT_HIDE_HARD_LINKS); + let use_cache: bool = loaded_entries.get_bool(hashmap_ls[&LoadText::UseCache].clone(), DEFAULT_USE_CACHE); + let use_json_cache: bool = loaded_entries.get_bool(hashmap_ls[&LoadText::UseJsonCacheFile].clone(), DEFAULT_SAVE_ALSO_AS_JSON); + let use_trash: bool = loaded_entries.get_bool(hashmap_ls[&LoadText::DeleteToTrash].clone(), DEFAULT_USE_TRASH); + let ignore_other_fs: bool = loaded_entries.get_bool(hashmap_ls[&LoadText::GeneralIgnoreOtherFilesystems].clone(), DEFAULT_GENERAL_IGNORE_OTHER_FILESYSTEMS); let delete_outdated_cache_duplicates: bool = loaded_entries.get_bool( - hashmap_ls.get(&LoadText::DuplicateDeleteOutdatedCacheEntries).unwrap().clone(), + hashmap_ls[&LoadText::DuplicateDeleteOutdatedCacheEntries].clone(), DEFAULT_DUPLICATE_REMOVE_AUTO_OUTDATED_CACHE, ); - let delete_outdated_cache_similar_images: bool = loaded_entries.get_bool( - hashmap_ls.get(&LoadText::ImageDeleteOutdatedCacheEntries).unwrap().clone(), - DEFAULT_IMAGE_REMOVE_AUTO_OUTDATED_CACHE, - ); - let delete_outdated_cache_similar_videos: bool = loaded_entries.get_bool( - hashmap_ls.get(&LoadText::VideoDeleteOutdatedCacheEntries).unwrap().clone(), - DEFAULT_VIDEO_REMOVE_AUTO_OUTDATED_CACHE, - ); - let use_prehash_cache: bool = loaded_entries.get_bool(hashmap_ls.get(&LoadText::UsePrehashCache).unwrap().clone(), DEFAULT_USE_PRECACHE); + let delete_outdated_cache_similar_images: bool = + loaded_entries.get_bool(hashmap_ls[&LoadText::ImageDeleteOutdatedCacheEntries].clone(), DEFAULT_IMAGE_REMOVE_AUTO_OUTDATED_CACHE); + let delete_outdated_cache_similar_videos: bool = + loaded_entries.get_bool(hashmap_ls[&LoadText::VideoDeleteOutdatedCacheEntries].clone(), DEFAULT_VIDEO_REMOVE_AUTO_OUTDATED_CACHE); + let use_prehash_cache: bool = loaded_entries.get_bool(hashmap_ls[&LoadText::UsePrehashCache].clone(), DEFAULT_USE_PRECACHE); - let cache_prehash_minimal_size: String = loaded_entries.get_integer_string( - hashmap_ls.get(&LoadText::MinimalPrehashCacheSize).unwrap().clone(), - DEFAULT_PREHASH_MINIMAL_CACHE_SIZE.to_string(), - ); - let cache_minimal_size: String = loaded_entries.get_integer_string(hashmap_ls.get(&LoadText::MinimalCacheSize).unwrap().clone(), DEFAULT_MINIMAL_CACHE_SIZE.to_string()); - let short_language = loaded_entries.get_string(hashmap_ls.get(&LoadText::Language).unwrap().clone(), short_language); + let cache_prehash_minimal_size: String = + loaded_entries.get_integer_string(hashmap_ls[&LoadText::MinimalPrehashCacheSize].clone(), DEFAULT_PREHASH_MINIMAL_CACHE_SIZE.to_string()); + let cache_minimal_size: String = loaded_entries.get_integer_string(hashmap_ls[&LoadText::MinimalCacheSize].clone(), DEFAULT_MINIMAL_CACHE_SIZE.to_string()); + let short_language = loaded_entries.get_string(hashmap_ls[&LoadText::Language].clone(), short_language); - let combo_box_duplicate_hash_type = loaded_entries.get_object(hashmap_ls.get(&LoadText::ComboBoxDuplicateHashType).unwrap().clone(), 0); - let combo_box_duplicate_checking_method = loaded_entries.get_object(hashmap_ls.get(&LoadText::ComboBoxDuplicateCheckMethod).unwrap().clone(), 0); - let combo_box_image_hash_size = loaded_entries.get_object(hashmap_ls.get(&LoadText::ComboBoxImageHashSize).unwrap().clone(), 1); // 16 instead default 8 - let combo_box_image_hash_algorithm = loaded_entries.get_object(hashmap_ls.get(&LoadText::ComboBoxImageHashType).unwrap().clone(), 0); - let combo_box_image_resize_algorithm = loaded_entries.get_object(hashmap_ls.get(&LoadText::ComboBoxImageResizeAlgorithm).unwrap().clone(), 0); - let combo_box_big_files_mode = loaded_entries.get_object(hashmap_ls.get(&LoadText::ComboBoxBigFiles).unwrap().clone(), 0); + let combo_box_duplicate_hash_type = loaded_entries.get_object(hashmap_ls[&LoadText::ComboBoxDuplicateHashType].clone(), 0); + let combo_box_duplicate_checking_method = loaded_entries.get_object(hashmap_ls[&LoadText::ComboBoxDuplicateCheckMethod].clone(), 0); + let combo_box_image_hash_size = loaded_entries.get_object(hashmap_ls[&LoadText::ComboBoxImageHashSize].clone(), 1); // 16 instead default 8 + let combo_box_image_hash_algorithm = loaded_entries.get_object(hashmap_ls[&LoadText::ComboBoxImageHashType].clone(), 0); + let combo_box_image_resize_algorithm = loaded_entries.get_object(hashmap_ls[&LoadText::ComboBoxImageResizeAlgorithm].clone(), 0); + let combo_box_big_files_mode = loaded_entries.get_object(hashmap_ls[&LoadText::ComboBoxBigFiles].clone(), 0); - let number_of_biggest_files = loaded_entries.get_integer_string( - hashmap_ls.get(&LoadText::NumberOfBiggestFiles).unwrap().clone(), - DEFAULT_NUMBER_OF_BIGGEST_FILES.to_string(), - ); - let similar_images_similarity = loaded_entries.get_object(hashmap_ls.get(&LoadText::SimilarImagesSimilarity).unwrap().clone(), DEFAULT_SIMILAR_IMAGES_SIMILARITY); - let similar_images_ignore_same_size = loaded_entries.get_bool( - hashmap_ls.get(&LoadText::SimilarImagesIgnoreSameSize).unwrap().clone(), - DEFAULT_SIMILAR_IMAGES_IGNORE_SAME_SIZE, - ); - let similar_videos_similarity = loaded_entries.get_object(hashmap_ls.get(&LoadText::SimilarVideosSimilarity).unwrap().clone(), DEFAULT_SIMILAR_VIDEOS_SIMILARITY); - let similar_videos_ignore_same_size = loaded_entries.get_bool( - hashmap_ls.get(&LoadText::SimilarVideosIgnoreSameSize).unwrap().clone(), - DEFAULT_SIMILAR_VIDEOS_IGNORE_SAME_SIZE, - ); - let check_button_case_sensitive_name = loaded_entries.get_object( - hashmap_ls.get(&LoadText::DuplicateNameCaseSensitive).unwrap().clone(), - DEFAULT_DUPLICATE_CASE_SENSITIVE_NAME_CHECKING, - ); + let number_of_biggest_files = loaded_entries.get_integer_string(hashmap_ls[&LoadText::NumberOfBiggestFiles].clone(), DEFAULT_NUMBER_OF_BIGGEST_FILES.to_string()); + let similar_images_similarity = loaded_entries.get_object(hashmap_ls[&LoadText::SimilarImagesSimilarity].clone(), DEFAULT_SIMILAR_IMAGES_SIMILARITY); + let similar_images_ignore_same_size = loaded_entries.get_bool(hashmap_ls[&LoadText::SimilarImagesIgnoreSameSize].clone(), DEFAULT_SIMILAR_IMAGES_IGNORE_SAME_SIZE); + let similar_videos_similarity = loaded_entries.get_object(hashmap_ls[&LoadText::SimilarVideosSimilarity].clone(), DEFAULT_SIMILAR_VIDEOS_SIMILARITY); + let similar_videos_ignore_same_size = loaded_entries.get_bool(hashmap_ls[&LoadText::SimilarVideosIgnoreSameSize].clone(), DEFAULT_SIMILAR_VIDEOS_IGNORE_SAME_SIZE); + let check_button_case_sensitive_name = loaded_entries.get_object(hashmap_ls[&LoadText::DuplicateNameCaseSensitive].clone(), DEFAULT_DUPLICATE_CASE_SENSITIVE_NAME_CHECKING); - let check_button_broken_files_archive = loaded_entries.get_object(hashmap_ls.get(&LoadText::BrokenFilesArchive).unwrap().clone(), DEFAULT_BROKEN_FILES_ARCHIVE); - let check_button_broken_files_pdf = loaded_entries.get_object(hashmap_ls.get(&LoadText::BrokenFilesPdf).unwrap().clone(), DEFAULT_BROKEN_FILES_PDF); - let check_button_broken_files_image = loaded_entries.get_object(hashmap_ls.get(&LoadText::BrokenFilesImage).unwrap().clone(), DEFAULT_BROKEN_FILES_IMAGE); - let check_button_broken_files_audio = loaded_entries.get_object(hashmap_ls.get(&LoadText::BrokenFilesAudio).unwrap().clone(), DEFAULT_BROKEN_FILES_AUDIO); - let thread_number = loaded_entries.get_object(hashmap_ls.get(&LoadText::ThreadNumber).unwrap().clone(), DEFAULT_THREAD_NUMBER); + let check_button_broken_files_archive = loaded_entries.get_object(hashmap_ls[&LoadText::BrokenFilesArchive].clone(), DEFAULT_BROKEN_FILES_ARCHIVE); + let check_button_broken_files_pdf = loaded_entries.get_object(hashmap_ls[&LoadText::BrokenFilesPdf].clone(), DEFAULT_BROKEN_FILES_PDF); + let check_button_broken_files_image = loaded_entries.get_object(hashmap_ls[&LoadText::BrokenFilesImage].clone(), DEFAULT_BROKEN_FILES_IMAGE); + let check_button_broken_files_audio = loaded_entries.get_object(hashmap_ls[&LoadText::BrokenFilesAudio].clone(), DEFAULT_BROKEN_FILES_AUDIO); + let thread_number = loaded_entries.get_object(hashmap_ls[&LoadText::ThreadNumber].clone(), DEFAULT_THREAD_NUMBER); let mut set_start_folders = false; if !manual_execution { diff --git a/krokiet/src/connect_show_preview.rs b/krokiet/src/connect_show_preview.rs index 720a1de..ccdcc1c 100644 --- a/krokiet/src/connect_show_preview.rs +++ b/krokiet/src/connect_show_preview.rs @@ -7,7 +7,7 @@ use slint::ComponentHandle; use czkawka_core::common::{get_dynamic_image_from_raw_image, IMAGE_RS_EXTENSIONS, RAW_IMAGE_EXTENSIONS}; -use crate::{Callabler, GuiState, MainWindow}; +use crate::{Callabler, CurrentTab, GuiState, MainWindow, Settings}; pub type ImageBufferRgba = image::ImageBuffer, Vec>; @@ -16,6 +16,16 @@ pub fn connect_show_preview(app: &MainWindow) { app.global::().on_load_image_preview(move |image_path| { let app = a.upgrade().unwrap(); + let settings = app.global::(); + let gui_state = app.global::(); + + let active_tab = gui_state.get_active_tab(); + + if active_tab == CurrentTab::SimilarImages && !settings.get_similar_images_show_image_preview() { + gui_state.set_preview_visible(false); + return; + } + let path = Path::new(image_path.as_str()); let res = load_image(path); @@ -25,16 +35,16 @@ pub fn connect_show_preview(app: &MainWindow) { let convert_time = start_timer_convert_time.elapsed(); let start_set_time = Instant::now(); - app.global::().set_preview_image(slint_image); + gui_state.set_preview_image(slint_image); let set_time = start_set_time.elapsed(); debug!( "Loading image took: {:?}, converting image took: {:?}, setting image took: {:?}", load_time, convert_time, set_time ); - app.global::().set_preview_visible(true); + gui_state.set_preview_visible(true); } else { - app.global::().set_preview_visible(false); + gui_state.set_preview_visible(false); } }); }