Commonsy
This commit is contained in:
parent
93e6f92e42
commit
69dea58516
116
Cargo.lock
generated
116
Cargo.lock
generated
|
@ -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",
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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<Path>) -> bool {
|
||||
pub fn remove_folder_if_contains_only_empty_folders(path: impl AsRef<Path>, 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<Path>) -> 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<String>) -> Option<((Option<File>, PathBuf), (Option<File>, 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());
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,15 @@ impl Messages {
|
|||
pub fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
pub fn new_from_errors(errors: Vec<String>) -> Self {
|
||||
Messages { errors, ..Default::default() }
|
||||
}
|
||||
pub fn new_from_warnings(warnings: Vec<String>) -> Self {
|
||||
Messages { warnings, ..Default::default() }
|
||||
}
|
||||
pub fn new_from_messages(messages: Vec<String>) -> Self {
|
||||
Messages { messages, ..Default::default() }
|
||||
}
|
||||
pub fn print_messages(&self) {
|
||||
println!("{}", self.create_messages_text());
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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::<GuiState>().set_info_text(Messages::new_from_errors(errors).create_messages_text().into());
|
||||
|
||||
app.global::<GuiState>().set_preview_visible(false);
|
||||
});
|
||||
}
|
||||
|
||||
fn handle_delete_items(items: &ModelRc<MainListModel>, active_tab: CurrentTab) -> Option<ModelRc<MainListModel>> {
|
||||
fn handle_delete_items(items: &ModelRc<MainListModel>, active_tab: CurrentTab, remove_to_trash: bool) -> (Vec<String>, Option<ModelRc<MainListModel>>) {
|
||||
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<String>, active_tab: CurrentTab) {
|
||||
fn remove_selected_items(items_to_remove: Vec<String>, active_tab: CurrentTab, remove_to_trash: bool) -> Vec<String> {
|
||||
// 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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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::<Callabler>().on_move_items(move |select_mode| {
|
||||
// let app = a.upgrade().unwrap();
|
||||
// let active_tab = app.global::<GuiState>().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::<Callabler>().on_move_items(move |select_mode, preserve_structure, copy_mode| {
|
||||
let app = a.upgrade().unwrap();
|
||||
let active_tab = app.global::<GuiState>().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::<GuiState>().set_info_text(Messages::new_from_errors(errors).create_messages_text().into());
|
||||
});
|
||||
}
|
||||
|
||||
fn move_operation(items: &ModelRc<MainListModel>, preserve_structure: bool, copy_mode: bool, output_folder: &str, active_tab: CurrentTab) -> Option<ModelRc<MainListModel>> {
|
||||
fn move_operation(
|
||||
items: &ModelRc<MainListModel>,
|
||||
preserve_structure: bool,
|
||||
copy_mode: bool,
|
||||
output_folder: &str,
|
||||
active_tab: CurrentTab,
|
||||
) -> (Vec<String>, Option<ModelRc<MainListModel>>) {
|
||||
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<String> {
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue