diff --git a/Cargo.lock b/Cargo.lock index cde8c0d..c120dac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -32,9 +32,9 @@ checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" [[package]] name = "aes" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher", @@ -43,9 +43,9 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.7" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +checksum = "42cd52102d3df161c77a887b608d7a4897d7cc112886a9537b738a887a03aaff" dependencies = [ "cfg-if", "getrandom", @@ -654,9 +654,9 @@ dependencies = [ [[package]] name = "cairo-rs" -version = "0.19.1" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc1c415b7088381c53c575420899c34c9e6312df5ac5defd05614210e9fd6e1b" +checksum = "2650f66005301bd33cc486dec076e1293c4cecf768bc7ba9bf5d2b1be339b99c" dependencies = [ "bitflags 2.4.2", "cairo-sys-rs", @@ -667,9 +667,9 @@ dependencies = [ [[package]] name = "cairo-sys-rs" -version = "0.19.1" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b6a5fefce2eadb8333e3c604ac964ba6573ec4f28bdd17f67032c4a2831831" +checksum = "fd3bb3119664efbd78b5e6c93957447944f16bdbced84c17a9f41c7829b81e64" dependencies = [ "glib-sys", "libc", @@ -786,9 +786,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.33" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f13690e35a5e4ace198e7beea2895d29f3a9cc55015fcebe6336bd2010af9eb" +checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" dependencies = [ "android-tzdata", "iana-time-zone", @@ -1102,9 +1102,9 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" dependencies = [ "cfg-if", ] @@ -1267,6 +1267,7 @@ dependencies = [ "state", "symphonia", "tempfile", + "trash", "vid_dup_finder_lib", "xxhash-rust", "zip", @@ -1618,9 +1619,9 @@ dependencies = [ [[package]] name = "enumflags2" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5998b4f30320c9d93aed72f63af821bfdac50465b75428fce77b48ec482c3939" +checksum = "3278c9d5fb675e0a51dabcf4c0d355f692b064171535ba72361be1528a9d8e8d" dependencies = [ "enumflags2_derive", "serde", @@ -1628,9 +1629,9 @@ dependencies = [ [[package]] name = "enumflags2_derive" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f95e2801cd355d4a1a3e3953ce6ee5ae9603a5c833455343a8bfe3f44d418246" +checksum = "5c785274071b1b420972453b306eeca06acf4633829db4223b58a2a8c5953bc4" dependencies = [ "proc-macro2", "quote", @@ -2168,9 +2169,9 @@ dependencies = [ [[package]] name = "gdk-pixbuf" -version = "0.19.0" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c311c47800051b87de1335e8792774d7cec551c91a0a3d109ab21d76b36f208f" +checksum = "f6a23f8a0b5090494fd04924662d463f8386cc678dd3915015a838c1a3679b92" dependencies = [ "gdk-pixbuf-sys", "gio", @@ -2298,9 +2299,9 @@ dependencies = [ [[package]] name = "gio" -version = "0.19.0" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1aaa2d926710a27f3b35822806b1513b393b71174dd2601c9d02fdab0cb82" +checksum = "2eae10b27b6dd27e22ed0d812c6387deba295e6fc004a8b379e459b663b05a02" dependencies = [ "futures-channel", "futures-core", @@ -2340,9 +2341,9 @@ dependencies = [ [[package]] name = "glib" -version = "0.19.0" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "170ee82b9b44b3b5fd1cf4971d6cf0eadec38303bb84c7bcc4e6b95a18934e71" +checksum = "ab9e86540b5d8402e905ad4ce7d6aa544092131ab564f3102175af176b90a053" dependencies = [ "bitflags 2.4.2", "futures-channel", @@ -2362,9 +2363,9 @@ dependencies = [ [[package]] name = "glib-macros" -version = "0.19.0" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ff52fff7e4d1bb8598ae744e9bb90c8c76271712483c3f0ce931bee9814de85" +checksum = "0f5897ca27a83e4cdc7b4666850bade0a2e73e17689aabafcc9acddad9d823b8" dependencies = [ "heck", "proc-macro-crate 3.1.0", @@ -2413,9 +2414,9 @@ dependencies = [ [[package]] name = "glutin" -version = "0.31.2" +version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "005459a22af86adc706522d78d360101118e2638ec21df3852fcc626e0dbb212" +checksum = "18fcd4ae4e86d991ad1300b8f57166e5be0c95ef1f63f3f5b827f8a164548746" dependencies = [ "bitflags 2.4.2", "cfg_aliases 0.1.1", @@ -2489,9 +2490,9 @@ dependencies = [ [[package]] name = "graphene-rs" -version = "0.19.0" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147827e4f506f8073ac3ec5b28cc2255bdf3abc30f5b4e101a80506eebe11d2c" +checksum = "99e4d388e96c5f29e2b2f67045d229ddf826d0a8d6d282f94ed3b34452222c91" dependencies = [ "glib", "graphene-sys", @@ -3124,9 +3125,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.2" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824b2ae422412366ba479e8111fd301f7b5faece8149317bb81925979a53f520" +checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" dependencies = [ "equivalent", "hashbrown 0.14.3", @@ -4087,9 +4088,9 @@ dependencies = [ [[package]] name = "pango" -version = "0.19.0" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78d7f779b957728c74fd1a060dfa6d89a0bea792ebc50cc2da80e4e87282d69e" +checksum = "7809e8af4df8d024a066106b72ca6bc7253a484ae3867041a96103ef8a13188d" dependencies = [ "gio", "glib", @@ -4186,7 +4187,7 @@ dependencies = [ "deflate", "fax", "globalcache", - "indexmap 2.2.2", + "indexmap 2.2.3", "istring", "itertools 0.10.5", "jpeg-decoder", @@ -5632,18 +5633,18 @@ checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233" [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" dependencies = [ "proc-macro2", "quote", @@ -5784,7 +5785,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.4", + "toml_edit 0.22.5", ] [[package]] @@ -5802,9 +5803,9 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.2.2", + "indexmap 2.2.3", "toml_datetime", - "winnow", + "winnow 0.5.40", ] [[package]] @@ -5813,22 +5814,22 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "indexmap 2.2.2", + "indexmap 2.2.3", "toml_datetime", - "winnow", + "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.22.4" +version = "0.22.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c9ffdf896f8daaabf9b66ba8e77ea1ed5ed0f72821b398aba62352e95062951" +checksum = "99e68c159e8f5ba8a28c4eb7b0c0c190d77bb479047ca713270048145a9ad28a" dependencies = [ - "indexmap 2.2.2", + "indexmap 2.2.3", "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.6.0", ] [[package]] @@ -5904,9 +5905,9 @@ dependencies = [ [[package]] name = "trash" -version = "3.3.0" +version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e0434017970a3b6770ee6f0117e9a7afe25b02e540fab01759e137e508e2f81" +checksum = "c658458d46d9d5a153a3b5cdd88d8579ad50d4fb85d53961e4526c8fc7c55a57" dependencies = [ "chrono", "libc", @@ -6253,7 +6254,7 @@ dependencies = [ "crossbeam-queue", "half", "heck", - "indexmap 2.2.2", + "indexmap 2.2.3", "libloading 0.8.1", "objc", "once_cell", @@ -6839,9 +6840,18 @@ dependencies = [ [[package]] name = "winnow" -version = "0.5.39" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5389a154b01683d28c77f8f68f49dea75f0a4da32557a58f68ee51ebba472d29" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1dbce9e90e5404c5a52ed82b1d13fc8cfbdad85033b6f57546ffd1265f8451" dependencies = [ "memchr", ] @@ -6963,9 +6973,9 @@ dependencies = [ [[package]] name = "xkbcommon-dl" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6924668544c48c0133152e7eec86d644a056ca3d09275eb8d5cdb9855f9d8699" +checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" dependencies = [ "bitflags 2.4.2", "dlib", diff --git a/czkawka_cli/Cargo.toml b/czkawka_cli/Cargo.toml index fa266c5..5fa4fb5 100644 --- a/czkawka_cli/Cargo.toml +++ b/czkawka_cli/Cargo.toml @@ -10,7 +10,7 @@ homepage = "https://github.com/qarmin/czkawka" repository = "https://github.com/qarmin/czkawka" [dependencies] -clap = { version = "4.4", features = ["derive"] } +clap = { version = "4.5", features = ["derive"] } # For enum types image_hasher = "1.2" diff --git a/czkawka_core/Cargo.toml b/czkawka_core/Cargo.toml index 3a4fcf6..7ae6b0f 100644 --- a/czkawka_core/Cargo.toml +++ b/czkawka_core/Cargo.toml @@ -39,7 +39,7 @@ symphonia = { version = "0.5", features = ["all"] } # Hashes for duplicate files blake3 = "1.5" -crc32fast = "1.3" +crc32fast = "1.4" xxhash-rust = { version = "0.8", features = ["xxh3"] } tempfile = "3.10" @@ -75,6 +75,7 @@ anyhow = { version = "1.0" } state = "0.6" +trash = "3.3" os_info = { version = "3", default-features = false } log = "0.4.20" diff --git a/czkawka_core/src/common.rs b/czkawka_core/src/common.rs index 098be44..94c7201 100644 --- a/czkawka_core/src/common.rs +++ b/czkawka_core/src/common.rs @@ -146,22 +146,21 @@ pub const VIDEO_FILES_EXTENSIONS: &[&str] = &[ pub const LOOP_DURATION: u32 = 20; //ms pub const SEND_PROGRESS_DATA_TIME_BETWEEN: u32 = 200; //ms -pub fn remove_folder_if_contains_only_empty_folders(path: impl AsRef) -> bool { +pub fn remove_folder_if_contains_only_empty_folders(path: impl AsRef, remove_to_trash: bool) -> Result<(), String> { let path = path.as_ref(); if !path.is_dir() { - error!("Trying to remove folder which is not a directory"); - return false; + return Err(format!("Trying to remove folder {path:?} which is not a directory",)); } let mut entries_to_check = Vec::new(); let Ok(initial_entry) = path.read_dir() else { - return false; + return Err(format!("Cannot read directory {path:?}",)); }; for entry in initial_entry { if let Ok(entry) = entry { entries_to_check.push(entry); } else { - return false; + return Err(format!("Cannot read entry from directory {path:?}")); } } loop { @@ -169,25 +168,29 @@ pub fn remove_folder_if_contains_only_empty_folders(path: impl AsRef) -> b break; }; let Some(file_type) = entry.file_type().ok() else { - return false; + return Err(format!("Folder contains file with unknown type {:?} inside {path:?}", entry.path())); }; if !file_type.is_dir() { - return false; + return Err(format!("Folder contains file {:?} inside {path:?}", entry.path(),)); } let Ok(internal_read_dir) = entry.path().read_dir() else { - return false; + return Err(format!("Cannot read directory {:?} inside {path:?}", entry.path())); }; for internal_elements in internal_read_dir { if let Ok(internal_element) = internal_elements { entries_to_check.push(internal_element); } else { - return false; + return Err(format!("Cannot read entry from directory {:?} inside {path:?}", entry.path())); } } } - fs::remove_dir_all(path).is_ok() + if remove_to_trash { + trash::delete(path).map_err(|e| format!("Cannot move folder {path:?} to trash, reason {e}")) + } else { + fs::remove_dir_all(path).map_err(|e| format!("Cannot remove directory {path:?}, reason {e}")) + } } pub fn open_cache_folder(cache_file_name: &str, save_to_cache: bool, use_json: bool, warnings: &mut Vec) -> Option<((Option, PathBuf), (Option, PathBuf))> { @@ -621,20 +624,20 @@ mod test { fs::create_dir(&sub_dir).unwrap(); // Test with empty directory - assert!(remove_folder_if_contains_only_empty_folders(&sub_dir)); + assert!(remove_folder_if_contains_only_empty_folders(&sub_dir, false).is_ok()); assert!(!Path::new(&sub_dir).exists()); // Test with directory containing an empty directory fs::create_dir(&sub_dir).unwrap(); fs::create_dir(sub_dir.join("empty_sub_dir")).unwrap(); - assert!(remove_folder_if_contains_only_empty_folders(&sub_dir)); + assert!(remove_folder_if_contains_only_empty_folders(&sub_dir, false).is_ok()); assert!(!Path::new(&sub_dir).exists()); // Test with directory containing a file fs::create_dir(&sub_dir).unwrap(); let mut file = fs::File::create(sub_dir.join("file.txt")).unwrap(); writeln!(file, "Hello, world!").unwrap(); - assert!(!remove_folder_if_contains_only_empty_folders(&sub_dir)); + assert!(remove_folder_if_contains_only_empty_folders(&sub_dir, false).is_err()); assert!(Path::new(&sub_dir).exists()); } diff --git a/czkawka_core/src/common_messages.rs b/czkawka_core/src/common_messages.rs index 0b45743..9e4b26f 100644 --- a/czkawka_core/src/common_messages.rs +++ b/czkawka_core/src/common_messages.rs @@ -9,6 +9,15 @@ impl Messages { pub fn new() -> Self { Default::default() } + pub fn new_from_errors(errors: Vec) -> Self { + Messages { errors, ..Default::default() } + } + pub fn new_from_warnings(warnings: Vec) -> Self { + Messages { warnings, ..Default::default() } + } + pub fn new_from_messages(messages: Vec) -> Self { + Messages { messages, ..Default::default() } + } pub fn print_messages(&self) { println!("{}", self.create_messages_text()); } diff --git a/czkawka_gui/Cargo.toml b/czkawka_gui/Cargo.toml index 27064da..6ca2932 100644 --- a/czkawka_gui/Cargo.toml +++ b/czkawka_gui/Cargo.toml @@ -15,7 +15,7 @@ glib = "0.19" gtk4 = { version = "0.8", default-features = false, features = ["v4_6"] } humansize = "2.1" -chrono = "0.4.33" +chrono = "0.4.34" # Used for sending stop signal across threads crossbeam-channel = "0.5" diff --git a/krokiet/Cargo.toml b/krokiet/Cargo.toml index e816f48..8b56513 100644 --- a/krokiet/Cargo.toml +++ b/krokiet/Cargo.toml @@ -13,7 +13,7 @@ build = "build.rs" [dependencies] rand = "0.8" czkawka_core = { version = "6.1.0", path = "../czkawka_core" } -chrono = "0.4.33" +chrono = "0.4.34" open = "5.0" crossbeam-channel = "0.5" handsome_logger = "0.8" diff --git a/krokiet/src/common.rs b/krokiet/src/common.rs index 2243774..b4c3fbd 100644 --- a/krokiet/src/common.rs +++ b/krokiet/src/common.rs @@ -1,7 +1,7 @@ use std::path::PathBuf; -use crate::{CurrentTab, ExcludedDirectoriesModel, IncludedDirectoriesModel, MainListModel, MainWindow}; -use slint::{ModelRc, SharedString, VecModel}; +use crate::{CurrentTab, ExcludedDirectoriesModel, GuiState, IncludedDirectoriesModel, MainListModel, MainWindow}; +use slint::{ComponentHandle, ModelRc, SharedString, VecModel}; // Remember to match updated this according to ui/main_lists.slint and connect_scan.rs files pub fn get_str_path_idx(active_tab: CurrentTab) -> usize { diff --git a/krokiet/src/connect_delete.rs b/krokiet/src/connect_delete.rs index b0c1df9..ea5ec6d 100644 --- a/krokiet/src/connect_delete.rs +++ b/krokiet/src/connect_delete.rs @@ -2,6 +2,7 @@ use rayon::prelude::*; use slint::{ComponentHandle, ModelRc, VecModel}; use czkawka_core::common::remove_folder_if_contains_only_empty_folders; +use czkawka_core::common_messages::Messages; use crate::common::{get_is_header_mode, get_tool_model, set_tool_model}; use crate::model_operations::{collect_full_path_from_model, deselect_all_items, filter_out_checked_items}; @@ -16,43 +17,54 @@ pub fn connect_delete_button(app: &MainWindow) { let model = get_tool_model(&app, active_tab); - let new_model = handle_delete_items(&model, active_tab); + let remove_to_trash = false; + + let (errors, new_model) = handle_delete_items(&model, active_tab, remove_to_trash); if let Some(new_model) = new_model { set_tool_model(&app, active_tab, new_model); } + app.global::().set_info_text(Messages::new_from_errors(errors).create_messages_text().into()); + app.global::().set_preview_visible(false); }); } -fn handle_delete_items(items: &ModelRc, active_tab: CurrentTab) -> Option> { +fn handle_delete_items(items: &ModelRc, active_tab: CurrentTab, remove_to_trash: bool) -> (Vec, Option>) { let (entries_to_delete, mut entries_left) = filter_out_checked_items(items, get_is_header_mode(active_tab)); if !entries_to_delete.is_empty() { let vec_items_to_remove = collect_full_path_from_model(&entries_to_delete, active_tab); - remove_selected_items(vec_items_to_remove, active_tab); + let errors = remove_selected_items(vec_items_to_remove, active_tab, remove_to_trash); deselect_all_items(&mut entries_left); let r = ModelRc::new(VecModel::from(entries_left)); // TODO here maybe should also stay old model if entries cannot be removed - return Some(r); + return (errors, Some(r)); } - None + (vec![], None) } // TODO delete in parallel items, consider to add progress bar // For empty folders double check if folders are really empty - this function probably should be run in thread // and at the end should be send signal to main thread to update model // TODO handle also situations where cannot delete file/folder -fn remove_selected_items(items_to_remove: Vec, active_tab: CurrentTab) { +fn remove_selected_items(items_to_remove: Vec, active_tab: CurrentTab, remove_to_trash: bool) -> Vec { // Iterate over empty folders and not delete them if they are not empty if active_tab == CurrentTab::EmptyFolders { - items_to_remove.into_par_iter().for_each(|item| { - remove_folder_if_contains_only_empty_folders(item); - }); + items_to_remove + .into_par_iter() + .filter_map(|item| remove_folder_if_contains_only_empty_folders(item, remove_to_trash).err()) + .collect() } else { - items_to_remove.into_par_iter().for_each(|item| { - let _ = std::fs::remove_file(item); - }); + items_to_remove + .into_par_iter() + .filter_map(|item| { + if let Err(e) = std::fs::remove_file(item) { + return Some(format!("Error while removing file: {e}")); + } + None + }) + .collect() } } diff --git a/krokiet/src/connect_move.rs b/krokiet/src/connect_move.rs index 6f07484..8a4510a 100644 --- a/krokiet/src/connect_move.rs +++ b/krokiet/src/connect_move.rs @@ -1,8 +1,8 @@ -use crate::common::{get_is_header_mode, get_tool_model}; +use crate::common::{get_is_header_mode, get_tool_model, set_tool_model}; use crate::model_operations::{collect_path_name_from_model, deselect_all_items, filter_out_checked_items}; -use crate::CurrentTab; -use crate::{Callabler, GuiState, MainListModel, MainWindow}; +use crate::{Callabler, CurrentTab, GuiState, MainListModel, MainWindow}; +use czkawka_core::common_messages::Messages; use rayon::prelude::*; use slint::{ComponentHandle, ModelRc, VecModel}; use std::path::{Path, PathBuf}; @@ -10,32 +10,42 @@ use std::{fs, path}; pub fn connect_move(app: &MainWindow) { let a = app.as_weak(); - // app.global::().on_move_items(move |select_mode| { - // let app = a.upgrade().unwrap(); - // let active_tab = app.global::().get_active_tab(); - // let current_model = get_tool_model(&app, active_tab); - // - // // If tree structure will be - // let preserve_structure = false; - // let copy_mode = true; - // let output_folder = "/home/rafal/Downloads/AAAAAAAA"; - // move_operation(¤t_model, preserve_structure, copy_mode, output_folder, active_tab); - // }); - // move_selected_items(vec![("/home/rafal/".to_string(), "Other.png".to_string())], true, true, "/home/rafal/Downloads/AAAAAAAA"); + app.global::().on_move_items(move |select_mode, preserve_structure, copy_mode| { + let app = a.upgrade().unwrap(); + let active_tab = app.global::().get_active_tab(); + let current_model = get_tool_model(&app, active_tab); + + // If tree structure will be + let preserve_structure = false; + let copy_mode = true; + let output_folder = "/home/rafal/Downloads/AAAAAAAA"; + + let (errors, new_model) = move_operation(¤t_model, preserve_structure, copy_mode, output_folder, active_tab); + if let Some(new_model) = new_model { + set_tool_model(&app, active_tab, new_model); + } + app.global::().set_info_text(Messages::new_from_errors(errors).create_messages_text().into()); + }); } -fn move_operation(items: &ModelRc, preserve_structure: bool, copy_mode: bool, output_folder: &str, active_tab: CurrentTab) -> Option> { +fn move_operation( + items: &ModelRc, + preserve_structure: bool, + copy_mode: bool, + output_folder: &str, + active_tab: CurrentTab, +) -> (Vec, Option>) { let (entries_to_move, mut entries_left) = filter_out_checked_items(items, get_is_header_mode(active_tab)); if !entries_to_move.is_empty() { let vec_items_to_move = collect_path_name_from_model(&entries_to_move, active_tab); - move_selected_items(vec_items_to_move, preserve_structure, copy_mode, output_folder); + let errors = move_selected_items(vec_items_to_move, preserve_structure, copy_mode, output_folder); deselect_all_items(&mut entries_left); let r = ModelRc::new(VecModel::from(entries_left)); - return Some(r); + return (errors, Some(r)); } - None + (vec![], None) } fn move_selected_items(items_to_move: Vec<(String, String)>, preserve_structure: bool, copy_mode: bool, output_folder: &str) -> Vec { @@ -78,7 +88,7 @@ fn move_selected_items(items_to_move: Vec<(String, String)>, preserve_structure: )); } if let Err(e) = fs::remove_file(&input_file) { - return Some(format!("Error while removing file {input_file:?}, reason {e}")); + return Some(format!("Error while removing file {input_file:?}(after copying into different partition), reason {e}")); } None diff --git a/krokiet/src/connect_select.rs b/krokiet/src/connect_select.rs index 78e6da4..88aed10 100644 --- a/krokiet/src/connect_select.rs +++ b/krokiet/src/connect_select.rs @@ -1,8 +1,7 @@ use crate::common::{ connect_i32_into_u64, get_int_height_idx, get_int_modification_date_idx, get_int_size_idx, get_int_width_idx, get_is_header_mode, get_tool_model, set_tool_model, }; -use crate::{Callabler, GuiState, MainListModel, MainWindow, SelectMode}; -use crate::{CurrentTab, SelectModel}; +use crate::{Callabler, CurrentTab, GuiState, MainListModel, MainWindow, SelectMode, SelectModel}; use slint::{ComponentHandle, Model, ModelRc, VecModel}; // TODO optimize this, not sure if it is possible to not copy entire model to just select item