From 0a924d2355b1d1f435d041e3962b47bebaf335ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mikrut?= <41945903+qarmin@users.noreply.github.com> Date: Sun, 19 Dec 2021 14:45:10 +0100 Subject: [PATCH] Improve translations (#507) * Improve translations * Imports --- czkawka_core/src/big_file.rs | 17 +-- czkawka_core/src/broken_files.rs | 17 +-- czkawka_core/src/duplicate.rs | 32 +++--- czkawka_core/src/empty_files.rs | 19 ++-- czkawka_core/src/empty_folder.rs | 22 +++- czkawka_core/src/invalid_symlinks.rs | 17 +-- czkawka_core/src/localizer.rs | 10 ++ czkawka_core/src/same_music.rs | 17 +-- czkawka_core/src/similar_images.rs | 16 +-- czkawka_core/src/similar_videos.rs | 17 +-- czkawka_core/src/temporary.rs | 17 +-- czkawka_gui/src/compute_results.rs | 2 +- czkawka_gui/src/connect_button_delete.rs | 24 +++-- czkawka_gui/src/connect_button_hardlink.rs | 20 +++- czkawka_gui/src/connect_button_move.rs | 16 ++- czkawka_gui/src/connect_button_save.rs | 3 +- czkawka_gui/src/connect_button_search.rs | 2 +- czkawka_gui/src/connect_change_language.rs | 6 +- czkawka_gui/src/connect_duplicate_buttons.rs | 3 +- czkawka_gui/src/connect_popovers.rs | 2 +- czkawka_gui/src/connect_progress_window.rs | 63 +++++++---- .../src/connect_selection_of_directories.rs | 3 +- czkawka_gui/src/connect_settings.rs | 12 ++- czkawka_gui/src/gui_about.rs | 3 +- czkawka_gui/src/gui_bottom_buttons.rs | 5 +- czkawka_gui/src/gui_header.rs | 3 +- czkawka_gui/src/gui_main_notebook.rs | 7 +- czkawka_gui/src/gui_popovers.rs | 3 +- czkawka_gui/src/gui_progress_dialog.rs | 5 +- czkawka_gui/src/gui_settings.rs | 19 +++- czkawka_gui/src/gui_upper_notebook.rs | 5 +- czkawka_gui/src/help_combo_box.rs | 3 +- czkawka_gui/src/initialize_gui.rs | 24 ++++- czkawka_gui/src/opening_selecting_records.rs | 3 +- czkawka_gui/src/saving_loading.rs | 100 +++++++++++++++--- czkawka_gui/ui/settings.glade | 2 +- i18n/en/czkawka_gui.ftl | 69 ++++++++---- i18n/pl/czkawka_gui.ftl | 63 +++++++---- 38 files changed, 477 insertions(+), 194 deletions(-) diff --git a/czkawka_core/src/big_file.rs b/czkawka_core/src/big_file.rs index 01f18f8..9351515 100644 --- a/czkawka_core/src/big_file.rs +++ b/czkawka_core/src/big_file.rs @@ -20,6 +20,8 @@ use crate::common_extensions::Extensions; use crate::common_items::ExcludedItems; use crate::common_messages::Messages; use crate::common_traits::{DebugPrint, PrintResults, SaveResults}; +use crate::fl; +use crate::localizer::generate_translation_hashmap; #[derive(Debug)] pub struct ProgressData { @@ -173,7 +175,7 @@ impl BigFile { let read_dir = match fs::read_dir(¤t_folder) { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot open dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_open_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); return (dir_result, warnings, fe_result); } }; @@ -183,14 +185,14 @@ impl BigFile { let entry_data = match entry { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot read entry in dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_read_entry_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); continue 'dir; } }; let metadata: Metadata = match entry_data.metadata() { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot read metadata in dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_read_metadata_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); continue 'dir; } }; @@ -215,7 +217,7 @@ impl BigFile { let file_name_lowercase: String = match entry_data.file_name().into_string() { Ok(t) => t, Err(_inspected) => { - warnings.push(format!("File {:?} has not valid UTF-8 name", entry_data)); + warnings.push(fl!("core_file_not_utf8_name", generate_translation_hashmap(vec![("name", entry_data.path().display().to_string())]))); continue 'dir; } } @@ -237,12 +239,15 @@ impl BigFile { Ok(t) => match t.duration_since(UNIX_EPOCH) { Ok(d) => d.as_secs(), Err(_inspected) => { - warnings.push(format!("File {} seems to be modified before Unix Epoch.", current_file_name.display())); + warnings.push(fl!("core_file_modified_before_epoch", generate_translation_hashmap(vec![("name", current_file_name.display().to_string())]))); 0 } }, Err(e) => { - warnings.push(format!("Unable to get modification date from file {}, reason {}", current_file_name.display(), e)); + warnings.push(fl!( + "core_file_no_modification_date", + generate_translation_hashmap(vec![("name", current_file_name.display().to_string()), ("reason", e.to_string())]) + )); 0 } }, diff --git a/czkawka_core/src/broken_files.rs b/czkawka_core/src/broken_files.rs index b9a70d2..e7e4cf0 100644 --- a/czkawka_core/src/broken_files.rs +++ b/czkawka_core/src/broken_files.rs @@ -19,6 +19,8 @@ use crate::common_extensions::Extensions; use crate::common_items::ExcludedItems; use crate::common_messages::Messages; use crate::common_traits::*; +use crate::fl; +use crate::localizer::generate_translation_hashmap; const CACHE_FILE_NAME: &str = "cache_broken_files.txt"; @@ -213,7 +215,7 @@ impl BrokenFiles { let read_dir = match fs::read_dir(¤t_folder) { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot open dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_open_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); return (dir_result, warnings, fe_result); } }; @@ -223,14 +225,14 @@ impl BrokenFiles { let entry_data = match entry { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot read entry in dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_read_entry_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); continue 'dir; } }; let metadata: Metadata = match entry_data.metadata() { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot read metadata in dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_read_metadata_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); continue 'dir; } }; @@ -255,7 +257,7 @@ impl BrokenFiles { let file_name_lowercase: String = match entry_data.file_name().into_string() { Ok(t) => t, Err(_inspected) => { - warnings.push(format!("File {:?} has not valid UTF-8 name", entry_data)); + warnings.push(fl!("core_file_not_utf8_name", generate_translation_hashmap(vec![("name", entry_data.path().display().to_string())]))); continue 'dir; } } @@ -281,12 +283,15 @@ impl BrokenFiles { Ok(t) => match t.duration_since(UNIX_EPOCH) { Ok(d) => d.as_secs(), Err(_inspected) => { - warnings.push(format!("File {} seems to be modified before Unix Epoch.", current_file_name.display())); + warnings.push(fl!("core_file_modified_before_epoch", generate_translation_hashmap(vec![("name", current_file_name.display().to_string())]))); 0 } }, Err(e) => { - warnings.push(format!("Unable to get modification date from file {}, reason {}", current_file_name.display(), e)); + warnings.push(fl!( + "core_file_no_modification_date", + generate_translation_hashmap(vec![("name", current_file_name.display().to_string()), ("reason", e.to_string())]) + )); 0 } }, diff --git a/czkawka_core/src/duplicate.rs b/czkawka_core/src/duplicate.rs index 26ad426..e578c50 100644 --- a/czkawka_core/src/duplicate.rs +++ b/czkawka_core/src/duplicate.rs @@ -26,6 +26,8 @@ use crate::common_extensions::Extensions; use crate::common_items::ExcludedItems; use crate::common_messages::Messages; use crate::common_traits::*; +use crate::fl; +use crate::localizer::generate_translation_hashmap; #[derive(Debug)] pub struct ProgressData { @@ -345,7 +347,7 @@ impl DuplicateFinder { let read_dir = match fs::read_dir(¤t_folder) { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot open dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_open_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); return (dir_result, warnings, fe_result); } }; @@ -355,14 +357,14 @@ impl DuplicateFinder { let entry_data = match entry { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot read entry in dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_read_entry_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); continue 'dir; } }; let metadata: Metadata = match entry_data.metadata() { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot read metadata in dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_read_metadata_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); continue 'dir; } }; @@ -387,7 +389,7 @@ impl DuplicateFinder { let file_name_lowercase: String = match entry_data.file_name().into_string() { Ok(t) => t, Err(_inspected) => { - warnings.push(format!("File {:?} has not valid UTF-8 name", entry_data)); + warnings.push(fl!("core_file_not_utf8_name", generate_translation_hashmap(vec![("name", entry_data.path().display().to_string())]))); continue 'dir; } } @@ -410,12 +412,15 @@ impl DuplicateFinder { Ok(t) => match t.duration_since(UNIX_EPOCH) { Ok(d) => d.as_secs(), Err(_inspected) => { - warnings.push(format!("File {} seems to be modified before Unix Epoch.", current_file_name.display())); + warnings.push(fl!("core_file_modified_before_epoch", generate_translation_hashmap(vec![("name", current_file_name.display().to_string())]))); 0 } }, Err(e) => { - warnings.push(format!("Unable to get modification date from file {}, reason {}", current_file_name.display(), e)); + warnings.push(fl!( + "core_file_no_modification_date", + generate_translation_hashmap(vec![("name", current_file_name.display().to_string()), ("reason", e.to_string())]) + )); 0 } }, @@ -530,7 +535,7 @@ impl DuplicateFinder { let read_dir = match fs::read_dir(¤t_folder) { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot open dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_open_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); return (dir_result, warnings, fe_result); } }; @@ -540,14 +545,14 @@ impl DuplicateFinder { let entry_data = match entry { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot read entry in dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_read_entry_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); continue 'dir; } }; let metadata: Metadata = match entry_data.metadata() { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot read metadata in dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_read_metadata_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); continue 'dir; } }; @@ -572,7 +577,7 @@ impl DuplicateFinder { let file_name_lowercase: String = match entry_data.file_name().into_string() { Ok(t) => t, Err(_inspected) => { - warnings.push(format!("File {:?} has not valid UTF-8 name", entry_data)); + warnings.push(fl!("core_file_not_utf8_name", generate_translation_hashmap(vec![("name", entry_data.path().display().to_string())]))); continue 'dir; } } @@ -596,12 +601,15 @@ impl DuplicateFinder { Ok(t) => match t.duration_since(UNIX_EPOCH) { Ok(d) => d.as_secs(), Err(_inspected) => { - warnings.push(format!("File {} seems to be modified before Unix Epoch.", current_file_name.display())); + warnings.push(fl!("core_file_modified_before_epoch", generate_translation_hashmap(vec![("name", current_file_name.display().to_string())]))); 0 } }, Err(e) => { - warnings.push(format!("Unable to get modification date from file {}, reason {}", current_file_name.display(), e)); + warnings.push(fl!( + "core_file_no_modification_date", + generate_translation_hashmap(vec![("name", current_file_name.display().to_string()), ("reason", e.to_string())]) + )); 0 } }, diff --git a/czkawka_core/src/empty_files.rs b/czkawka_core/src/empty_files.rs index ec9625d..513ca56 100644 --- a/czkawka_core/src/empty_files.rs +++ b/czkawka_core/src/empty_files.rs @@ -1,4 +1,3 @@ -use rayon::prelude::*; use std::fs::{File, Metadata}; use std::io::prelude::*; use std::io::BufWriter; @@ -10,6 +9,7 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH}; use std::{fs, thread}; use crossbeam_channel::Receiver; +use rayon::prelude::*; use crate::common::Common; use crate::common_directory::Directories; @@ -17,6 +17,8 @@ use crate::common_extensions::Extensions; use crate::common_items::ExcludedItems; use crate::common_messages::Messages; use crate::common_traits::*; +use crate::fl; +use crate::localizer::generate_translation_hashmap; #[derive(Debug)] pub struct ProgressData { @@ -184,7 +186,7 @@ impl EmptyFiles { let read_dir = match fs::read_dir(¤t_folder) { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot open dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_open_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); return (dir_result, warnings, fe_result); } }; @@ -194,14 +196,14 @@ impl EmptyFiles { let entry_data = match entry { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot read entry in dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_read_entry_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); continue 'dir; } }; let metadata: Metadata = match entry_data.metadata() { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot read metadata in dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_read_metadata_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); continue 'dir; } }; @@ -226,7 +228,7 @@ impl EmptyFiles { let file_name_lowercase: String = match entry_data.file_name().into_string() { Ok(t) => t, Err(_inspected) => { - warnings.push(format!("File {:?} has not valid UTF-8 name", entry_data)); + warnings.push(fl!("core_file_not_utf8_name", generate_translation_hashmap(vec![("name", entry_data.path().display().to_string())]))); continue 'dir; } } @@ -248,12 +250,15 @@ impl EmptyFiles { Ok(t) => match t.duration_since(UNIX_EPOCH) { Ok(d) => d.as_secs(), Err(_inspected) => { - warnings.push(format!("File {} seems to be modified before Unix Epoch.", current_file_name.display())); + warnings.push(fl!("core_file_modified_before_epoch", generate_translation_hashmap(vec![("name", current_file_name.display().to_string())]))); 0 } }, Err(e) => { - warnings.push(format!("Unable to get modification date from file {}, reason {}", current_file_name.display(), e)); + warnings.push(fl!( + "core_file_no_modification_date", + generate_translation_hashmap(vec![("name", current_file_name.display().to_string()), ("reason", e.to_string())]) + )); 0 } }, diff --git a/czkawka_core/src/empty_folder.rs b/czkawka_core/src/empty_folder.rs index e58d176..06944ed 100644 --- a/czkawka_core/src/empty_folder.rs +++ b/czkawka_core/src/empty_folder.rs @@ -15,6 +15,8 @@ use crate::common_directory::Directories; use crate::common_items::ExcludedItems; use crate::common_messages::Messages; use crate::common_traits::{DebugPrint, PrintResults, SaveResults}; +use crate::fl; +use crate::localizer::generate_translation_hashmap; #[derive(Debug)] pub struct ProgressData { @@ -199,7 +201,9 @@ impl EmptyFolder { let read_dir = match fs::read_dir(¤t_folder) { Ok(t) => t, Err(e) => { - self.text_messages.warnings.push(format!("Cannot open dir {}, reason {}", current_folder.display(), e)); + self.text_messages + .warnings + .push(fl!("core_cannot_open_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); continue; } }; @@ -209,14 +213,18 @@ impl EmptyFolder { let entry_data = match entry { Ok(t) => t, Err(e) => { - self.text_messages.warnings.push(format!("Cannot read entry in dir {}, reason {}", current_folder.display(), e)); + self.text_messages + .warnings + .push(fl!("core_cannot_read_entry_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); continue 'dir; } }; let metadata: Metadata = match entry_data.metadata() { Ok(t) => t, Err(e) => { - self.text_messages.warnings.push(format!("Cannot read metadata in dir {}, reason {}", current_folder.display(), e)); + self.text_messages + .warnings + .push(fl!("core_cannot_read_metadata_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); continue 'dir; } }; @@ -237,12 +245,16 @@ impl EmptyFolder { Ok(t) => match t.duration_since(UNIX_EPOCH) { Ok(d) => d.as_secs(), Err(_inspected) => { - self.text_messages.warnings.push(format!("Folder {} seems to be modified before Unix Epoch.", current_folder.display())); + self.text_messages + .warnings + .push(fl!("core_folder_modified_before_epoch", generate_translation_hashmap(vec![("name", current_folder.display().to_string())]))); 0 } }, Err(e) => { - self.text_messages.warnings.push(format!("Failed to read modification date of folder {}, reason {}", current_folder.display(), e)); + self.text_messages + .warnings + .push(fl!("core_folder_no_modification_date", generate_translation_hashmap(vec![("name", current_folder.display().to_string()), ("reason", e.to_string())]))); 0 } }, diff --git a/czkawka_core/src/invalid_symlinks.rs b/czkawka_core/src/invalid_symlinks.rs index b3101ea..adfc312 100644 --- a/czkawka_core/src/invalid_symlinks.rs +++ b/czkawka_core/src/invalid_symlinks.rs @@ -17,6 +17,8 @@ use crate::common_extensions::Extensions; use crate::common_items::ExcludedItems; use crate::common_messages::Messages; use crate::common_traits::*; +use crate::fl; +use crate::localizer::generate_translation_hashmap; #[derive(Debug)] pub struct ProgressData { @@ -194,7 +196,7 @@ impl InvalidSymlinks { let read_dir = match fs::read_dir(¤t_folder) { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot open dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_open_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); return (dir_result, warnings, fe_result); } }; @@ -204,14 +206,14 @@ impl InvalidSymlinks { let entry_data = match entry { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot read entry in dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_read_entry_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); continue 'dir; } }; let metadata: Metadata = match entry_data.metadata() { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot read metadata in dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_read_metadata_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); continue 'dir; } }; @@ -238,7 +240,7 @@ impl InvalidSymlinks { let file_name_lowercase: String = match entry_data.file_name().into_string() { Ok(t) => t, Err(_inspected) => { - warnings.push(format!("File {:?} has not valid UTF-8 name", entry_data)); + warnings.push(fl!("core_file_not_utf8_name", generate_translation_hashmap(vec![("name", entry_data.path().display().to_string())]))); continue 'dir; } } @@ -297,12 +299,15 @@ impl InvalidSymlinks { Ok(t) => match t.duration_since(UNIX_EPOCH) { Ok(d) => d.as_secs(), Err(_inspected) => { - warnings.push(format!("File {} seems to be modified before Unix Epoch.", current_file_name.display())); + warnings.push(fl!("core_file_modified_before_epoch", generate_translation_hashmap(vec![("name", current_file_name.display().to_string())]))); 0 } }, Err(e) => { - warnings.push(format!("Unable to get modification date from file {}, reason {}", current_file_name.display(), e)); + warnings.push(fl!( + "core_file_no_modification_date", + generate_translation_hashmap(vec![("name", current_file_name.display().to_string()), ("reason", e.to_string())]) + )); 0 } }, diff --git a/czkawka_core/src/localizer.rs b/czkawka_core/src/localizer.rs index 3560fb1..b3a22ce 100644 --- a/czkawka_core/src/localizer.rs +++ b/czkawka_core/src/localizer.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use i18n_embed::{ fluent::{fluent_language_loader, FluentLanguageLoader}, DefaultLocalizer, LanguageLoader, Localizer, @@ -32,3 +34,11 @@ macro_rules! fl { pub fn localizer() -> Box { Box::from(DefaultLocalizer::new(&*LANGUAGE_LOADER, &Localizations)) } + +pub fn generate_translation_hashmap(vec: Vec<(&'static str, String)>) -> HashMap<&'static str, String> { + let mut hashmap: HashMap<&'static str, String> = Default::default(); + for (key, value) in vec { + hashmap.insert(key, value); + } + hashmap +} diff --git a/czkawka_core/src/same_music.rs b/czkawka_core/src/same_music.rs index be69feb..83daad4 100644 --- a/czkawka_core/src/same_music.rs +++ b/czkawka_core/src/same_music.rs @@ -19,6 +19,8 @@ use crate::common_extensions::Extensions; use crate::common_items::ExcludedItems; use crate::common_messages::Messages; use crate::common_traits::*; +use crate::fl; +use crate::localizer::generate_translation_hashmap; #[derive(Debug)] pub struct ProgressData { @@ -255,7 +257,7 @@ impl SameMusic { let read_dir = match fs::read_dir(¤t_folder) { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot open dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_open_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); return (dir_result, warnings, fe_result); } }; @@ -265,14 +267,14 @@ impl SameMusic { let entry_data = match entry { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot read entry in dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_read_entry_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); continue 'dir; } }; let metadata: Metadata = match entry_data.metadata() { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot read metadata in dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_read_metadata_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); continue 'dir; } }; @@ -297,7 +299,7 @@ impl SameMusic { let file_name_lowercase: String = match entry_data.file_name().into_string() { Ok(t) => t, Err(_inspected) => { - warnings.push(format!("File {:?} has not valid UTF-8 name", entry_data)); + warnings.push(fl!("core_file_not_utf8_name", generate_translation_hashmap(vec![("name", entry_data.path().display().to_string())]))); continue 'dir; } } @@ -321,12 +323,15 @@ impl SameMusic { Ok(t) => match t.duration_since(UNIX_EPOCH) { Ok(d) => d.as_secs(), Err(_inspected) => { - warnings.push(format!("File {} seems to be modified before Unix Epoch.", current_file_name.display())); + warnings.push(fl!("core_file_modified_before_epoch", generate_translation_hashmap(vec![("name", current_file_name.display().to_string())]))); 0 } }, Err(e) => { - warnings.push(format!("Unable to get modification date from file {}, reason {}", current_file_name.display(), e)); + warnings.push(fl!( + "core_file_no_modification_date", + generate_translation_hashmap(vec![("name", current_file_name.display().to_string()), ("reason", e.to_string())]) + )); 0 } }, diff --git a/czkawka_core/src/similar_images.rs b/czkawka_core/src/similar_images.rs index 947767b..9c67297 100644 --- a/czkawka_core/src/similar_images.rs +++ b/czkawka_core/src/similar_images.rs @@ -25,6 +25,7 @@ use crate::common_items::ExcludedItems; use crate::common_messages::Messages; use crate::common_traits::{DebugPrint, PrintResults, SaveResults}; use crate::fl; +use crate::localizer::generate_translation_hashmap; // TODO check for better values pub const SIMILAR_VALUES: [[u32; 6]; 4] = [ @@ -299,7 +300,7 @@ impl SimilarImages { let read_dir = match fs::read_dir(¤t_folder) { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot open dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_open_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); return (dir_result, warnings, fe_result); } }; @@ -309,14 +310,14 @@ impl SimilarImages { let entry_data = match entry { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot read entry in dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_read_entry_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); continue 'dir; } }; let metadata: Metadata = match entry_data.metadata() { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot read metadata in dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_read_metadata_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); continue 'dir; } }; @@ -341,7 +342,7 @@ impl SimilarImages { let file_name_lowercase: String = match entry_data.file_name().into_string() { Ok(t) => t, Err(_inspected) => { - warnings.push(format!("File {:?} has not valid UTF-8 name", entry_data)); + warnings.push(fl!("core_file_not_utf8_name", generate_translation_hashmap(vec![("name", entry_data.path().display().to_string())]))); continue 'dir; } } @@ -366,12 +367,15 @@ impl SimilarImages { Ok(t) => match t.duration_since(UNIX_EPOCH) { Ok(d) => d.as_secs(), Err(_inspected) => { - warnings.push(format!("File {} seems to be modified before Unix Epoch.", current_file_name.display())); + warnings.push(fl!("core_file_modified_before_epoch", generate_translation_hashmap(vec![("name", current_file_name.display().to_string())]))); 0 } }, Err(e) => { - warnings.push(format!("Unable to get modification date from file {}, reason {}", current_file_name.display(), e)); + warnings.push(fl!( + "core_file_no_modification_date", + generate_translation_hashmap(vec![("name", current_file_name.display().to_string()), ("reason", e.to_string())]) + )); 0 } }, diff --git a/czkawka_core/src/similar_videos.rs b/czkawka_core/src/similar_videos.rs index f97bf9e..82aadae 100644 --- a/czkawka_core/src/similar_videos.rs +++ b/czkawka_core/src/similar_videos.rs @@ -25,6 +25,8 @@ use crate::common_extensions::Extensions; use crate::common_items::ExcludedItems; use crate::common_messages::Messages; use crate::common_traits::{DebugPrint, PrintResults, SaveResults}; +use crate::fl; +use crate::localizer::generate_translation_hashmap; pub const MAX_TOLERANCE: i32 = 20; @@ -256,7 +258,7 @@ impl SimilarVideos { let read_dir = match fs::read_dir(¤t_folder) { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot open dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_open_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); return (dir_result, warnings, fe_result); } }; @@ -266,14 +268,14 @@ impl SimilarVideos { let entry_data = match entry { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot read entry in dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_read_entry_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); continue 'dir; } }; let metadata: Metadata = match entry_data.metadata() { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot read metadata in dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_read_metadata_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); continue 'dir; } }; @@ -298,7 +300,7 @@ impl SimilarVideos { let file_name_lowercase: String = match entry_data.file_name().into_string() { Ok(t) => t, Err(_inspected) => { - warnings.push(format!("File {:?} has not valid UTF-8 name", entry_data)); + warnings.push(fl!("core_file_not_utf8_name", generate_translation_hashmap(vec![("name", entry_data.path().display().to_string())]))); continue 'dir; } } @@ -322,12 +324,15 @@ impl SimilarVideos { Ok(t) => match t.duration_since(UNIX_EPOCH) { Ok(d) => d.as_secs(), Err(_inspected) => { - warnings.push(format!("File {} seems to be modified before Unix Epoch.", current_file_name.display())); + warnings.push(fl!("core_file_modified_before_epoch", generate_translation_hashmap(vec![("name", current_file_name.display().to_string())]))); 0 } }, Err(e) => { - warnings.push(format!("Unable to get modification date from file {}, reason {}", current_file_name.display(), e)); + warnings.push(fl!( + "core_file_no_modification_date", + generate_translation_hashmap(vec![("name", current_file_name.display().to_string()), ("reason", e.to_string())]) + )); 0 } }, diff --git a/czkawka_core/src/temporary.rs b/czkawka_core/src/temporary.rs index a8b84cf..eb381e1 100644 --- a/czkawka_core/src/temporary.rs +++ b/czkawka_core/src/temporary.rs @@ -16,6 +16,8 @@ use crate::common_directory::Directories; use crate::common_items::ExcludedItems; use crate::common_messages::Messages; use crate::common_traits::*; +use crate::fl; +use crate::localizer::generate_translation_hashmap; #[derive(Debug)] pub struct ProgressData { @@ -176,7 +178,7 @@ impl Temporary { let read_dir = match fs::read_dir(¤t_folder) { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot open dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_open_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); return (dir_result, warnings, fe_result); } }; @@ -186,14 +188,14 @@ impl Temporary { let entry_data = match entry { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot read entry in dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_read_entry_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); continue 'dir; } }; let metadata: Metadata = match entry_data.metadata() { Ok(t) => t, Err(e) => { - warnings.push(format!("Cannot read metadata in dir {}, reason {}", current_folder.display(), e)); + warnings.push(fl!("core_cannot_read_metadata_dir", generate_translation_hashmap(vec![("dir", current_folder.display().to_string()), ("reason", e.to_string())]))); continue 'dir; } }; @@ -218,7 +220,7 @@ impl Temporary { let file_name_lowercase: String = match entry_data.file_name().into_string() { Ok(t) => t, Err(_inspected) => { - warnings.push(format!("File {:?} has not valid UTF-8 name", entry_data)); + warnings.push(fl!("core_file_not_utf8_name", generate_translation_hashmap(vec![("name", entry_data.path().display().to_string())]))); continue 'dir; } } @@ -242,12 +244,15 @@ impl Temporary { Ok(t) => match t.duration_since(UNIX_EPOCH) { Ok(d) => d.as_secs(), Err(_inspected) => { - warnings.push(format!("File {} seems to be modified before Unix Epoch.", current_file_name.display())); + warnings.push(fl!("core_file_modified_before_epoch", generate_translation_hashmap(vec![("name", current_file_name.display().to_string())]))); 0 } }, Err(e) => { - warnings.push(format!("Unable to get modification date from file {}, reason {}", current_file_name.display(), e)); + warnings.push(fl!( + "core_file_no_modification_date", + generate_translation_hashmap(vec![("name", current_file_name.display().to_string()), ("reason", e.to_string())]) + )); 0 } // Permissions Denied }, diff --git a/czkawka_gui/src/compute_results.rs b/czkawka_gui/src/compute_results.rs index 0800f5f..0ee8a60 100644 --- a/czkawka_gui/src/compute_results.rs +++ b/czkawka_gui/src/compute_results.rs @@ -8,11 +8,11 @@ use glib::Receiver; use gtk::prelude::*; use humansize::{file_size_opts as options, FileSize}; -use crate::fl; use czkawka_core::duplicate::CheckingMethod; use czkawka_core::same_music::MusicSimilarity; use czkawka_core::similar_images; +use crate::fl; use crate::gui_data::GuiData; use crate::help_combo_box::IMAGES_HASH_SIZE_COMBO_BOX; use crate::help_functions::*; diff --git a/czkawka_gui/src/connect_button_delete.rs b/czkawka_gui/src/connect_button_delete.rs index 584a3e9..671b781 100644 --- a/czkawka_gui/src/connect_button_delete.rs +++ b/czkawka_gui/src/connect_button_delete.rs @@ -2,12 +2,14 @@ use std::collections::BTreeMap; use std::fs; use std::fs::Metadata; -use czkawka_core::fl; use gtk::prelude::*; use gtk::{Align, CheckButton, Dialog, ResponseType, TextView}; +use czkawka_core::fl; + use crate::gui_data::GuiData; use crate::help_functions::*; +use crate::localizer::generate_translation_hashmap; use crate::notebook_enums::*; // TODO add support for checking if really symlink doesn't point to correct directory/file @@ -289,7 +291,8 @@ pub fn empty_folder_remover(tree_view: >k::TreeView, column_file_name: i32, co } } if error_happened { - messages += format!("{} {}/{} {}\n", fl!("delete_folder_failed_1"), path, name, fl!("delete_folder_failed_2")).as_str() + messages += &fl!("delete_folder_failed", generate_translation_hashmap(vec![("dir", format!("{}/{}", path, name))])); + messages += "\n"; } } @@ -333,14 +336,21 @@ pub fn basic_remove(tree_view: >k::TreeView, column_file_name: i32, column_pat Ok(_) => { model.remove(&iter); } - Err(e) => messages += format!("{} {}/{}, reason {}\n", fl!("delete_file_failed"), path, name, e).as_str(), + + Err(e) => { + messages += fl!("delete_file_failed", generate_translation_hashmap(vec![("name", format!("{}/{}", path, name)), ("reason", e.to_string())])).as_str(); + messages += "\n"; + } } } else { match trash::delete(format!("{}/{}", path, name)) { Ok(_) => { model.remove(&iter); } - Err(e) => messages += format!("{} {}/{}, reason {}\n", fl!("delete_file_failed"), path, name, e).as_str(), + Err(e) => { + messages += fl!("delete_file_failed", generate_translation_hashmap(vec![("name", format!("{}/{}", path, name)), ("reason", e.to_string())])).as_str(); + messages += "\n"; + } } } } @@ -401,10 +411,12 @@ pub fn tree_remove(tree_view: >k::TreeView, column_file_name: i32, column_path for file_name in vec_file_name { if !use_trash { if let Err(e) = fs::remove_file(format!("{}/{}", path.clone(), file_name.clone())) { - messages += format!("{} {}/{}, reason {}\n", fl!("delete_file_failed"), path, file_name, e).as_str() + messages += fl!("delete_file_failed", generate_translation_hashmap(vec![("name", format!("{}/{}", path, file_name)), ("reason", e.to_string())])).as_str(); + messages += "\n"; } } else if let Err(e) = trash::delete(format!("{}/{}", path.clone(), file_name.clone())) { - messages += format!("{} {}/{}, reason {}\n", fl!("delete_file_failed"), path, file_name, e).as_str() + messages += fl!("delete_file_failed", generate_translation_hashmap(vec![("name", format!("{}/{}", path, file_name)), ("reason", e.to_string())])).as_str(); + messages += "\n"; } vec_path_to_delete.push((path.clone(), file_name.clone())); diff --git a/czkawka_gui/src/connect_button_hardlink.rs b/czkawka_gui/src/connect_button_hardlink.rs index 8e8ad1a..aabd9be 100644 --- a/czkawka_gui/src/connect_button_hardlink.rs +++ b/czkawka_gui/src/connect_button_hardlink.rs @@ -9,6 +9,7 @@ use czkawka_core::fl; use crate::gui_data::GuiData; use crate::help_functions::*; +use crate::localizer::generate_translation_hashmap; use crate::notebook_enums::*; pub fn connect_button_hardlink_symlink(gui_data: &GuiData) { @@ -190,21 +191,30 @@ pub fn hardlink_symlink(tree_view: >k::TreeView, column_file_name: i32, column for symhardlink_data in vec_symhardlink_data { for file_to_symlink in symhardlink_data.files_to_symhardlink { if let Err(e) = fs::remove_file(&file_to_symlink) { - add_text_to_text_view(text_view_errors, format!("{} {}, reason {}", fl!("delete_file_failed"), file_to_symlink, e).as_str()); + add_text_to_text_view( + text_view_errors, + fl!("delete_file_failed", generate_translation_hashmap(vec![("name", file_to_symlink.to_string()), ("reason", e.to_string())])).as_str(), + ); continue; }; #[cfg(target_family = "unix")] { if let Err(e) = std::os::unix::fs::symlink(&symhardlink_data.original_data, &file_to_symlink) { - add_text_to_text_view(text_view_errors, format!("{} {}, reason {}", fl!("delete_file_failed"), file_to_symlink, e).as_str()); + add_text_to_text_view( + text_view_errors, + fl!("delete_file_failed", generate_translation_hashmap(vec![("name", file_to_symlink.to_string()), ("reason", e.to_string())])).as_str(), + ); continue; }; } #[cfg(target_family = "windows")] { if let Err(e) = std::os::windows::fs::symlink_file(&symhardlink_data.original_data, &file_to_symlink) { - add_text_to_text_view(&text_view_errors, format!("{} {}, reason {}", fl!("delete_file_failed"), file_to_symlink, e).as_str()); + add_text_to_text_view( + text_view_errors, + fl!("delete_file_failed", generate_translation_hashmap(vec![("name", file_to_symlink.to_string()), ("reason", e.to_string())])).as_str(), + ); continue; }; } @@ -219,7 +229,7 @@ pub fn hardlink_symlink(tree_view: >k::TreeView, column_file_name: i32, column } fn create_dialog_non_group(window_main: >k::Window) -> Dialog { - let dialog = gtk::Dialog::builder().title("Invalid selection with some groups").transient_for(window_main).modal(true).build(); + let dialog = gtk::Dialog::builder().title(&fl!("hard_sym_invalid_selection_title_dialog")).transient_for(window_main).modal(true).build(); let button_ok = dialog.add_button(&fl!("general_ok_button"), ResponseType::Ok); dialog.add_button(&fl!("general_close_button"), ResponseType::Cancel); @@ -328,7 +338,7 @@ fn create_dialog_ask_for_linking(window_main: >k::Window) -> (Dialog, CheckBut dialog.add_button(&fl!("general_close_button"), ResponseType::Cancel); let label: gtk::Label = gtk::Label::new(Some(&fl!("hard_sym_link_label"))); - let check_button: gtk::CheckButton = gtk::CheckButton::with_label("Ask next time"); + let check_button: gtk::CheckButton = gtk::CheckButton::with_label(&fl!("dialogs_ask_next_time")); check_button.set_active(true); check_button.set_halign(Align::Center); diff --git a/czkawka_gui/src/connect_button_move.rs b/czkawka_gui/src/connect_button_move.rs index 63746f0..1dba9e2 100644 --- a/czkawka_gui/src/connect_button_move.rs +++ b/czkawka_gui/src/connect_button_move.rs @@ -1,11 +1,13 @@ use std::path::{Path, PathBuf}; -use czkawka_core::fl; use gtk::prelude::*; use gtk::{ResponseType, TreePath}; +use czkawka_core::fl; + use crate::gui_data::GuiData; use crate::help_functions::*; +use crate::localizer::generate_translation_hashmap; use crate::notebook_enums::*; pub fn connect_button_move(gui_data: &GuiData) { @@ -92,7 +94,7 @@ fn move_things(tree_view: >k::TreeView, column_file_name: i32, column_path: i3 // } if folders.len() != 1 { - add_text_to_text_view(&text_view_errors, format!("{} {:?}", &fl!("move_files_choose_more_than_1_path"), folders).as_str()); + add_text_to_text_view(&text_view_errors, fl!("move_files_choose_more_than_1_path", generate_translation_hashmap(vec![("path_number", folders.len().to_string())])).as_str()); } else { let folder = folders[0].clone(); if let Some(column_color) = column_color { @@ -176,19 +178,23 @@ fn move_files_common(selected_rows: &[TreePath], model: >k::ListStore, column_ 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!("{}, reason {}\n", fl!("move_folder_failed"), e).as_str(); + messages += fl!("move_folder_failed", generate_translation_hashmap(vec![("name", thing), ("reason", e.to_string())])).as_str(); + messages += "\n"; continue 'next_result; } } else { if let Err(e) = fs_extra::file::move_file(&thing, &destination_file, &fs_extra::file::CopyOptions::new()) { - messages += format!("{}, reason {}\n", fl!("move_file_failed"), e).as_str(); + messages += fl!("move_file_failed", generate_translation_hashmap(vec![("name", thing), ("reason", e.to_string())])).as_str(); + messages += "\n"; + continue 'next_result; } } model.remove(&iter); moved_files += 1; } - entry_info.set_text(format!("{} {}/{} {}", fl!("move_stats_1"), moved_files, selected_rows.len(), fl!("move_stats_2")).as_str()); + + entry_info.set_text(fl!("move_stats", generate_translation_hashmap(vec![("num_files", moved_files.to_string()), ("all_files", selected_rows.len().to_string())])).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 f508c2c..eb88e06 100644 --- a/czkawka_gui/src/connect_button_save.rs +++ b/czkawka_gui/src/connect_button_save.rs @@ -9,6 +9,7 @@ use czkawka_core::common_traits::SaveResults; use czkawka_core::fl; use crate::gui_data::GuiData; +use crate::localizer::generate_translation_hashmap; use crate::notebook_enums::*; pub fn connect_button_save(gui_data: &GuiData) { @@ -87,7 +88,7 @@ pub fn connect_button_save(gui_data: &GuiData) { } 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!("{} {}", fl!("save_results_to_file"), file_name).as_str()); + entry_info.set_text(fl!("save_results_to_file", generate_translation_hashmap(vec![("name", file_name.to_string())])).as_str()); // Set state { buttons_save.hide(); diff --git a/czkawka_gui/src/connect_button_search.rs b/czkawka_gui/src/connect_button_search.rs index 11f366d..44f6875 100644 --- a/czkawka_gui/src/connect_button_search.rs +++ b/czkawka_gui/src/connect_button_search.rs @@ -5,7 +5,6 @@ use std::thread; use glib::Sender; use gtk::prelude::*; -use crate::fl; use czkawka_core::big_file::BigFile; use czkawka_core::broken_files::BrokenFiles; use czkawka_core::duplicate::DuplicateFinder; @@ -18,6 +17,7 @@ use czkawka_core::similar_videos::SimilarVideos; use czkawka_core::temporary::Temporary; use czkawka_core::*; +use crate::fl; use crate::gui_data::GuiData; use crate::help_combo_box::{DUPLICATES_CHECK_METHOD_COMBO_BOX, DUPLICATES_HASH_TYPE_COMBO_BOX, IMAGES_HASH_SIZE_COMBO_BOX, IMAGES_HASH_TYPE_COMBO_BOX, IMAGES_RESIZE_ALGORITHM_COMBO_BOX}; use crate::help_functions::*; diff --git a/czkawka_gui/src/connect_change_language.rs b/czkawka_gui/src/connect_change_language.rs index c0aabcc..adbf985 100644 --- a/czkawka_gui/src/connect_change_language.rs +++ b/czkawka_gui/src/connect_change_language.rs @@ -1,8 +1,10 @@ -use crate::language_functions::get_language_from_combo_box_text; -use crate::{GuiData, LANGUAGES_ALL}; use gtk::prelude::*; use i18n_embed::unic_langid::LanguageIdentifier; use i18n_embed::DesktopLanguageRequester; + +use crate::language_functions::get_language_from_combo_box_text; +use crate::{GuiData, LANGUAGES_ALL}; + // use i18n_embed::{DesktopLanguageRequester, Localizer}; pub fn connect_change_language(gui_data: &GuiData) { diff --git a/czkawka_gui/src/connect_duplicate_buttons.rs b/czkawka_gui/src/connect_duplicate_buttons.rs index 12c77f6..072ec31 100644 --- a/czkawka_gui/src/connect_duplicate_buttons.rs +++ b/czkawka_gui/src/connect_duplicate_buttons.rs @@ -1,6 +1,7 @@ -use czkawka_core::duplicate::CheckingMethod; use gtk::prelude::*; +use czkawka_core::duplicate::CheckingMethod; + use crate::gui_data::GuiData; use crate::help_combo_box::DUPLICATES_CHECK_METHOD_COMBO_BOX; diff --git a/czkawka_gui/src/connect_popovers.rs b/czkawka_gui/src/connect_popovers.rs index 6f12d44..5a748d7 100644 --- a/czkawka_gui/src/connect_popovers.rs +++ b/czkawka_gui/src/connect_popovers.rs @@ -2,9 +2,9 @@ use gtk::prelude::*; use gtk::{ResponseType, TreeIter, Window}; use regex::Regex; -use crate::fl; use czkawka_core::common::Common; +use crate::fl; use crate::gui_data::GuiData; use crate::help_functions::*; diff --git a/czkawka_gui/src/connect_progress_window.rs b/czkawka_gui/src/connect_progress_window.rs index af6e265..c55e3bb 100644 --- a/czkawka_gui/src/connect_progress_window.rs +++ b/czkawka_gui/src/connect_progress_window.rs @@ -1,10 +1,11 @@ use futures::StreamExt; use gtk::prelude::*; -use crate::fl; use czkawka_core::{big_file, broken_files, duplicate, empty_files, empty_folder, invalid_symlinks, same_music, similar_images, similar_videos, temporary}; +use crate::fl; use crate::gui_data::GuiData; +use crate::localizer::generate_translation_hashmap; use crate::taskbar_progress::tbp_flags::TBPF_INDETERMINATE; #[allow(clippy::too_many_arguments)] @@ -42,7 +43,7 @@ pub fn connect_progress_window( progress_bar_current_stage.hide(); // progress_bar_all_stages.hide(); progress_bar_all_stages.set_fraction(0 as f64); - label_stage.set_text(format!("{} {} {} {}", fl!("progress_scanned"), fl!("progress_size"), item.files_checked, fl!("progress_files")).as_str()); + label_stage.set_text(&fl!("progress_scanning_size", generate_translation_hashmap(vec![("file_number", item.files_checked.to_string())]))); taskbar_state.borrow().set_progress_state(TBPF_INDETERMINATE); } // Hash - first 1KB file @@ -58,7 +59,11 @@ pub fn connect_progress_window( progress_bar_current_stage.set_fraction(0f64); taskbar_state.borrow().set_progress_value(1, 1 + item.max_stage as u64); } - label_stage.set_text(format!("{} {}/{} {}", fl!("progress_analyzed_partial_hash"), item.files_checked, item.files_to_check, fl!("progress_files")).as_str()); + + label_stage.set_text(&fl!( + "progress_analyzed_partial_hash", + generate_translation_hashmap(vec![("file_checked", item.files_checked.to_string()), ("all_files", item.files_to_check.to_string())]) + )); } // Hash - normal hash 2 => { @@ -74,7 +79,10 @@ pub fn connect_progress_window( taskbar_state.borrow().set_progress_value(2, 1 + item.max_stage as u64); } - label_stage.set_text(format!("{} {}/{} {}", fl!("progress_analyzed_full_hash"), item.files_checked, item.files_to_check, fl!("progress_files")).as_str()); + label_stage.set_text(&fl!( + "progress_analyzed_full_hash", + generate_translation_hashmap(vec![("file_checked", item.files_checked.to_string()), ("all_files", item.files_to_check.to_string())]) + )); } _ => { panic!("Not available current_stage"); @@ -85,14 +93,14 @@ pub fn connect_progress_window( label_stage.show(); grid_progress_stages.hide(); - label_stage.set_text(format!("{} {} {} {}", fl!("progress_scanned"), fl!("progress_name"), item.files_checked, fl!("progress_files")).as_str()); + label_stage.set_text(&fl!("progress_scanning_name", generate_translation_hashmap(vec![("file_number", item.files_checked.to_string())]))); taskbar_state.borrow().set_progress_state(TBPF_INDETERMINATE); } duplicate::CheckingMethod::Size => { label_stage.show(); grid_progress_stages.hide(); - label_stage.set_text(format!("{} {} {} {}", fl!("progress_scanned"), fl!("progress_size"), item.files_checked, fl!("progress_files")).as_str()); + label_stage.set_text(&fl!("progress_scanning_size", generate_translation_hashmap(vec![("file_number", item.files_checked.to_string())]))); taskbar_state.borrow().set_progress_state(TBPF_INDETERMINATE); } duplicate::CheckingMethod::None => { @@ -109,7 +117,7 @@ pub fn connect_progress_window( let taskbar_state = gui_data.taskbar_state.clone(); let future = async move { while let Some(item) = futures_receiver_empty_files.next().await { - label_stage.set_text(format!("{} {} {}", fl!("progress_scanned"), item.files_checked, fl!("progress_files")).as_str()); + label_stage.set_text(&fl!("progress_scanning_general_file", generate_translation_hashmap(vec![("file_number", item.files_checked.to_string())]))); taskbar_state.borrow().set_progress_state(TBPF_INDETERMINATE); } }; @@ -121,7 +129,7 @@ pub fn connect_progress_window( let taskbar_state = gui_data.taskbar_state.clone(); let future = async move { while let Some(item) = futures_receiver_empty_folder.next().await { - label_stage.set_text(format!("{} {} {}", fl!("progress_scanned"), item.folders_checked, fl!("progress_folders")).as_str()); + label_stage.set_text(&fl!("progress_scanning_empty_folders", generate_translation_hashmap(vec![("folder_number", item.folders_checked.to_string())]))); taskbar_state.borrow().set_progress_state(TBPF_INDETERMINATE); } }; @@ -133,7 +141,7 @@ pub fn connect_progress_window( let taskbar_state = gui_data.taskbar_state.clone(); let future = async move { while let Some(item) = futures_receiver_big_files.next().await { - label_stage.set_text(format!("{} {} {}", fl!("progress_scanned"), item.files_checked, fl!("progress_files")).as_str()); + label_stage.set_text(&fl!("progress_scanning_general_file", generate_translation_hashmap(vec![("file_number", item.files_checked.to_string())]))); taskbar_state.borrow().set_progress_state(TBPF_INDETERMINATE); } }; @@ -150,7 +158,7 @@ pub fn connect_progress_window( match item.current_stage { 0 => { progress_bar_current_stage.hide(); - label_stage.set_text(format!("{} {} {}", fl!("progress_scanned"), item.music_checked, fl!("progress_files")).as_str()); + label_stage.set_text(&fl!("progress_scanning_general_file", generate_translation_hashmap(vec![("file_number", item.music_checked.to_string())]))); taskbar_state.borrow().set_progress_state(TBPF_INDETERMINATE); } 1 => { @@ -164,7 +172,10 @@ pub fn connect_progress_window( progress_bar_current_stage.set_fraction(0f64); taskbar_state.borrow().set_progress_value(1, (item.max_stage + 1) as u64); } - label_stage.set_text(format!("{} {}/{} {}", fl!("progress_tags"), item.music_checked, item.music_to_check, fl!("progress_files")).as_str()); + label_stage.set_text(&fl!( + "progress_scanning_music_tags", + generate_translation_hashmap(vec![("file_checked", item.music_checked.to_string()), ("all_files", item.music_to_check.to_string())]) + )); } 2 => { if item.music_to_check != 0 { @@ -178,7 +189,10 @@ pub fn connect_progress_window( progress_bar_current_stage.set_fraction(0f64); taskbar_state.borrow().set_progress_value(2, (item.max_stage + 1) as u64); } - label_stage.set_text(format!("{} {}/{} {}", fl!("progress_checking"), item.music_checked, item.music_to_check, fl!("progress_files")).as_str()); + label_stage.set_text(&fl!( + "progress_scanning_music_tags_end", + generate_translation_hashmap(vec![("file_checked", item.music_checked.to_string()), ("all_files", item.music_to_check.to_string())]) + )); } _ => { panic!(); @@ -199,7 +213,7 @@ pub fn connect_progress_window( match item.current_stage { 0 => { progress_bar_current_stage.hide(); - label_stage.set_text(format!("{} {} {}", fl!("progress_scanned"), item.images_checked, fl!("progress_files")).as_str()); + label_stage.set_text(&fl!("progress_scanning_general_file", generate_translation_hashmap(vec![("file_number", item.images_checked.to_string())]))); taskbar_state.borrow().set_progress_state(TBPF_INDETERMINATE); } 1 => { @@ -215,7 +229,10 @@ pub fn connect_progress_window( progress_bar_current_stage.set_fraction(0f64); taskbar_state.borrow().set_progress_value(1, (item.max_stage + 1) as u64); } - label_stage.set_text(format!("{} {}/{} {}", fl!("progress_hashing"), item.images_checked, item.images_to_check, fl!("progress_files")).as_str()); + label_stage.set_text(&fl!( + "progress_scanning_image", + generate_translation_hashmap(vec![("file_checked", item.images_checked.to_string()), ("all_files", item.images_to_check.to_string())]) + )); } _ => { panic!(); @@ -236,7 +253,7 @@ pub fn connect_progress_window( match item.current_stage { 0 => { progress_bar_current_stage.hide(); - label_stage.set_text(format!("{} {} {}", fl!("progress_scanned"), item.videos_checked, fl!("progress_files")).as_str()); + label_stage.set_text(&fl!("progress_scanning_general_file", generate_translation_hashmap(vec![("file_number", item.videos_checked.to_string())]))); taskbar_state.borrow().set_progress_state(TBPF_INDETERMINATE); } 1 => { @@ -252,7 +269,10 @@ pub fn connect_progress_window( progress_bar_current_stage.set_fraction(0f64); taskbar_state.borrow().set_progress_value(1, (item.max_stage + 1) as u64); } - label_stage.set_text(format!("{} {}/{} {}", fl!("progress_hashing"), item.videos_checked, item.videos_to_check, fl!("progress_files")).as_str()); + label_stage.set_text(&fl!( + "progress_scanning_video", + generate_translation_hashmap(vec![("file_checked", item.videos_checked.to_string()), ("all_files", item.videos_to_check.to_string())]) + )); } _ => { panic!(); @@ -268,7 +288,7 @@ pub fn connect_progress_window( let taskbar_state = gui_data.taskbar_state.clone(); let future = async move { while let Some(item) = futures_receiver_temporary.next().await { - label_stage.set_text(format!("{} {} {}", fl!("progress_scanned"), item.files_checked, fl!("progress_files")).as_str()); + label_stage.set_text(&fl!("progress_scanning_general_file", generate_translation_hashmap(vec![("file_number", item.files_checked.to_string())]))); taskbar_state.borrow().set_progress_state(TBPF_INDETERMINATE); } }; @@ -280,7 +300,7 @@ pub fn connect_progress_window( let taskbar_state = gui_data.taskbar_state.clone(); let future = async move { while let Some(item) = futures_receiver_invalid_symlinks.next().await { - label_stage.set_text(format!("{} {} {}", fl!("progress_scanned"), item.files_checked, fl!("progress_files")).as_str()); + label_stage.set_text(&fl!("progress_scanning_general_file", generate_translation_hashmap(vec![("file_number", item.files_checked.to_string())]))); taskbar_state.borrow().set_progress_state(TBPF_INDETERMINATE); } }; @@ -297,7 +317,7 @@ pub fn connect_progress_window( match item.current_stage { 0 => { progress_bar_current_stage.hide(); - label_stage.set_text(format!("{} {} {}", fl!("progress_scanned"), item.files_checked, fl!("progress_files")).as_str()); + label_stage.set_text(&fl!("progress_scanning_general_file", generate_translation_hashmap(vec![("file_number", item.files_checked.to_string())]))); taskbar_state.borrow().set_progress_state(TBPF_INDETERMINATE); } 1 => { @@ -311,7 +331,10 @@ pub fn connect_progress_window( progress_bar_current_stage.set_fraction(0f64); taskbar_state.borrow().set_progress_value(1, (item.max_stage + 1) as u64); } - label_stage.set_text(format!("{} {}/{} {}", fl!("progress_checking"), item.files_checked, item.files_to_check, fl!("progress_files")).as_str()); + label_stage.set_text(&fl!( + "progress_scanning_broken_files", + generate_translation_hashmap(vec![("file_checked", item.files_checked.to_string()), ("all_files", item.files_to_check.to_string())]) + )); } _ => { panic!(); diff --git a/czkawka_gui/src/connect_selection_of_directories.rs b/czkawka_gui/src/connect_selection_of_directories.rs index 08dcb22..3687ff4 100644 --- a/czkawka_gui/src/connect_selection_of_directories.rs +++ b/czkawka_gui/src/connect_selection_of_directories.rs @@ -1,6 +1,7 @@ +use std::path::PathBuf; + use gtk::prelude::*; use gtk::{ResponseType, TreeView, Window}; -use std::path::PathBuf; #[cfg(target_family = "windows")] use czkawka_core::common::Common; diff --git a/czkawka_gui/src/connect_settings.rs b/czkawka_gui/src/connect_settings.rs index 866c953..fc32df7 100644 --- a/czkawka_gui/src/connect_settings.rs +++ b/czkawka_gui/src/connect_settings.rs @@ -1,13 +1,15 @@ -use czkawka_core::common_messages::Messages; -use czkawka_core::duplicate::HashType; -use czkawka_core::fl; +use std::collections::BTreeMap; +use std::default::Default; + use directories_next::ProjectDirs; use gtk::prelude::*; use gtk::{LabelBuilder, ResponseType, Window}; use image::imageops::FilterType; use img_hash::HashAlg; -use std::collections::BTreeMap; -use std::default::Default; + +use czkawka_core::common_messages::Messages; +use czkawka_core::duplicate::HashType; +use czkawka_core::fl; use crate::gui_data::GuiData; use crate::help_functions::get_dialog_box_child; diff --git a/czkawka_gui/src/gui_about.rs b/czkawka_gui/src/gui_about.rs index 63b26b1..65291f3 100644 --- a/czkawka_gui/src/gui_about.rs +++ b/czkawka_gui/src/gui_about.rs @@ -1,7 +1,8 @@ -use crate::fl; use gtk::prelude::*; use gtk::{Builder, Window}; +use crate::fl; + #[derive(Clone)] pub struct GuiAbout { pub about_dialog: gtk::AboutDialog, diff --git a/czkawka_gui/src/gui_bottom_buttons.rs b/czkawka_gui/src/gui_bottom_buttons.rs index 69595c7..a5aef76 100644 --- a/czkawka_gui/src/gui_bottom_buttons.rs +++ b/czkawka_gui/src/gui_bottom_buttons.rs @@ -1,8 +1,9 @@ -use crate::fl; -use crate::help_functions::get_custom_label_from_button_with_image; use gtk::prelude::*; use gtk::{Bin, Widget}; +use crate::fl; +use crate::help_functions::get_custom_label_from_button_with_image; + #[derive(Clone)] pub struct GuiBottomButtons { pub buttons_search: gtk::Button, diff --git a/czkawka_gui/src/gui_header.rs b/czkawka_gui/src/gui_header.rs index f9bd50b..d8198da 100644 --- a/czkawka_gui/src/gui_header.rs +++ b/czkawka_gui/src/gui_header.rs @@ -1,6 +1,7 @@ -use crate::fl; use gtk::prelude::*; +use crate::fl; + #[derive(Clone)] pub struct GuiHeader { pub button_settings: gtk::Button, diff --git a/czkawka_gui/src/gui_main_notebook.rs b/czkawka_gui/src/gui_main_notebook.rs index 5b87cdf..93640f7 100644 --- a/czkawka_gui/src/gui_main_notebook.rs +++ b/czkawka_gui/src/gui_main_notebook.rs @@ -1,9 +1,10 @@ -use crate::fl; -use crate::help_combo_box::IMAGES_HASH_SIZE_COMBO_BOX; -use czkawka_core::similar_images::{get_string_from_similarity, Similarity, SIMILAR_VALUES}; use gtk::prelude::*; use gtk::{EventControllerKey, TreeView}; +use czkawka_core::similar_images::{get_string_from_similarity, Similarity, SIMILAR_VALUES}; + +use crate::fl; +use crate::help_combo_box::IMAGES_HASH_SIZE_COMBO_BOX; use crate::notebook_enums::{NotebookMainEnum, NUMBER_OF_NOTEBOOK_MAIN_TABS}; #[derive(Clone)] diff --git a/czkawka_gui/src/gui_popovers.rs b/czkawka_gui/src/gui_popovers.rs index 4fe4e29..7acf5a6 100644 --- a/czkawka_gui/src/gui_popovers.rs +++ b/czkawka_gui/src/gui_popovers.rs @@ -1,7 +1,8 @@ -use crate::fl; use gtk::prelude::*; use gtk::Builder; +use crate::fl; + #[derive(Clone)] pub struct GuiPopovers { pub buttons_popover_select_all: gtk::Button, diff --git a/czkawka_gui/src/gui_progress_dialog.rs b/czkawka_gui/src/gui_progress_dialog.rs index 88a1397..87d68df 100644 --- a/czkawka_gui/src/gui_progress_dialog.rs +++ b/czkawka_gui/src/gui_progress_dialog.rs @@ -1,8 +1,9 @@ -use crate::fl; -use crate::help_functions::get_custom_label_from_button_with_image; use gtk::prelude::*; use gtk::{Bin, Builder, EventControllerKey, Window}; +use crate::fl; +use crate::help_functions::get_custom_label_from_button_with_image; + #[derive(Clone)] pub struct GuiProgressDialog { pub window_progress: gtk::Dialog, diff --git a/czkawka_gui/src/gui_settings.rs b/czkawka_gui/src/gui_settings.rs index f6d553f..0202d82 100644 --- a/czkawka_gui/src/gui_settings.rs +++ b/czkawka_gui/src/gui_settings.rs @@ -1,11 +1,14 @@ -use crate::fl; use gtk::prelude::*; use gtk::{Builder, Window}; +use crate::fl; + #[derive(Clone)] pub struct GuiSettings { pub window_settings: gtk::Window, + pub notebook_settings: gtk::Notebook, + // General pub check_button_settings_save_at_exit: gtk::CheckButton, pub check_button_settings_load_at_start: gtk::CheckButton, @@ -56,6 +59,8 @@ impl GuiSettings { window_settings.set_modal(true); window_settings.set_transient_for(Some(window_main)); + let notebook_settings: gtk::Notebook = builder.object("notebook_settings").unwrap(); + // General let check_button_settings_save_at_exit: gtk::CheckButton = builder.object("check_button_settings_save_at_exit").unwrap(); let check_button_settings_load_at_start: gtk::CheckButton = builder.object("check_button_settings_load_at_start").unwrap(); @@ -98,6 +103,7 @@ impl GuiSettings { Self { window_settings, + notebook_settings, check_button_settings_save_at_exit, check_button_settings_load_at_start, check_button_settings_confirm_deletion, @@ -197,5 +203,16 @@ impl GuiSettings { self.button_settings_open_cache_folder.set_tooltip_text(Some(&fl!("settings_folder_cache_open_tooltip"))); self.button_settings_open_settings_folder.set_tooltip_text(Some(&fl!("settings_folder_settings_open_tooltip"))); + + let vec_children: Vec = self.notebook_settings.children(); + + // let vec_children: Vec = get_all_children(&self.notebook_settings); + // let vec_children: Vec = get_all_children(&vec_children[1]); + + // Change name of main notebook tabs + let names: [String; 4] = [fl!("settings_notebook_general"), fl!("settings_notebook_duplicates"), fl!("settings_notebook_images"), fl!("settings_notebook_videos")]; + for (index, fl_thing) in names.iter().enumerate() { + self.notebook_settings.tab_label(&vec_children[index]).unwrap().downcast::().unwrap().set_text(fl_thing); + } } } diff --git a/czkawka_gui/src/gui_upper_notebook.rs b/czkawka_gui/src/gui_upper_notebook.rs index 5f872c8..863f82b 100644 --- a/czkawka_gui/src/gui_upper_notebook.rs +++ b/czkawka_gui/src/gui_upper_notebook.rs @@ -1,8 +1,9 @@ +use gtk::prelude::*; +use gtk::{Bin, EventControllerKey, TreeView}; + use crate::fl; use crate::help_functions::get_custom_label_from_button_with_image; use crate::notebook_enums::NotebookUpperEnum; -use gtk::prelude::*; -use gtk::{Bin, EventControllerKey, TreeView}; #[derive(Clone)] pub struct GuiUpperNotebook { diff --git a/czkawka_gui/src/help_combo_box.rs b/czkawka_gui/src/help_combo_box.rs index b917d8e..5b33cb6 100644 --- a/czkawka_gui/src/help_combo_box.rs +++ b/czkawka_gui/src/help_combo_box.rs @@ -1,6 +1,7 @@ -use czkawka_core::duplicate::{CheckingMethod, HashType}; use img_hash::{FilterType, HashAlg}; +use czkawka_core::duplicate::{CheckingMethod, HashType}; + pub struct HashTypeStruct { pub eng_name: &'static str, pub hash_type: HashType, diff --git a/czkawka_gui/src/initialize_gui.rs b/czkawka_gui/src/initialize_gui.rs index 7805208..2f73b20 100644 --- a/czkawka_gui/src/initialize_gui.rs +++ b/czkawka_gui/src/initialize_gui.rs @@ -11,6 +11,7 @@ use gtk::{CheckButton, Image, SelectionMode, TextView, TreeView}; use image::imageops::FilterType; use image::GenericImageView; +use czkawka_core::fl; use czkawka_core::similar_images::SIMILAR_VALUES; use czkawka_core::similar_videos::MAX_TOLERANCE; @@ -20,6 +21,7 @@ use crate::gui_data::*; use crate::help_combo_box::{DUPLICATES_CHECK_METHOD_COMBO_BOX, DUPLICATES_HASH_TYPE_COMBO_BOX, IMAGES_HASH_SIZE_COMBO_BOX, IMAGES_HASH_TYPE_COMBO_BOX, IMAGES_RESIZE_ALGORITHM_COMBO_BOX}; use crate::help_functions::*; use crate::language_functions::LANGUAGES_ALL; +use crate::localizer::generate_translation_hashmap; use crate::notebook_enums::NotebookMainEnum; use crate::opening_selecting_records::*; @@ -662,7 +664,10 @@ fn show_preview(tree_view: &TreeView, text_view_errors: &TextView, check_button_ break 'dir; } } else if let Err(e) = fs::create_dir_all(cache_dir) { - add_text_to_text_view(text_view_errors, format!("Failed to create dir {} needed by image preview, reason {}", cache_dir.display(), e).as_str()); + add_text_to_text_view( + text_view_errors, + fl!("preview_failed_to_create_cache_dir", generate_translation_hashmap(vec![("name", cache_dir.display().to_string()), ("reason", e.to_string())])).as_str(), + ); break 'dir; } let path = tree_model.value(&tree_model.iter(&tree_path).unwrap(), column_path).get::().unwrap(); @@ -687,12 +692,15 @@ fn show_preview(tree_view: &TreeView, text_view_errors: &TextView, check_button_ let img = match image::open(&file_name) { Ok(t) => t, Err(e) => { - add_text_to_text_view(text_view_errors, format!("Failed to open temporary image file {}, reason {}", file_name, e).as_str()); + add_text_to_text_view( + text_view_errors, + fl!("preview_temporary_file", generate_translation_hashmap(vec![("name", file_name.to_string()), ("reason", e.to_string())])).as_str(), + ); break 'dir; } }; if img.width() == 0 || img.height() == 0 { - add_text_to_text_view(text_view_errors, format!("Cannot create preview of image {}, with 0 width or height", file_name).as_str()); + add_text_to_text_view(text_view_errors, fl!("preview_0_size", generate_translation_hashmap(vec![("name", file_name.to_string())])).as_str()); break 'dir; } let ratio = img.width() / img.height(); @@ -715,7 +723,10 @@ fn show_preview(tree_view: &TreeView, text_view_errors: &TextView, check_button_ let img = img.resize(new_size.0, new_size.1, FilterType::Triangle); let file_dir = cache_dir.join(format!("cached_file.{}", extension.to_string_lossy().to_lowercase())); if let Err(e) = img.save(&file_dir) { - add_text_to_text_view(text_view_errors, format!("Failed to save temporary image file to {}, reason {}", file_dir.display(), e).as_str()); + add_text_to_text_view( + text_view_errors, + fl!("preview_temporary_image_save", generate_translation_hashmap(vec![("name", file_dir.display().to_string()), ("reason", e.to_string())])).as_str(), + ); let _ = fs::remove_file(&file_dir); break 'dir; } @@ -728,7 +739,10 @@ fn show_preview(tree_view: &TreeView, text_view_errors: &TextView, check_button_ } if let Err(e) = fs::remove_file(&file_dir) { - add_text_to_text_view(text_view_errors, format!("Failed to delete temporary image file to {}, reason {}", file_dir.display(), e).as_str()); + add_text_to_text_view( + text_view_errors, + fl!("preview_temporary_image_remove", generate_translation_hashmap(vec![("name", file_dir.display().to_string()), ("reason", e.to_string())])).as_str(), + ); break 'dir; } created_image = true; diff --git a/czkawka_gui/src/opening_selecting_records.rs b/czkawka_gui/src/opening_selecting_records.rs index 41f843f..83c7de2 100644 --- a/czkawka_gui/src/opening_selecting_records.rs +++ b/czkawka_gui/src/opening_selecting_records.rs @@ -1,7 +1,8 @@ -use crate::help_functions::*; use gdk::ModifierType; use gtk::prelude::*; +use crate::help_functions::*; + // TODO add option to open files and folders from context menu activated by pressing ONCE with right mouse button pub fn opening_enter_function_ported(event_controller: >k::EventControllerKey, _key_value: u32, key_code: u32, _modifier_type: ModifierType) -> bool { diff --git a/czkawka_gui/src/saving_loading.rs b/czkawka_gui/src/saving_loading.rs index 2c09d67..2bcd1ff 100644 --- a/czkawka_gui/src/saving_loading.rs +++ b/czkawka_gui/src/saving_loading.rs @@ -3,15 +3,17 @@ use std::io::Write; use std::path::Path; use std::{env, fs}; -use czkawka_core::fl; use directories_next::ProjectDirs; use gtk::prelude::*; use gtk::{ScrolledWindow, TextView}; +use czkawka_core::fl; + use crate::gui_settings::GuiSettings; use crate::gui_upper_notebook::GuiUpperNotebook; use crate::help_functions::*; use crate::language_functions::{get_language_from_combo_box_text, LANGUAGES_ALL}; +use crate::localizer::generate_translation_hashmap; // TODO organize this better, add specific functions that will allow to load from files specific strings const SAVE_FILE_NAME: &str = "czkawka_gui_config.txt"; @@ -346,14 +348,22 @@ pub fn load_configuration(manual_execution: bool, upper_notebook: &GuiUpperNoteb current_type = TypeOfLoadedData::None; add_text_to_text_view( &text_view_errors, - format!("Found invalid header in line {} \"{}\" when loading file {:?} (save file may be from different Czkawka version)", line_number, line, config_file).as_str(), + fl!( + "settings_load_orphan_data", + generate_translation_hashmap(vec![("name", config_file.display().to_string()), ("line_number", line_number.to_string()), ("line", line)]) + ) + .as_str(), ); } else { match current_type { TypeOfLoadedData::None => { add_text_to_text_view( &text_view_errors, - format!("Found orphan data in line {} \"{}\" when loading file {:?} (save file may be from different Czkawka version)", line_number, line, config_file).as_str(), + fl!( + "settings_load_orphan_data", + generate_translation_hashmap(vec![("name", config_file.display().to_string()), ("line_number", line_number.to_string()), ("line", line)]) + ) + .as_str(), ); } TypeOfLoadedData::IncludedDirectories => { @@ -377,7 +387,11 @@ pub fn load_configuration(manual_execution: bool, upper_notebook: &GuiUpperNoteb } 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(), + fl!( + "settings_load_invalid_bool_value", + generate_translation_hashmap(vec![("name", config_file.display().to_string()), ("line_number", line_number.to_string()), ("line", line)]) + ) + .as_str(), ); } } @@ -390,7 +404,11 @@ pub fn load_configuration(manual_execution: bool, upper_notebook: &GuiUpperNoteb } 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(), + fl!( + "settings_load_invalid_bool_value", + generate_translation_hashmap(vec![("name", config_file.display().to_string()), ("line_number", line_number.to_string()), ("line", line)]) + ) + .as_str(), ); } } @@ -403,7 +421,11 @@ pub fn load_configuration(manual_execution: bool, upper_notebook: &GuiUpperNoteb } 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(), + fl!( + "settings_load_invalid_bool_value", + generate_translation_hashmap(vec![("name", config_file.display().to_string()), ("line_number", line_number.to_string()), ("line", line)]) + ) + .as_str(), ); } } @@ -416,7 +438,11 @@ pub fn load_configuration(manual_execution: bool, upper_notebook: &GuiUpperNoteb } 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(), + fl!( + "settings_load_invalid_bool_value", + generate_translation_hashmap(vec![("name", config_file.display().to_string()), ("line_number", line_number.to_string()), ("line", line)]) + ) + .as_str(), ); } } @@ -429,7 +455,11 @@ pub fn load_configuration(manual_execution: bool, upper_notebook: &GuiUpperNoteb } 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(), + fl!( + "settings_load_invalid_bool_value", + generate_translation_hashmap(vec![("name", config_file.display().to_string()), ("line_number", line_number.to_string()), ("line", line)]) + ) + .as_str(), ); } } @@ -442,7 +472,11 @@ pub fn load_configuration(manual_execution: bool, upper_notebook: &GuiUpperNoteb } 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(), + fl!( + "settings_load_invalid_bool_value", + generate_translation_hashmap(vec![("name", config_file.display().to_string()), ("line_number", line_number.to_string()), ("line", line)]) + ) + .as_str(), ); } } @@ -455,7 +489,11 @@ pub fn load_configuration(manual_execution: bool, upper_notebook: &GuiUpperNoteb } 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(), + fl!( + "settings_load_invalid_bool_value", + generate_translation_hashmap(vec![("name", config_file.display().to_string()), ("line_number", line_number.to_string()), ("line", line)]) + ) + .as_str(), ); } } @@ -468,7 +506,11 @@ pub fn load_configuration(manual_execution: bool, upper_notebook: &GuiUpperNoteb } 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(), + fl!( + "settings_load_invalid_bool_value", + generate_translation_hashmap(vec![("name", config_file.display().to_string()), ("line_number", line_number.to_string()), ("line", line)]) + ) + .as_str(), ); } } @@ -481,7 +523,11 @@ pub fn load_configuration(manual_execution: bool, upper_notebook: &GuiUpperNoteb } 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(), + fl!( + "settings_load_invalid_bool_value", + generate_translation_hashmap(vec![("name", config_file.display().to_string()), ("line_number", line_number.to_string()), ("line", line)]) + ) + .as_str(), ); } } @@ -494,7 +540,11 @@ pub fn load_configuration(manual_execution: bool, upper_notebook: &GuiUpperNoteb } 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(), + fl!( + "settings_load_invalid_bool_value", + generate_translation_hashmap(vec![("name", config_file.display().to_string()), ("line_number", line_number.to_string()), ("line", line)]) + ) + .as_str(), ); } } @@ -517,7 +567,11 @@ pub fn load_configuration(manual_execution: bool, upper_notebook: &GuiUpperNoteb } 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(), + fl!( + "settings_load_invalid_bool_value", + generate_translation_hashmap(vec![("name", config_file.display().to_string()), ("line_number", line_number.to_string()), ("line", line)]) + ) + .as_str(), ); } } @@ -530,7 +584,11 @@ pub fn load_configuration(manual_execution: bool, upper_notebook: &GuiUpperNoteb } 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(), + fl!( + "settings_load_invalid_bool_value", + generate_translation_hashmap(vec![("name", config_file.display().to_string()), ("line_number", line_number.to_string()), ("line", line)]) + ) + .as_str(), ); } } @@ -543,7 +601,11 @@ pub fn load_configuration(manual_execution: bool, upper_notebook: &GuiUpperNoteb } 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(), + fl!( + "settings_load_invalid_bool_value", + generate_translation_hashmap(vec![("name", config_file.display().to_string()), ("line_number", line_number.to_string()), ("line", line)]) + ) + .as_str(), ); } } @@ -556,7 +618,11 @@ pub fn load_configuration(manual_execution: bool, upper_notebook: &GuiUpperNoteb } 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(), + fl!( + "settings_load_invalid_bool_value", + generate_translation_hashmap(vec![("name", config_file.display().to_string()), ("line_number", line_number.to_string()), ("line", line)]) + ) + .as_str(), ); } } diff --git a/czkawka_gui/ui/settings.glade b/czkawka_gui/ui/settings.glade index df4254f..5f55f4e 100644 --- a/czkawka_gui/ui/settings.glade +++ b/czkawka_gui/ui/settings.glade @@ -88,7 +88,7 @@ Author: Rafał Mikrut - + True True left diff --git a/i18n/en/czkawka_gui.ftl b/i18n/en/czkawka_gui.ftl index 4cca85c..5f64499 100644 --- a/i18n/en/czkawka_gui.ftl +++ b/i18n/en/czkawka_gui.ftl @@ -6,6 +6,16 @@ core_similarity_small = Small core_similarity_very_small = Very Small core_similarity_minimal = Minimal +core_cannot_open_dir = Cannot open dir {$dir}, reason {$reason} +core_cannot_read_entry_dir = Cannot read entry in dir {$dir}, reason {$reason} +core_cannot_read_metadata_dir = Cannot read metadata in dir {$dir}, reason {$reason} +core_file_not_utf8_name = File {$name} has not valid UTF-8 name(some characters may not be shown) +core_file_modified_before_epoch = File {$name} seems to be modified before Unix Epoch +core_folder_modified_before_epoch = Folder {$name} seems to be modified before Unix Epoch +core_file_no_modification_date = Unable to get modification date from file {$name}, reason {$reason} +core_folder_no_modification_date = Unable to get modification date from folder {$name}, reason {$reason} + + # General general_ok_button = Ok general_close_button = Close @@ -274,6 +284,11 @@ settings_multiple_delete_outdated_cache_checkbutton_tooltip = In case of having hundred of thousands records in cache, it is suggested to enable this option, to speedup cache loading and saving at start and end of scan. +settings_notebook_general = General +settings_notebook_duplicates = Duplicates +settings_notebook_images = Similar Images +settings_notebook_videos = Similar Video + ## Multiple - settings used in multiple tabs settings_multiple_delete_outdated_cache_checkbutton = Delete outdated cache entries automatically settings_multiple_delete_outdated_cache_checkbutton_tooltip = @@ -329,6 +344,9 @@ settings_saving_button = Save configuration settings_loading_button = Load configuration settings_reset_button = Reset configuration +settings_load_orphan_data = Found invalid header in line {$line_number} \"{$line}\" when loading file {$name} (save file may be from different Czkawka version) +settings_load_invalid_bool_value = Found invalid header in line {$line_number} \"{$line}\" which isn't proper value(0/1/true/false) when loading file {$name} + ## Opening cache/config folders settings_folder_cache_open_tooltip = @@ -368,25 +386,27 @@ compute_symlinks = invalid symlinks compute_broken_files = broken files # Progress window -progress_scanned = Scanned -progress_files = file -progress_folders = folders -progress_tags = Reading tags of -progress_hashing = Hashing -progress_checking = Checking -progress_size = size -progress_name = name -progress_analyzed_full_hash = Analyzed full hash of -progress_analyzed_partial_hash = Analyzed partial hash of +progress_scanning_general_file = Scanning {$file_number} file + +progress_scanning_broken_files = Checking {$file_checked}/{$all_files} file +progress_scanning_video = Hashing of {$file_checked}/{$all_files} video +progress_scanning_image = Hashing of {$file_checked}/{$all_files} image +progress_scanning_music_tags_end = Comparing tags of {$file_checked}/{$all_files} music file +progress_scanning_music_tags = Reading tags of {$file_checked}/{$all_files} music file +progress_scanning_empty_folders = Scanning {$folder_number} folder +progress_scanning_size = Scanning size of {$file_number} file +progress_scanning_name = Scanning name of {$file_number} file +progress_analyzed_partial_hash = Analyzed partial hash of {$file_checked}/{$all_files} files +progress_analyzed_full_hash = Analyzed full hash of {$file_checked}/{$all_files} files + +progress_current_stage = Current Stage:{" "} +progress_all_stages = All Stages:{" "} # Saving loading saving_loading_saving_success = Saved configuration to file saving_loading_reset_configuration = Current configuration was cleared. saving_loading_loading_success = Properly loaded configuration from file -progress_current_stage = Current Stage:{" "} -progress_all_stages = All Stages:{" "} - # Invalid symlinks invalid_symlink_infinite_recursion = Infinite recursion invalid_symlink_non_existent_destination = Non existent destination file @@ -401,15 +421,14 @@ text_view_errors = ERRORS dialogs_ask_next_time = Ask next time reason_of_error = reason -delete_file_failed = Failed to remove file +delete_file_failed = Failed to remove file {$name}, reason {$reason} delete_title_dialog = Delete confirmation delete_question_label = Are you sure that you want to delete files? delete_all_files_in_group_title = Confirmation of deleting all files in group delete_all_files_in_group_label1 = In some groups there are selected all records. delete_all_files_in_group_label2 = Are you sure that you want to delete them? -delete_folder_failed_1 = Failed to remove folder -delete_folder_failed_2 = because folder doesn't exists, you don't have permissions or isn't empty. +delete_folder_failed = Failed to remove folder {$dir} because folder doesn't exists, you don't have permissions or isn't empty. hardlink_failed = Failed to hardlink hard_sym_invalid_selection_title_dialog = Invalid selection with some groups @@ -419,14 +438,13 @@ hard_sym_invalid_selection_label_3 = First in group is recognized as original an hard_sym_link_title_dialog = Link confirmation hard_sym_link_label = Are you sure that you want to link this files? -move_folder_failed = Failed to move folder -move_file_failed = Failed to move file +move_folder_failed = Failed to move folder {$name}, reason {$reason} +move_file_failed = Failed to move file {$name}, reason {$reason} move_files_title_dialog = Choose folder to which you want to move duplicated files -move_files_choose_more_than_1_path = Only 1 path must be selected to be able to copy there duplicated files, found -move_stats_1 = Properly moved -move_stats_2 = items +move_files_choose_more_than_1_path = Only 1 path must be selected to be able to copy there duplicated files, selected {$path_number} +move_stats = Properly moved {$num_files}/{$all_files} items -save_results_to_file = Saved results to file +save_results_to_file = Saved results to file {$name} search_not_choosing_any_music = ERROR: You must select at least one checkbox with music searching types. @@ -443,3 +461,10 @@ cache_clear_message_label_1 = Do you want to clear cache from outdated entries? cache_clear_message_label_2 = This operation will remove all cache entries which points to invalid files. cache_clear_message_label_3 = This may speedup a little loading/saving to cache. cache_clear_message_label_4 = WARNING: Operation will remove all cached data from unplugged external drives, so hash will need to be generated again. + +# Show preview +preview_temporary_file = Failed to open temporary image file {$name}, reason {$reason} +preview_0_size = Cannot create preview of image {$name}, with 0 width or height +preview_temporary_image_save = Failed to save temporary image file to {$name}, reason {$reason} +preview_temporary_image_remove = Failed to delete temporary image file {$name}, reason {$reason} +preview_failed_to_create_cache_dir = Failed to create dir {$name} needed by image preview, reason {$reason} diff --git a/i18n/pl/czkawka_gui.ftl b/i18n/pl/czkawka_gui.ftl index e3b9304..27e1802 100644 --- a/i18n/pl/czkawka_gui.ftl +++ b/i18n/pl/czkawka_gui.ftl @@ -6,6 +6,16 @@ core_similarity_small = Małe core_similarity_very_small = Bardzo Małe core_similarity_minimal = Minimalne +core_cannot_open_dir = Nie można otworzyć folderu {$dir}, powód {$reason} +core_cannot_read_entry_dir = Nie można odczytać danych z folderu {$dir}, powód {$reason} +core_cannot_read_metadata_dir = Nie można odczytać metadanych folderu {$dir}, powód {$reason} +core_file_not_utf8_name = Plik {$name} nie posiada nazwy zakodowanej za pomocą UTF-8(niektóre znaki mogą się nie wyświetlać) +core_file_modified_before_epoch = Plik {$name} ma datę modyfikacji sprzed epoki unixa +core_folder_modified_before_epoch = Folder {$name} ma datę modyfikacji sprzed epoki unixa +core_file_no_modification_date = Nie udało się pobrać daty modyfikacji z pliku {$name}, powód {$reason} +core_folder_no_modification_date = Nie udało się pobrać daty modyfikacji z folderu {$name}, powód {$reason} + + # Różne general_ok_button = Ok general_close_button = Zamknij @@ -325,6 +335,11 @@ settings_duplicates_prehash_checkbutton = Używaj pamięci podręcznej dla hashy settings_duplicates_minimal_size_cache_label = Wielkość pliku, od którego hash będzie zapisywany w pamięci podręcznej settings_duplicates_minimal_size_cache_prehash_label = Wielkość pliku, od którego cząstkowy hash będzie zapisywany w pamięci podręcznej +settings_notebook_general = Ogólne +settings_notebook_duplicates = Duplikaty +settings_notebook_images = Podobne Obrazy +settings_notebook_videos = Podobne Wideo + ## Saving/Loading settings settings_saving_button_tooltip = Zapisuje aktualne ustawienia do pliku. settings_loading_button_tooltip = Ładuje ustawienia z pliku. @@ -334,6 +349,8 @@ settings_saving_button = Zapisanie ustawień settings_loading_button = Załadowanie ustawień settings_reset_button = Reset ustawień +settings_load_orphan_data = Znaleziono dane bez wlaściciela w lini {$line_number} \"{$line}\" podczas ładowania pliku {$name} (plik zapisu może pochodzić z innej wersji Czkawki) +settings_load_invalid_bool_value = Znaleziono nieprawidłowe dane w linii {$line_number} \"{$line}\" które nie są poprawną wartością binarną(0/1/true/false) w pliku {$name} ## Opening cache/config folders settings_folder_cache_open_tooltip = @@ -371,16 +388,19 @@ compute_symlinks = niepoprawnych linków symbolicznych compute_broken_files = zepsutych plików # Progress window -progress_scanned = Przeskanowano -progress_files = plików -progress_folders = folderów -progress_tags = Sczytano tagi z -progress_hashing = Przehashowano -progress_checking = Sprawdzono -progress_size = rozmiar -progress_name = nazwa -progress_analyzed_full_hash = Przeanalizowano pełny hash -progress_analyzed_partial_hash = Przeanalizowano częściowy hash + +progress_scanning_general_file = Skanowanie {$file_number} pliku + +progress_scanning_broken_files = Sprawdzanie {$file_checked}/{$all_files} pliku +progress_scanning_video = Hashowanie {$file_checked}/{$all_files} pliku wideo +progress_scanning_image = Hashowanie {$file_checked}/{$all_files} obrazu +progress_scanning_music_tags_end = Porównywanie tagów {$file_checked}/{$all_files} pliku audio +progress_scanning_music_tags = Sczytywanie tagów {$file_checked}/{$all_files} pliku audio +progress_scanning_empty_folders = Przeszukiwanie {$folder_number} folderu +progress_scanning_size = Sprawdzanie rozmiaru {$file_number} pliku +progress_scanning_name = Sprawdzanie nazwy {$file_number} pliku +progress_analyzed_partial_hash = Obliczanie częściowego hashu {$file_checked}/{$all_files} pliku +progress_analyzed_full_hash = Obliczanie pełnego hashu {$file_checked}/{$all_files} pliku progress_current_stage = Aktualny Etap:{" "} progress_all_stages = Wszystkie Etapy:{" "} @@ -404,15 +424,14 @@ text_view_errors = BŁĘDY dialogs_ask_next_time = Pytaj następnym razem reason_of_error = powód -delete_file_failed = Nie udało się usunąć pliku +delete_file_failed = Nie udało się usunąć pliku {$name}, powód {$reason} delete_title_dialog = Potwierdzenie usunięcia delete_question_label = Czy na pewno usunąć te pliki? delete_all_files_in_group_title = Potwierdzenie usunięcia wszystkich plików w grupie delete_all_files_in_group_label1 = W niektórych grupach zaznaczono wszystkie rekordy. delete_all_files_in_group_label2 = Czy na pewno je usunąć? -delete_folder_failed_1 = Nie udało się usunąć folderu -delete_folder_failed_2 = ponieważ nie istnieje, uprawnienia nie są wystarczające lub nie jest pusty. +delete_folder_failed = Nie udało się usunąć folderu {$name} ponieważ nie istnieje, uprawnienia nie są wystarczające lub nie jest pusty. hardlink_failed = Nie udało się utworzyć twardego dowiązania hard_sym_invalid_selection_title_dialog = Niepoprawne zaznaczenie w niektórych grupach @@ -422,14 +441,13 @@ hard_sym_invalid_selection_label_3 = Pierwszy pozostaje nienaruszony a drugi i k hard_sym_link_title_dialog = Potwierdzenie dowiązania hard_sym_link_label = Czy na pewno dowiązać te pliki? -move_folder_failed = Nie można przenieść folderu -move_file_failed = Nie można przenieść pliku +move_folder_failed = Nie można przenieść folderu {$name}, powód {$reason} +move_file_failed = Nie można przenieść pliku {$name}, powód {$reason} move_files_title_dialog = Wybierz folder do którego zostaną przeniesione pliki -move_files_choose_more_than_1_path = Można przenieść elementy tylko do 1 folderu, zaznaczono -move_stats_1 = Poprawnie przeniesiono -move_stats_2 = elementów +move_files_choose_more_than_1_path = Można przenieść elementy tylko do 1 folderu, zaznaczono {$path_number} +move_stats = Poprawnie przeniesiono {$num_files}/{$all_files} elementów -save_results_to_file = Zapisano wyniki do pliku +save_results_to_file = Zapisano wyniki do pliku {$name} search_not_choosing_any_music = BŁĄD: Musisz zaznaczyć przynajmniej jeden pole, według którego będą wyszukiwane podobne pliki muzyczne. @@ -446,3 +464,10 @@ cache_clear_message_label_1 = Czy na pewno chcesz oczyścić pamięć podręczn cache_clear_message_label_2 = Ta operacja usunie wszystkie rekordy, które wskazują na nieistniejące pliki. cache_clear_message_label_3 = Może spowodować to przyspieszenie ładowania i zapisywania danych do pamięci w trakcie skanowania. cache_clear_message_label_4 = OSTRZEŻENIE: Usunięte zostaną wszystkie rekordy z odpiętych dyskach zewnętrznych i konieczne będzie ich ponowne sprawdzenie po podpięciu. + +# Show preview +preview_temporary_file = Nie udało się otworzyć tymczasowego obrazu {$name}, powód {$reason} +preview_0_size = Nie można stworzyć podglądu obrazu {$name}, z wysokością lub szerokością 0 pikseli +preview_temporary_image_save = Nie udało się zapisać tymczasowego obrazu do {$name}, powód {$reason} +preview_temporary_image_remove = Nie udało się usunąć tymczasowego obrazu {$name}, powód {$reason} +preview_failed_to_create_cache_dir = Nie udało stworzyć się katalogu {$name} wymaganego do stworzenia podglądu obrazu, powód {$reason}