1
0
Fork 0
mirror of synced 2024-04-28 09:33:30 +12:00

Add option to exclude files from other filesystems in GUI(Linux) (#776)

* Add exclude other fs to GUI

* Exclude in FS

* Fix crashes in gui and core

* More tests
This commit is contained in:
Rafał Mikrut 2022-07-19 19:09:52 +02:00 committed by GitHub
parent 07cfc7884f
commit 8f0527cd33
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
33 changed files with 288 additions and 131 deletions

136
Cargo.lock generated
View file

@ -284,9 +284,9 @@ checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
[[package]]
name = "cfb"
version = "0.7.2"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19ff6ea9647f5b4fb422a553d5b6fe1b398986a6e4f458d1219eb77e0e6e0606"
checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f"
dependencies = [
"byteorder",
"fnv",
@ -341,9 +341,9 @@ dependencies = [
[[package]]
name = "clap"
version = "3.2.8"
version = "3.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "190814073e85d238f31ff738fcb0bf6910cedeb73376c87cd69291028966fd83"
checksum = "ab8b79fe3946ceb4a0b1c080b4018992b8d27e9ff363644c1c9b6387c854614d"
dependencies = [
"atty",
"bitflags",
@ -455,9 +455,9 @@ dependencies = [
[[package]]
name = "crypto-common"
version = "0.1.4"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5999502d32b9c48d492abe66392408144895020ec4709e549e840799f3bb74c0"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"typenum",
@ -491,7 +491,7 @@ dependencies = [
"humansize",
"i18n-embed",
"i18n-embed-fl",
"image 0.24.2",
"image 0.24.3",
"image_hasher",
"imagepipe",
"infer",
@ -528,7 +528,7 @@ dependencies = [
"humansize",
"i18n-embed",
"i18n-embed-fl",
"image 0.24.2",
"image 0.24.3",
"image_hasher",
"once_cell",
"open",
@ -1217,9 +1217,9 @@ checksum = "65043da274378d68241eb9a8f8f8aa54e349136f7b8e12f63e3ef44043cc30e1"
[[package]]
name = "hashbrown"
version = "0.12.1"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "heck"
@ -1352,9 +1352,9 @@ dependencies = [
[[package]]
name = "image"
version = "0.24.2"
version = "0.24.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28edd9d7bc256be2502e325ac0628bde30b7001b9b52e0abe31a1a9dc2701212"
checksum = "7e30ca2ecf7666107ff827a8e481de6a132a9b687ed3bb20bb1c144a36c00964"
dependencies = [
"bytemuck",
"byteorder",
@ -1362,7 +1362,6 @@ dependencies = [
"exr",
"gif",
"jpeg-decoder 0.2.6",
"num-iter",
"num-rational 0.4.1",
"num-traits",
"png 0.17.5",
@ -1377,7 +1376,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c887ed1c9c32854da1c3c9539711814ae48e53926400c5e1ceac0f0491f59a72"
dependencies = [
"base64 0.20.0-alpha.1",
"image 0.24.2",
"image 0.24.3",
"rustdct 0.5.1",
"serde",
"transpose",
@ -1391,7 +1390,7 @@ checksum = "7af2d89e882e4be2e9b1ef50454aaa8da2c58924960e24521145f16ea4f7fd1c"
dependencies = [
"bincode",
"blake3",
"image 0.24.2",
"image 0.24.3",
"lazy_static",
"log",
"multicache",
@ -1570,9 +1569,9 @@ dependencies = [
[[package]]
name = "lofty"
version = "0.7.0"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f4e4309226629ef3486925c6a1b346241abeb30758e307b3ca9cfd66587bf4f"
checksum = "b6d1ba3c036ad548be962a93536441b393429b24da8492b1b5288012164b8a8f"
dependencies = [
"base64 0.13.0",
"byteorder",
@ -1822,9 +1821,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "open"
version = "3.0.1"
version = "3.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "360bcc8316bf6363aa3954c3ccc4de8add167b087e0259190a043c9514f910fe"
checksum = "f23a407004a1033f53e93f9b45580d14de23928faad187384f891507c9b0c045"
dependencies = [
"pathdiff",
"windows-sys",
@ -1838,9 +1837,9 @@ checksum = "91409674c628d07a6b4b79cc877c6b63ba5ccbfbadddd77ca822f55069ed1bd4"
[[package]]
name = "os_str_bytes"
version = "6.1.0"
version = "6.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa"
checksum = "648001efe5d5c0102d8cea768e348da85d90af8ba91f0bea908f157951493cd4"
[[package]]
name = "pango"
@ -2208,9 +2207,9 @@ dependencies = [
[[package]]
name = "regex"
version = "1.5.6"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1"
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
dependencies = [
"aho-corasick",
"memchr",
@ -2219,9 +2218,9 @@ dependencies = [
[[package]]
name = "regex-syntax"
version = "0.6.26"
version = "0.6.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
[[package]]
name = "remove_dir_all"
@ -2394,18 +2393,18 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.138"
version = "1.0.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1578c6245786b9d168c5447eeacfb96856573ca56c9d68fdcf394be134882a47"
checksum = "0171ebb889e45aa68b44aee0859b3eede84c6f5f5c228e6f140c0b2a0a46cad6"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.138"
version = "1.0.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "023e9b1467aef8a10fb88f25611870ada9800ef7e22afce356bb0d2387b6f27c"
checksum = "dc1d3230c1de7932af58ad8ffbe1d784bd55efd5a9d84ac24f69c72d83543dfb"
dependencies = [
"proc-macro2",
"quote",
@ -2425,9 +2424,9 @@ dependencies = [
[[package]]
name = "serde_yaml"
version = "0.8.24"
version = "0.8.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "707d15895415db6628332b737c838b88c598522e4dc70647e59b72312924aebc"
checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b"
dependencies = [
"indexmap",
"ryu",
@ -2472,9 +2471,12 @@ dependencies = [
[[package]]
name = "slab"
version = "0.4.6"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32"
checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
dependencies = [
"autocfg",
]
[[package]]
name = "smallvec"
@ -2505,9 +2507,9 @@ dependencies = [
[[package]]
name = "spin"
version = "0.9.3"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c530c2b0d0bf8b69304b39fe2001993e267461948b890cd037d8ad4293fa1a0d"
checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09"
dependencies = [
"lock_api",
]
@ -2542,9 +2544,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
[[package]]
name = "symphonia"
version = "0.5.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb30457ee7a904dae1e4ace25156dcabaf71e425db318e7885267f09cd8fb648"
checksum = "17033fe05e4f7f10a6ad602c272bafd2520b2e5cdd9feb61494d9cdce08e002f"
dependencies = [
"lazy_static",
"symphonia-bundle-flac",
@ -2563,9 +2565,9 @@ dependencies = [
[[package]]
name = "symphonia-bundle-flac"
version = "0.5.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f34f8f90825ee2692df0ee64981312267d6cf640358c3db7a4805d1805340665"
checksum = "044f655337892b217d6df1d8336ee119414c3886c89c72e0156989cd2ad7934a"
dependencies = [
"log",
"symphonia-core",
@ -2575,9 +2577,9 @@ dependencies = [
[[package]]
name = "symphonia-bundle-mp3"
version = "0.5.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9130cae661447f234b58759d74d23500e9c95697b698589b34196cb0fb488a61"
checksum = "db5d3d53535ae2b7d0e39e82f683cac5398a6c8baca25ff1183e107d13959d3e"
dependencies = [
"bitflags",
"lazy_static",
@ -2588,9 +2590,9 @@ dependencies = [
[[package]]
name = "symphonia-codec-aac"
version = "0.5.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96671dbcf83a4415e899812c5820dd26f48b9a6fece8b8d680e3004553080468"
checksum = "9e9431b89428c31b01428563df18e52b1aff7c49e71fb80b2fa8e85632094776"
dependencies = [
"lazy_static",
"log",
@ -2599,9 +2601,9 @@ dependencies = [
[[package]]
name = "symphonia-codec-alac"
version = "0.5.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a95d0cc9d94c55d9467e71e26990e509bd5a602fabde3ee422d87f77bbda860a"
checksum = "452438d6f32bf07f2f55f35371c3c8e9cce4a028a08b47fb301001f85a950f02"
dependencies = [
"log",
"symphonia-core",
@ -2609,9 +2611,9 @@ dependencies = [
[[package]]
name = "symphonia-codec-pcm"
version = "0.5.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0812a197602dff1f963ff212f174c4aa4d9b695d6511ba7a8fe2470296cf8310"
checksum = "17cca412c954abda6ab62b5e51223568eb604ed8266ec777d99e1d63c608443c"
dependencies = [
"log",
"symphonia-core",
@ -2619,9 +2621,9 @@ dependencies = [
[[package]]
name = "symphonia-codec-vorbis"
version = "0.5.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "746fc459966b37e277565f9632e5ffd6cbd83d9381152727123f68484cb8f9c4"
checksum = "323b94435a1a807e1001e29490aeaef2660fb72b145d47497e8429a6cb1d67c3"
dependencies = [
"log",
"symphonia-core",
@ -2630,9 +2632,9 @@ dependencies = [
[[package]]
name = "symphonia-core"
version = "0.5.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1edcb254d25e02b688b6f8a290a778153fa5f29674ac50773d03e0a16060391d"
checksum = "199a6417cd4115bac79289b64b859358ea050b7add0ceb364dc991f628c5b347"
dependencies = [
"arrayvec",
"bitflags",
@ -2643,9 +2645,9 @@ dependencies = [
[[package]]
name = "symphonia-format-isomp4"
version = "0.5.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a335816c1840bf3ce92b968a93b7b5c14a5d74737ad9ed63567ea451eac1951"
checksum = "1dce84cea63247dfcc43e12edf2d19406fbb62ebc24bac1b8e6c49f1ba67b890"
dependencies = [
"encoding_rs",
"log",
@ -2656,9 +2658,9 @@ dependencies = [
[[package]]
name = "symphonia-format-mkv"
version = "0.5.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "901a52e62285b3794a3ecb9b8a00b1d92d639e0dabf51eac0823a16493752726"
checksum = "f405400330b2cc0c70e19515198628ae9a6a99a59c77800541127d4cff113b96"
dependencies = [
"lazy_static",
"log",
@ -2669,9 +2671,9 @@ dependencies = [
[[package]]
name = "symphonia-format-ogg"
version = "0.5.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00f5b92a2a6370873d9dbe3326dad1bf795b3151efcadca6e5f47d732499a518"
checksum = "8d2f741469a0f103607ed1f2605f7f00b13ba044ea9ddc616764558c6d3d9b7d"
dependencies = [
"log",
"symphonia-core",
@ -2681,9 +2683,9 @@ dependencies = [
[[package]]
name = "symphonia-format-wav"
version = "0.5.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66b2016576a9f7e5e95f9354993116458170a9077845a908ee67a4c81e8072c0"
checksum = "5f9d771aa6889f05b771e629110f6a60b5e1c0ad580fc41da574bc490fbe2822"
dependencies = [
"log",
"symphonia-core",
@ -2692,9 +2694,9 @@ dependencies = [
[[package]]
name = "symphonia-metadata"
version = "0.5.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f04ee665c99fd2b919b87261c86a5312e996b720ca142646a163d9583e72bd0e"
checksum = "6ed71acf6b5e6e8bee1509597b86365a06b78c1d73218df47357620a6fe5997b"
dependencies = [
"encoding_rs",
"lazy_static",
@ -2704,9 +2706,9 @@ dependencies = [
[[package]]
name = "symphonia-utils-xiph"
version = "0.5.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abadfa53359fa437836f2554a0019dd06bfdf742fbb735d0645db3b6c5a763e0"
checksum = "73cbb0766ce77a8aef535f9438db645e7b6f1b2c4cf3be9bf246b4e11a7d5531"
dependencies = [
"symphonia-core",
"symphonia-metadata",
@ -2964,9 +2966,9 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
[[package]]
name = "unicode-ident"
version = "1.0.1"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7"
[[package]]
name = "unicode-normalization"
@ -3103,9 +3105,9 @@ checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be"
[[package]]
name = "weezl"
version = "0.1.6"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c97e489d8f836838d497091de568cf16b117486d529ec5579233521065bd5e4"
checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb"
[[package]]
name = "winapi"

View file

@ -1,9 +1,10 @@
## Version 5.0.0 - ?.?.2022r
- GTK 4 port - [#466](https://github.com/qarmin/czkawka/pull/466)
- GUI ported to use GTK 4 - [#466](https://github.com/qarmin/czkawka/pull/466)
- Use multithreading and improved algorithm to compare image hashes - [#762](https://github.com/qarmin/czkawka/pull/762)
- Resize preview with window - [#466](https://github.com/qarmin/czkawka/pull/466)
- Fix removing only one item from list view - [#466](https://github.com/qarmin/czkawka/pull/466)
- Fix showing help command in duplicate CLI mode - [#720](https://github.com/qarmin/czkawka/pull/720)
- Fix freeze when not choosing any tag in similar music mode - [TODO]()
- Fix freeze when not choosing any tag in similar music mode - [#732](https://github.com/qarmin/czkawka/pull/732)
- Fix preview of files with non-lowercase extensions - [#694](https://github.com/qarmin/czkawka/pull/694)
- Read more tags from music files - [#705](https://github.com/qarmin/czkawka/pull/705)
- Improve checking for invalid extensions - [#705](https://github.com/qarmin/czkawka/pull/705), [#747](https://github.com/qarmin/czkawka/pull/747), [#749](https://github.com/qarmin/czkawka/pull/749)
@ -15,6 +16,7 @@
- Improve Windows CI - [#749](https://github.com/qarmin/czkawka/pull/749)
- Ability to check for broken files by types - [#749](https://github.com/qarmin/czkawka/pull/749)
- Add heif and Webp files support - [#750](https://github.com/qarmin/czkawka/pull/750)
- Use in CLI Clap library instead StructOpt - [#759](https://github.com/qarmin/czkawka/pull/759)
## Version 4.1.0 - 24.04.2022r
- New mode - finding files whose content not match with their extension - [#678](https://github.com/qarmin/czkawka/pull/678)

View file

@ -3,13 +3,14 @@ name = "czkawka_cli"
version = "4.1.0"
authors = ["Rafał Mikrut <mikrutrafal@protonmail.com>"]
edition = "2021"
rust-version = "1.60"
description = "CLI frontend of Czkawka"
license = "MIT"
homepage = "https://github.com/qarmin/czkawka"
repository = "https://github.com/qarmin/czkawka"
[dependencies]
clap = { version = "3.2.3", features = ["derive"]}
clap = { version = "3.2.12", features = ["derive"] }
# For enum types
image_hasher = "1.0.0"
@ -21,4 +22,4 @@ features = []
[features]
default = []
heif = ["czkawka_core/heif"]
heif = ["czkawka_core/heif"]

View file

@ -3,6 +3,7 @@ name = "czkawka_core"
version = "4.1.0"
authors = ["Rafał Mikrut <mikrutrafal@protonmail.com>"]
edition = "2021"
rust-version = "1.60"
description = "Core of Czkawka app"
license = "MIT"
homepage = "https://github.com/qarmin/czkawka"
@ -11,8 +12,8 @@ repository = "https://github.com/qarmin/czkawka"
[dependencies]
humansize = "1.1.1"
rayon = "1.5.1"
crossbeam-channel = "0.5.4"
rayon = "1.5.3"
crossbeam-channel = "0.5.5"
# For saving/loading config files to specific directories
directories-next = "2.0.0"
@ -20,18 +21,18 @@ directories-next = "2.0.0"
# Needed by similar images
image_hasher = "1.0.0"
bk-tree = "0.4.0"
image = "0.24.2"
image = "0.24.3"
hamming = "0.1.3"
# Needed by same music
bitflags = "1.3.2"
lofty="0.7.0"
lofty= "0.7.2"
# Futures - needed by async progress sender
futures = "0.3.21"
# Needed by broken files
zip = { version = "0.6.2", features=["aes-crypto", "bzip2", "deflate", "time"], default-features = false}
zip = { version = "0.6.2", features = ["aes-crypto", "bzip2", "deflate", "time"], default-features = false }
audio_checker = "0.1.0"
pdf = "0.7.2"
@ -47,15 +48,15 @@ vid_dup_finder_lib = "0.1.0"
ffmpeg_cmdline_utils = "0.1.1"
# Saving/Loading Cache
serde = "1.0.137"
serde = "1.0.139"
bincode = "1.3.3"
serde_json = "1.0.81"
serde_json = "1.0.82"
# Language
i18n-embed = { version = "0.13.4", features = ["fluent-system", "desktop-requester"] }
i18n-embed-fl = "0.6.4"
rust-embed = "6.4.0"
once_cell = "1.10.0"
once_cell = "1.13.0"
# Raw image files
rawloader = "0.37.1"
@ -68,8 +69,8 @@ infer = "0.9.0"
num_cpus = "1.13.1"
libheif-rs = { version = "0.15.0", optional = true }
anyhow = { version = "1.0.57", optional = true }
anyhow = { version = "1.0.58", optional = true }
[features]
default = []
heif = ["dep:libheif-rs", "dep:anyhow"]
heif = ["dep:libheif-rs", "dep:anyhow"]

View file

@ -238,6 +238,12 @@ impl BadExtensions {
t => t,
};
}
#[cfg(target_family = "unix")]
pub fn set_exclude_other_filesystems(&mut self, exclude_other_filesystems: bool) {
self.directories.set_exclude_other_filesystems(exclude_other_filesystems);
}
#[cfg(not(target_family = "unix"))]
pub fn set_exclude_other_filesystems(&mut self, _exclude_other_filesystems: bool) {}
pub const fn get_text_messages(&self) -> &Messages {
&self.text_messages

View file

@ -133,6 +133,8 @@ impl BigFile {
pub fn set_exclude_other_filesystems(&mut self, exclude_other_filesystems: bool) {
self.directories.set_exclude_other_filesystems(exclude_other_filesystems);
}
#[cfg(not(target_family = "unix"))]
pub fn set_exclude_other_filesystems(&mut self, _exclude_other_filesystems: bool) {}
/// List of allowed extensions, only files with this extensions will be checking if are duplicates
pub fn set_allowed_extensions(&mut self, allowed_extensions: String) {

View file

@ -171,6 +171,8 @@ impl BrokenFiles {
pub fn set_exclude_other_filesystems(&mut self, exclude_other_filesystems: bool) {
self.directories.set_exclude_other_filesystems(exclude_other_filesystems);
}
#[cfg(not(target_family = "unix"))]
pub fn set_exclude_other_filesystems(&mut self, _exclude_other_filesystems: bool) {}
pub fn set_included_directory(&mut self, included_directory: Vec<PathBuf>) -> bool {
self.directories.set_included_directory(included_directory, &mut self.text_messages)

View file

@ -13,7 +13,6 @@ pub struct Directories {
pub excluded_directories: Vec<PathBuf>,
pub included_directories: Vec<PathBuf>,
pub reference_directories: Vec<PathBuf>,
#[cfg(target_family = "unix")]
exclude_other_filesystems: Option<bool>,
#[cfg(target_family = "unix")]
included_dev_ids: Vec<u64>,
@ -181,7 +180,8 @@ impl Directories {
self.reference_directories.dedup();
// Optimize for duplicated included directories - "/", "/home". "/home/Pulpit" to "/"
if recursive_search {
// Do not use when not using recursive search or using
if recursive_search && !self.exclude_other_filesystems.unwrap_or(false) {
// This is only point which can't be done when recursive search is disabled.
let mut is_inside: bool;
for ed_checked in &self.excluded_directories {

View file

@ -271,6 +271,8 @@ impl DuplicateFinder {
pub fn set_exclude_other_filesystems(&mut self, exclude_other_filesystems: bool) {
self.directories.set_exclude_other_filesystems(exclude_other_filesystems);
}
#[cfg(not(target_family = "unix"))]
pub fn set_exclude_other_filesystems(&mut self, _exclude_other_filesystems: bool) {}
pub fn set_included_directory(&mut self, included_directory: Vec<PathBuf>) {
self.directories.set_included_directory(included_directory, &mut self.text_messages);

View file

@ -100,6 +100,8 @@ impl EmptyFiles {
pub fn set_exclude_other_filesystems(&mut self, exclude_other_filesystems: bool) {
self.directories.set_exclude_other_filesystems(exclude_other_filesystems);
}
#[cfg(not(target_family = "unix"))]
pub fn set_exclude_other_filesystems(&mut self, _exclude_other_filesystems: bool) {}
pub fn set_included_directory(&mut self, included_directory: Vec<PathBuf>) -> bool {
self.directories.set_included_directory(included_directory, &mut self.text_messages)

View file

@ -71,6 +71,8 @@ impl EmptyFolder {
pub fn set_exclude_other_filesystems(&mut self, exclude_other_filesystems: bool) {
self.directories.set_exclude_other_filesystems(exclude_other_filesystems);
}
#[cfg(not(target_family = "unix"))]
pub fn set_exclude_other_filesystems(&mut self, _exclude_other_filesystems: bool) {}
pub fn set_excluded_items(&mut self, excluded_items: Vec<String>) {
self.excluded_items.set_excluded_items(excluded_items, &mut self.text_messages);

View file

@ -99,6 +99,8 @@ impl InvalidSymlinks {
pub fn set_exclude_other_filesystems(&mut self, exclude_other_filesystems: bool) {
self.directories.set_exclude_other_filesystems(exclude_other_filesystems);
}
#[cfg(not(target_family = "unix"))]
pub fn set_exclude_other_filesystems(&mut self, _exclude_other_filesystems: bool) {}
pub fn set_included_directory(&mut self, included_directory: Vec<PathBuf>) -> bool {
self.directories.set_included_directory(included_directory, &mut self.text_messages)

View file

@ -199,6 +199,8 @@ impl SameMusic {
pub fn set_exclude_other_filesystems(&mut self, exclude_other_filesystems: bool) {
self.directories.set_exclude_other_filesystems(exclude_other_filesystems);
}
#[cfg(not(target_family = "unix"))]
pub fn set_exclude_other_filesystems(&mut self, _exclude_other_filesystems: bool) {}
/// Set included dir which needs to be relative, exists etc.
pub fn set_included_directory(&mut self, included_directory: Vec<PathBuf>) {

View file

@ -216,6 +216,8 @@ impl SimilarImages {
pub fn set_exclude_other_filesystems(&mut self, exclude_other_filesystems: bool) {
self.directories.set_exclude_other_filesystems(exclude_other_filesystems);
}
#[cfg(not(target_family = "unix"))]
pub fn set_exclude_other_filesystems(&mut self, _exclude_other_filesystems: bool) {}
pub fn set_allowed_extensions(&mut self, allowed_extensions: String) {
self.allowed_extensions.set_allowed_extensions(allowed_extensions, &mut self.text_messages);
@ -730,7 +732,8 @@ impl SimilarImages {
}
let number_of_processors = num_cpus::get();
let chunks: Vec<_> = all_hashes.chunks(all_hashes.len() / number_of_processors).collect();
let chunk_size = all_hashes.len() / number_of_processors;
let chunks: Vec<_> = if chunk_size > 0 { all_hashes.chunks(chunk_size).collect() } else { vec![&all_hashes] };
let parts: Vec<_> = chunks
.into_par_iter()

View file

@ -170,6 +170,8 @@ impl SimilarVideos {
pub fn set_exclude_other_filesystems(&mut self, exclude_other_filesystems: bool) {
self.directories.set_exclude_other_filesystems(exclude_other_filesystems);
}
#[cfg(not(target_family = "unix"))]
pub fn set_exclude_other_filesystems(&mut self, _exclude_other_filesystems: bool) {}
pub fn set_minimal_file_size(&mut self, minimal_file_size: u64) {
self.minimal_file_size = match minimal_file_size {

View file

@ -113,6 +113,8 @@ impl Temporary {
pub fn set_exclude_other_filesystems(&mut self, exclude_other_filesystems: bool) {
self.directories.set_exclude_other_filesystems(exclude_other_filesystems);
}
#[cfg(not(target_family = "unix"))]
pub fn set_exclude_other_filesystems(&mut self, _exclude_other_filesystems: bool) {}
pub fn set_included_directory(&mut self, included_directory: Vec<PathBuf>) -> bool {
self.directories.set_included_directory(included_directory, &mut self.text_messages)

View file

@ -3,20 +3,21 @@ name = "czkawka_gui"
version = "4.1.0"
authors = ["Rafał Mikrut <mikrutrafal@protonmail.com>"]
edition = "2021"
rust-version = "1.60"
description = "GTK frontend of Czkawka"
license = "MIT"
homepage = "https://github.com/qarmin/czkawka"
repository = "https://github.com/qarmin/czkawka"
[dependencies]
gdk4 = "0.4.7"
glib = "0.15.11"
gdk4 = "0.4.8"
glib = "0.15.12"
humansize = "1.1.1"
chrono = "0.4.19"
# Used for sending stop signal across threads
crossbeam-channel = "0.5.4"
crossbeam-channel = "0.5.5"
# To get informations about progress
futures = "0.3.21"
@ -25,19 +26,19 @@ futures = "0.3.21"
directories-next = "2.0.0"
# For opening files
open = "3.0.1"
open = "3.0.2"
# To get image preview
image = "0.24.2"
image = "0.24.3"
# To be able to use custom select
regex = "1.5.5"
regex = "1.6.0"
# To get image_hasher types
image_hasher = "1.0.0"
# Move files to trash
trash = "2.1.4"
trash = "2.1.5"
# For moving files(why std::fs doesn't have such features)
fs_extra = "1.2.0"
@ -46,14 +47,14 @@ fs_extra = "1.2.0"
i18n-embed = { version = "0.13.4", features = ["fluent-system", "desktop-requester"] }
i18n-embed-fl = "0.6.4"
rust-embed = "6.4.0"
once_cell = "1.10.0"
once_cell = "1.13.0"
[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3.9", features = ["combaseapi", "objbase", "shobjidl_core", "windef", "winerror", "wtypesbase", "winuser"] }
[dependencies.gtk4]
version = "0.4.7"
default-features = false # just in case
version = "0.4.8"
default-features = false
features = ["v4_6"]
[dependencies.czkawka_core]
@ -63,4 +64,4 @@ features = []
[features]
default = []
heif = ["czkawka_core/heif"]
heif = ["czkawka_core/heif"]

View file

@ -268,6 +268,12 @@ header_about_button_tooltip = Opens dialog with info about app.
# Settings
## General
settings_ignore_other_filesystems = Ignore other filesystems(only Linux)
settings_ignore_other_filesystems_tooltip =
ignores files that are not in the same file system as searched directories.
Works same like -xdev option in find command on Linux
settings_save_at_exit_button_tooltip = Save configuration to file when closing app.
settings_load_at_start_button_tooltip =
Load configuration from file when opening app.

View file

@ -11,7 +11,9 @@ use image::DynamicImage;
use crate::flg;
use crate::gui_structs::gui_data::GuiData;
use crate::help_functions::{count_number_of_groups, get_all_children, get_full_name_from_path_name, get_max_file_name, get_pixbuf_from_dynamic_image, resize_pixbuf_dimension};
use crate::help_functions::{
count_number_of_groups, get_all_direct_children, get_full_name_from_path_name, get_max_file_name, get_pixbuf_from_dynamic_image, resize_pixbuf_dimension,
};
use crate::localizer_core::generate_translation_hashmap;
use crate::notebook_info::{NotebookObject, NOTEBOOKS_INFO};
@ -326,7 +328,7 @@ fn populate_groups_at_start(
*shared_image_cache.borrow_mut() = cache_all_images.clone();
let mut found = false;
for i in get_all_children(&scrolled_window_compare_choose_images.child().unwrap().downcast::<gtk4::Viewport>().unwrap()) {
for i in get_all_direct_children(&scrolled_window_compare_choose_images.child().unwrap().downcast::<gtk4::Viewport>().unwrap()) {
if i.widget_name() == "all_box" {
let gtk_box = i.downcast::<gtk4::Box>().unwrap();
update_bottom_buttons(&gtk_box, shared_using_for_preview, shared_image_cache);
@ -618,13 +620,13 @@ fn update_bottom_buttons(
let left_tree_view = (*shared_using_for_preview.borrow()).0.clone().unwrap();
let right_tree_view = (*shared_using_for_preview.borrow()).1.clone().unwrap();
for (number, i) in get_all_children(all_gtk_box).into_iter().enumerate() {
for (number, i) in get_all_direct_children(all_gtk_box).into_iter().enumerate() {
let cache_tree_path = (*image_cache.borrow())[number].4.clone();
let is_chosen = cache_tree_path != right_tree_view && cache_tree_path != left_tree_view;
let bx = i.downcast::<gtk4::Box>().unwrap();
let smaller_bx = get_all_children(&bx)[0].clone().downcast::<gtk4::Box>().unwrap();
for items in get_all_children(&smaller_bx) {
let smaller_bx = get_all_direct_children(&bx)[0].clone().downcast::<gtk4::Box>().unwrap();
for items in get_all_direct_children(&smaller_bx) {
if let Ok(btn) = items.downcast::<gtk4::Button>() {
btn.set_sensitive(is_chosen);
}

View file

@ -45,6 +45,7 @@ pub fn connect_button_search(
futures_sender_broken_files: futures::channel::mpsc::UnboundedSender<broken_files::ProgressData>,
futures_sender_bad_extensions: futures::channel::mpsc::UnboundedSender<common_dir_traversal::ProgressData>,
) {
let check_button_settings_one_filesystem = gui_data.settings.check_button_settings_one_filesystem.clone();
let combo_box_image_hash_size = gui_data.main_notebook.combo_box_image_hash_size.clone();
let combo_box_image_hash_algorithm = gui_data.main_notebook.combo_box_image_hash_algorithm.clone();
let combo_box_image_resize_algorithm = gui_data.main_notebook.combo_box_image_resize_algorithm.clone();
@ -147,6 +148,7 @@ pub fn connect_button_search(
.unwrap_or_else(|_| DEFAULT_MAXIMAL_FILE_SIZE.parse::<u64>().unwrap());
let show_dialog = Arc::new(AtomicBool::new(true));
let ignore_other_filesystems = check_button_settings_one_filesystem.is_active();
window_progress.set_title(Some(&flg!("window_progress_title")));
@ -214,6 +216,7 @@ pub fn connect_button_search(
df.set_use_prehash_cache(use_prehash_cache);
df.set_delete_outdated_cache(delete_outdated_cache);
df.set_case_sensitive_name_comparison(case_sensitive_name_comparison);
df.set_exclude_other_filesystems(ignore_other_filesystems);
df.find_duplicates(Some(&stop_receiver), Some(&futures_sender_duplicate_files));
let _ = glib_stop_sender.send(Message::Duplicates(df));
});
@ -235,6 +238,7 @@ pub fn connect_button_search(
vf.set_recursive_search(recursive_search);
vf.set_excluded_items(excluded_items);
vf.set_allowed_extensions(allowed_extensions);
vf.set_exclude_other_filesystems(ignore_other_filesystems);
vf.find_empty_files(Some(&stop_receiver), Some(&futures_sender_empty_files));
let _ = glib_stop_sender.send(Message::EmptyFiles(vf));
});
@ -253,6 +257,7 @@ pub fn connect_button_search(
ef.set_included_directory(included_directories);
ef.set_excluded_directory(excluded_directories);
ef.set_excluded_items(excluded_items);
ef.set_exclude_other_filesystems(ignore_other_filesystems);
ef.find_empty_folders(Some(&stop_receiver), Some(&futures_sender_empty_folder));
let _ = glib_stop_sender.send(Message::EmptyFolders(ef));
});
@ -281,6 +286,7 @@ pub fn connect_button_search(
bf.set_allowed_extensions(allowed_extensions);
bf.set_number_of_files_to_check(numbers_of_files_to_check);
bf.set_search_mode(big_files_mode);
bf.set_exclude_other_filesystems(ignore_other_filesystems);
bf.find_big_files(Some(&stop_receiver), Some(&futures_sender_big_file));
let _ = glib_stop_sender.send(Message::BigFiles(bf));
});
@ -301,6 +307,7 @@ pub fn connect_button_search(
tf.set_excluded_directory(excluded_directories);
tf.set_recursive_search(recursive_search);
tf.set_excluded_items(excluded_items);
tf.set_exclude_other_filesystems(ignore_other_filesystems);
tf.find_temporary_files(Some(&stop_receiver), Some(&futures_sender_temporary));
let _ = glib_stop_sender.send(Message::Temporary(tf));
});
@ -350,6 +357,7 @@ pub fn connect_button_search(
sf.set_delete_outdated_cache(delete_outdated_cache);
sf.set_exclude_images_with_same_size(ignore_same_size);
sf.set_save_also_as_json(save_also_as_json);
sf.set_exclude_other_filesystems(ignore_other_filesystems);
sf.find_similar_images(Some(&stop_receiver), Some(&futures_sender_similar_images));
let _ = glib_stop_sender.send(Message::SimilarImages(sf));
});
@ -385,6 +393,7 @@ pub fn connect_button_search(
sf.set_delete_outdated_cache(delete_outdated_cache);
sf.set_exclude_videos_with_same_size(ignore_same_size);
sf.set_save_also_as_json(save_also_as_json);
sf.set_exclude_other_filesystems(ignore_other_filesystems);
sf.find_similar_videos(Some(&stop_receiver), Some(&futures_sender_similar_videos));
let _ = glib_stop_sender.send(Message::SimilarVideos(sf));
});
@ -436,6 +445,7 @@ pub fn connect_button_search(
mf.set_music_similarity(music_similarity);
mf.set_approximate_comparison(approximate_comparison);
mf.set_save_also_as_json(save_also_as_json);
mf.set_exclude_other_filesystems(ignore_other_filesystems);
mf.find_same_music(Some(&stop_receiver), Some(&futures_sender_same_music));
let _ = glib_stop_sender.send(Message::SameMusic(mf));
});
@ -471,6 +481,7 @@ pub fn connect_button_search(
isf.set_recursive_search(recursive_search);
isf.set_excluded_items(excluded_items);
isf.set_allowed_extensions(allowed_extensions);
isf.set_exclude_other_filesystems(ignore_other_filesystems);
isf.find_invalid_links(Some(&stop_receiver), Some(&futures_sender_invalid_symlinks));
let _ = glib_stop_sender.send(Message::InvalidSymlinks(isf));
});
@ -511,6 +522,7 @@ pub fn connect_button_search(
br.set_allowed_extensions(allowed_extensions);
br.set_save_also_as_json(save_also_as_json);
br.set_checked_types(checked_types);
br.set_exclude_other_filesystems(ignore_other_filesystems);
br.find_broken_files(Some(&stop_receiver), Some(&futures_sender_broken_files));
let _ = glib_stop_sender.send(Message::BrokenFiles(br));
});
@ -548,6 +560,7 @@ pub fn connect_button_search(
be.set_maximal_file_size(maximal_file_size);
be.set_allowed_extensions(allowed_extensions);
be.set_recursive_search(recursive_search);
be.set_exclude_other_filesystems(ignore_other_filesystems);
be.find_bad_extensions_files(Some(&stop_receiver), Some(&futures_sender_bad_extensions));
let _ = glib_stop_sender.send(Message::BadExtensions(be));
});

View file

@ -8,7 +8,7 @@ use czkawka_core::similar_images::{get_string_from_similarity, SIMILAR_VALUES};
use crate::flg;
use crate::help_combo_box::{BIG_FILES_CHECK_METHOD_COMBO_BOX, DUPLICATES_CHECK_METHOD_COMBO_BOX, IMAGES_HASH_SIZE_COMBO_BOX};
use crate::help_functions::get_all_children;
use crate::help_functions::get_all_direct_children;
use crate::notebook_enums::{NotebookMainEnum, NUMBER_OF_NOTEBOOK_MAIN_TABS};
#[derive(Clone)]
@ -430,8 +430,8 @@ impl GuiMainNotebook {
}
}
let vec_children: Vec<Widget> = get_all_children(&self.notebook_main);
let vec_children: Vec<Widget> = get_all_children(&vec_children[1]);
let vec_children: Vec<Widget> = get_all_direct_children(&self.notebook_main);
let vec_children: Vec<Widget> = get_all_direct_children(&vec_children[1]);
// Change name of main notebook tabs
for (main_enum, fl_thing) in [

View file

@ -2,7 +2,7 @@ use gtk4::prelude::*;
use gtk4::{Builder, Window};
use crate::flg;
use crate::help_functions::get_all_children;
use crate::help_functions::get_all_direct_children;
#[derive(Clone)]
pub struct GuiSettings {
@ -22,6 +22,7 @@ pub struct GuiSettings {
pub check_button_settings_use_trash: gtk4::CheckButton,
pub label_settings_general_language: gtk4::Label,
pub combo_box_settings_language: gtk4::ComboBoxText,
pub check_button_settings_one_filesystem: gtk4::CheckButton,
// Duplicates
pub check_button_settings_hide_hard_links: gtk4::CheckButton,
@ -65,6 +66,7 @@ impl GuiSettings {
let notebook_settings: gtk4::Notebook = builder.object("notebook_settings").unwrap();
// General
let check_button_settings_one_filesystem: gtk4::CheckButton = builder.object("check_button_settings_one_filesystem").unwrap();
let check_button_settings_save_at_exit: gtk4::CheckButton = builder.object("check_button_settings_save_at_exit").unwrap();
let check_button_settings_load_at_start: gtk4::CheckButton = builder.object("check_button_settings_load_at_start").unwrap();
let check_button_settings_confirm_deletion: gtk4::CheckButton = builder.object("check_button_settings_confirm_deletion").unwrap();
@ -119,6 +121,7 @@ impl GuiSettings {
check_button_settings_use_trash,
label_settings_general_language,
combo_box_settings_language,
check_button_settings_one_filesystem,
check_button_settings_hide_hard_links,
entry_settings_cache_file_minimal_size,
entry_settings_prehash_cache_file_minimal_size,
@ -155,6 +158,7 @@ impl GuiSettings {
self.check_button_settings_save_also_json.set_label(Some(&flg!("settings_save_also_as_json_button")));
self.check_button_settings_use_trash.set_label(Some(&flg!("settings_use_trash_button")));
self.label_settings_general_language.set_label(&flg!("settings_language_label"));
self.check_button_settings_one_filesystem.set_label(Some(&flg!("settings_ignore_other_filesystems")));
self.check_button_settings_save_at_exit
.set_tooltip_text(Some(&flg!("settings_save_at_exit_button_tooltip")));
@ -173,6 +177,8 @@ impl GuiSettings {
self.check_button_settings_use_cache.set_tooltip_text(Some(&flg!("settings_use_cache_button_tooltip")));
self.check_button_settings_use_trash.set_tooltip_text(Some(&flg!("settings_use_trash_button_tooltip")));
self.label_settings_general_language.set_tooltip_text(Some(&flg!("settings_language_label_tooltip")));
self.check_button_settings_one_filesystem
.set_tooltip_text(Some(&flg!("settings_ignore_other_filesystems_tooltip")));
self.check_button_settings_hide_hard_links
.set_label(Some(&flg!("settings_duplicates_hide_hard_link_button")));
@ -240,8 +246,8 @@ impl GuiSettings {
self.button_settings_open_settings_folder
.set_tooltip_text(Some(&flg!("settings_folder_settings_open_tooltip")));
let vec_children: Vec<gtk4::Widget> = get_all_children(&self.notebook_settings);
let vec_children: Vec<gtk4::Widget> = get_all_children(&vec_children[1]);
let vec_children: Vec<gtk4::Widget> = get_all_direct_children(&self.notebook_settings);
let vec_children: Vec<gtk4::Widget> = get_all_direct_children(&vec_children[1]);
// Change name of main notebook tabs
let names: [String; 4] = [

View file

@ -1,7 +1,7 @@
use gtk4::prelude::*;
use gtk4::{EventControllerKey, GestureClick, TreeView};
use crate::help_functions::{get_all_children, get_custom_label_from_widget, set_icon_of_button};
use crate::help_functions::{get_all_direct_children, get_custom_label_from_widget, set_icon_of_button};
use crate::notebook_enums::NotebookUpperEnum;
use crate::{flg, CZK_ICON_ADD, CZK_ICON_DELETE, CZK_ICON_MANUAL_ADD};
@ -157,8 +157,8 @@ impl GuiUpperNotebook {
self.entry_general_minimal_size.set_tooltip_text(Some(&flg!("main_label_size_bytes_tooltip")));
self.entry_general_maximal_size.set_tooltip_text(Some(&flg!("main_label_size_bytes_tooltip")));
let vec_children: Vec<gtk4::Widget> = get_all_children(&self.notebook_upper);
let vec_children: Vec<gtk4::Widget> = get_all_children(&vec_children[1]);
let vec_children: Vec<gtk4::Widget> = get_all_direct_children(&self.notebook_upper);
let vec_children: Vec<gtk4::Widget> = get_all_direct_children(&vec_children[1]);
// Change name of upper notebook tabs
for (upper_enum, fl_thing) in [

View file

@ -608,14 +608,23 @@ pub fn resize_pixbuf_dimension(pixbuf: Pixbuf, requested_size: (i32, i32), inter
pub fn get_max_file_name(file_name: &str, max_length: usize) -> String {
assert!(max_length > 10); // Maybe in future will be supported lower values
if file_name.len() > max_length {
let difference = file_name.len() - max_length;
let characters_in_filename = file_name.chars().count();
if characters_in_filename > max_length {
let start_characters = 10;
let difference = characters_in_filename - max_length;
let second_part_start = start_characters + difference;
let mut string_pre = "".to_string();
let mut string_after = "".to_string();
let mut string = "".to_string();
string += &file_name[0..10];
string += " ... ";
string += &file_name[10 + difference..];
string
for (index, character) in file_name.chars().enumerate() {
if index < start_characters {
string_pre.push(character);
} else if index >= second_part_start {
string_after.push(character);
}
}
format!("{string_pre} ... {string_after}")
} else {
file_name.to_string()
}
@ -628,7 +637,7 @@ pub fn get_custom_label_from_widget<P: IsA<Widget>>(item: &P) -> gtk4::Label {
if let Ok(label) = widget.clone().downcast::<gtk4::Label>() {
return label;
} else {
widgets_to_check.extend(get_all_children(&widget));
widgets_to_check.extend(get_all_direct_children(&widget));
}
}
panic!("Button doesn't have proper custom label child");
@ -641,7 +650,7 @@ pub fn get_custom_image_from_widget<P: IsA<Widget>>(item: &P) -> gtk4::Image {
if let Ok(image) = widget.clone().downcast::<gtk4::Image>() {
return image;
} else {
widgets_to_check.extend(get_all_children(&widget));
widgets_to_check.extend(get_all_direct_children(&widget));
}
}
panic!("Button doesn't have proper custom label child");
@ -655,7 +664,7 @@ pub fn debug_print_widget<P: IsA<Widget>>(item: &P) {
println!("{}, {}, {:?} ", widgets_to_check[0].0, widgets_to_check[0].1, widgets_to_check[0].2);
while let Some((current_number, parent_number, widget)) = widgets_to_check.pop() {
for widget in get_all_children(&widget) {
for widget in get_all_direct_children(&widget) {
widgets_to_check.push((next_free_number, current_number, widget));
next_free_number += 1;
}
@ -668,7 +677,7 @@ pub fn get_all_boxes_from_widget<P: IsA<Widget>>(item: &P) -> Vec<gtk4::Box> {
let mut boxes = Vec::new();
while let Some(widget) = widgets_to_check.pop() {
widgets_to_check.extend(get_all_children(&widget));
widgets_to_check.extend(get_all_direct_children(&widget));
if let Ok(bbox) = widget.clone().downcast::<gtk4::Box>() {
boxes.push(bbox);
}
@ -676,7 +685,7 @@ pub fn get_all_boxes_from_widget<P: IsA<Widget>>(item: &P) -> Vec<gtk4::Box> {
boxes
}
pub fn get_all_children<P: IsA<Widget>>(wid: &P) -> Vec<Widget> {
pub fn get_all_direct_children<P: IsA<Widget>>(wid: &P) -> Vec<Widget> {
let mut vector = vec![];
if let Some(mut child) = wid.first_child() {
vector.push(child.clone());
@ -714,3 +723,66 @@ pub fn get_pixbuf_from_dynamic_image(dynamic_image: &DynamicImage) -> Result<Pix
}
Pixbuf::from_read(arra)
}
#[test]
fn test_file_name_shortener() {
let name_to_check = "/home/rafal/czkawek/romek/atomek.txt";
assert_eq!(get_max_file_name(name_to_check, 20), "/home/rafa ... atomek.txt");
assert_eq!(get_max_file_name(name_to_check, 21), "/home/rafa ... /atomek.txt");
let name_to_check = "/home/rafal/czkawek/romek/czekistan/atomek.txt";
assert_eq!(get_max_file_name(name_to_check, 21), "/home/rafa ... /atomek.txt");
assert_eq!(get_max_file_name(name_to_check, 80), name_to_check);
let name_to_check = "/home/rafal/‍🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈.txt";
assert_eq!(get_max_file_name(name_to_check, 21), "/home/rafa ... 🌈🌈🌈🌈🌈🌈🌈.txt");
assert_eq!(get_max_file_name(name_to_check, 20), "/home/rafa ... 🌈🌈🌈🌈🌈🌈.txt");
assert_eq!(get_max_file_name(name_to_check, 19), "/home/rafa ... 🌈🌈🌈🌈🌈.txt");
let name_to_check = "/home/rafal/‍🏳️‍🌈️🏳️‍🌈️🏳️‍🌈️🏳️‍🌈️🏳️‍🌈️🏳️‍🌈️🏳️‍🌈️🏳️‍🌈️🏳️‍🌈️.txt";
assert_eq!(get_max_file_name(name_to_check, 21), "/home/rafa ... 🌈\u{fe0f}🏳\u{fe0f}\u{200d}🌈\u{fe0f}.txt");
assert_eq!(get_max_file_name(name_to_check, 20), "/home/rafa ... \u{fe0f}🏳\u{fe0f}\u{200d}🌈\u{fe0f}.txt");
assert_eq!(get_max_file_name(name_to_check, 19), "/home/rafa ... 🏳\u{fe0f}\u{200d}🌈\u{fe0f}.txt");
}
#[cfg(test)]
mod test {
use crate::help_functions::{get_all_boxes_from_widget, get_all_direct_children, get_pixbuf_from_dynamic_image};
use gtk4::prelude::*;
use gtk4::Orientation;
use image::DynamicImage;
#[test]
fn test_pixbuf_from_dynamic_image() {
let dynamic_image = DynamicImage::new_rgb8(1, 1);
get_pixbuf_from_dynamic_image(&dynamic_image).unwrap();
get_pixbuf_from_dynamic_image(&dynamic_image).unwrap();
get_pixbuf_from_dynamic_image(&dynamic_image).unwrap();
get_pixbuf_from_dynamic_image(&dynamic_image).unwrap();
}
#[gtk4::test]
fn test_get_all_direct_children() {
let obj = gtk4::Box::new(Orientation::Horizontal, 0);
let obj2 = gtk4::Box::new(Orientation::Horizontal, 0);
let obj3 = gtk4::Image::new();
let obj4 = gtk4::Image::new();
let obj5 = gtk4::Image::new();
obj.append(&obj2);
obj.append(&obj3);
obj2.append(&obj4);
obj2.append(&obj5);
assert_eq!(get_all_direct_children(&obj).len(), 2);
}
#[gtk4::test]
fn test_get_all_boxes_from_widget() {
let obj = gtk4::Box::new(Orientation::Horizontal, 0);
let obj2 = gtk4::Box::new(Orientation::Horizontal, 0);
let obj3 = gtk4::Image::new();
let obj4 = gtk4::Image::new();
let obj5 = gtk4::Image::new();
obj.append(&obj2);
obj.append(&obj3);
obj2.append(&obj4);
obj2.append(&obj5);
assert_eq!(get_all_boxes_from_widget(&obj).len(), 2);
}
}

View file

@ -41,6 +41,7 @@ const DEFAULT_VIDEO_REMOVE_AUTO_OUTDATED_CACHE: bool = false;
const DEFAULT_IMAGE_REMOVE_AUTO_OUTDATED_CACHE: bool = true;
const DEFAULT_DUPLICATE_REMOVE_AUTO_OUTDATED_CACHE: bool = true;
const DEFAULT_DUPLICATE_CASE_SENSITIVE_NAME_CHECKING: bool = false;
const DEFAULT_GENERAL_IGNORE_OTHER_FILESYSTEMS: bool = false;
const DEFAULT_BROKEN_FILES_PDF: bool = true;
const DEFAULT_BROKEN_FILES_AUDIO: bool = true;
@ -417,6 +418,7 @@ enum LoadText {
VideoDeleteOutdatedCacheEntries,
UsePrehashCache,
MinimalPrehashCacheSize,
GeneralIgnoreOtherFilesystems,
Language,
ComboBoxDuplicateHashType,
ComboBoxDuplicateCheckMethod,
@ -480,6 +482,7 @@ fn create_hash_map() -> (HashMap<LoadText, String>, HashMap<String, LoadText>) {
(LoadText::BrokenFilesAudio, "broken_files_audio"),
(LoadText::BrokenFilesImage, "broken_files_image"),
(LoadText::BrokenFilesArchive, "broken_files_archive"),
(LoadText::GeneralIgnoreOtherFilesystems, "ignore_other_filesystems"),
];
let mut hashmap_ls: HashMap<LoadText, String> = Default::default();
let mut hashmap_sl: HashMap<String, LoadText> = Default::default();
@ -593,6 +596,10 @@ pub fn save_configuration(manual_execution: bool, upper_notebook: &GuiUpperNoteb
hashmap_ls.get(&LoadText::ShowBottomTextPanel).unwrap().to_string(),
settings.check_button_settings_show_text_view.is_active(),
);
saving_struct.save_var(
hashmap_ls.get(&LoadText::GeneralIgnoreOtherFilesystems).unwrap().to_string(),
settings.check_button_settings_one_filesystem.is_active(),
);
saving_struct.save_var(
hashmap_ls.get(&LoadText::BrokenFilesArchive).unwrap().to_string(),
@ -732,6 +739,10 @@ pub fn load_configuration(
let use_cache: bool = loaded_entries.get_bool(hashmap_ls.get(&LoadText::UseCache).unwrap().clone(), DEFAULT_USE_CACHE);
let use_json_cache: bool = loaded_entries.get_bool(hashmap_ls.get(&LoadText::UseJsonCacheFile).unwrap().clone(), DEFAULT_SAVE_ALSO_AS_JSON);
let use_trash: bool = loaded_entries.get_bool(hashmap_ls.get(&LoadText::DeleteToTrash).unwrap().clone(), DEFAULT_USE_TRASH);
let ignore_other_fs: bool = loaded_entries.get_bool(
hashmap_ls.get(&LoadText::GeneralIgnoreOtherFilesystems).unwrap().clone(),
DEFAULT_GENERAL_IGNORE_OTHER_FILESYSTEMS,
);
let delete_outdated_cache_duplicates: bool = loaded_entries.get_bool(
hashmap_ls.get(&LoadText::DuplicateDeleteOutdatedCacheEntries).unwrap().clone(),
DEFAULT_DUPLICATE_REMOVE_AUTO_OUTDATED_CACHE,
@ -893,6 +904,7 @@ pub fn load_configuration(
settings.check_button_settings_use_trash.set_active(use_trash);
settings.entry_settings_cache_file_minimal_size.set_text(&cache_minimal_size);
settings.entry_settings_prehash_cache_file_minimal_size.set_text(&cache_prehash_minimal_size);
settings.check_button_settings_one_filesystem.set_active(ignore_other_fs);
save_proper_value_to_combo_box(&main_notebook.combo_box_duplicate_hash_type, combo_box_duplicate_hash_type);
save_proper_value_to_combo_box(&main_notebook.combo_box_duplicate_check_method, combo_box_duplicate_checking_method);
@ -1028,6 +1040,7 @@ pub fn reset_configuration(manual_clearing: bool, upper_notebook: &GuiUpperNoteb
settings.check_button_duplicates_use_prehash_cache.set_active(DEFAULT_USE_PRECACHE);
settings.entry_settings_prehash_cache_file_minimal_size.set_text(DEFAULT_PREHASH_MINIMAL_CACHE_SIZE);
settings.combo_box_settings_language.set_active(Some(0));
settings.check_button_settings_one_filesystem.set_active(DEFAULT_GENERAL_IGNORE_OTHER_FILESYSTEMS);
main_notebook.combo_box_duplicate_hash_type.set_active(Some(0));
main_notebook.combo_box_duplicate_check_method.set_active(Some(0));

View file

@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.10.2 -->
<!-- Created with Cambalache 0.11.0 -->
<interface>
<!-- interface-name about_dialog.ui -->
<requires lib="gtk" version="4.0"/>

View file

@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.10.2 -->
<!-- Created with Cambalache 0.11.0 -->
<interface>
<!-- interface-name compare_images.ui -->
<requires lib="gtk" version="4.0"/>

View file

@ -1,6 +1,6 @@
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<!DOCTYPE cambalache-project SYSTEM "cambalache-project.dtd">
<cambalache-project version="0.10.2" target_tk="gtk-4.0">
<cambalache-project version="0.11.0" target_tk="gtk-4.0">
<ui>
(3,None,"about_dialog.ui","about_dialog.ui",None,None,None,None,None,None),
(4,None,"compare_images.ui","compare_images.ui",None,None,None,None,None,None),
@ -313,7 +313,8 @@
(9,51,"GtkBox",None,3,None,None,None,2),
(9,52,"GtkButton","button_settings_load_configuration",51,None,None,None,None),
(9,53,"GtkButton","button_settings_reset_configuration",51,None,None,None,1),
(9,54,"GtkButton","button_settings_save_configuration",51,None,None,None,2)
(9,54,"GtkButton","button_settings_save_configuration",51,None,None,None,2),
(9,55,"GtkCheckButton","check_button_settings_one_filesystem",9,None,None,None,10)
</object>
<object_property>
(3,1,"GtkAboutDialog","comments","2020 - 2022 Rafał Mikrut(qarmin)\n\nThis program is free to use and will always be.\n",1,None,None,None,None),
@ -947,7 +948,10 @@
(9,54,"GtkButton","label","Save configuration",1,None,None,None,None),
(9,54,"GtkWidget","focusable","1",None,None,None,None,None),
(9,54,"GtkWidget","halign","center",None,None,None,None,None),
(9,54,"GtkWidget","receives-default","1",None,None,None,None,None)
(9,54,"GtkWidget","receives-default","1",None,None,None,None,None),
(9,55,"GtkCheckButton","active","1",None,None,None,None,None),
(9,55,"GtkCheckButton","label","Exclude other filesystems(Linux)",None,None,None,None,None),
(9,55,"GtkWidget","focusable","1",None,None,None,None,None)
</object_property>
<object_layout_property>
(8,17,18,"GtkGridLayoutChild","column","0",None,None,None,None),

View file

@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.10.2 -->
<!-- Created with Cambalache 0.11.0 -->
<interface>
<!-- interface-name main_window.ui -->
<requires lib="gtk" version="4.0"/>

View file

@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.10.2 -->
<!-- Created with Cambalache 0.11.0 -->
<interface>
<!-- interface-name popover_right_click.ui -->
<requires lib="gtk" version="4.0"/>

View file

@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.10.2 -->
<!-- Created with Cambalache 0.11.0 -->
<interface>
<!-- interface-name popover_select.ui -->
<requires lib="gtk" version="4.0"/>

View file

@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.10.2 -->
<!-- Created with Cambalache 0.11.0 -->
<interface>
<!-- interface-name progress.ui -->
<requires lib="gtk" version="4.0"/>

View file

@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.10.2 -->
<!-- Created with Cambalache 0.11.0 -->
<interface>
<!-- interface-name settings.ui -->
<requires lib="gtk" version="4.0"/>
@ -107,6 +107,13 @@
<property name="label" translatable="yes">Move deleted files to trash</property>
</object>
</child>
<child>
<object class="GtkCheckButton" id="check_button_settings_one_filesystem">
<property name="active">1</property>
<property name="focusable">1</property>
<property name="label">Exclude other filesystems(Linux)</property>
</object>
</child>
</object>
</child>
<child>