diff --git a/Cargo.lock b/Cargo.lock index 895b984..24526b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -47,9 +47,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.40" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b" +checksum = "595d3cfa7a60d4555cb5067b99f07142a08ea778de5cf993f7b75c7d8fabc486" [[package]] name = "arrayref" @@ -177,15 +177,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.6.1" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe" +checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" [[package]] name = "bytemuck" -version = "1.5.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bed57e2090563b83ba8f83366628ce535a7584c9afa4c9fc0612a03925c6df58" +checksum = "9966d2ab714d0f785dbac0a0396251a35280aeb42413281617d0209ab4898435" [[package]] name = "byteorder" @@ -222,9 +222,9 @@ dependencies = [ [[package]] name = "cairo-rs" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d32eecb1e806433cf68063c4548bbdc15cc56d35db19d685ab60909c4c85206" +checksum = "a408c13bbc04c3337b94194c1a4d04067097439b79dbc1dcbceba299d828b9ea" dependencies = [ "bitflags", "cairo-sys-rs", @@ -246,9 +246,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.67" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" +checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" dependencies = [ "jobserver", ] @@ -342,9 +342,9 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "combine" -version = "4.5.2" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc4369b5e4c0cddf64ad8981c0111e7df4f7078f4d6ba98fb31f2e17c4c57b7e" +checksum = "a2d47c1b11006b87e492b53b313bb699ce60e16613c4dddaa91f8f7c220ab2fa" dependencies = [ "bytes", "memchr", @@ -438,9 +438,9 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52fb27eab85b17fbb9f6fd667089e07d6a2eb8743d02639ee7f6a7a7729c9c94" +checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" dependencies = [ "cfg-if 1.0.0", "crossbeam-utils", @@ -451,11 +451,10 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4feb231f0d4d6af81aed15928e58ecf5816aa62a2393e2c82f46973e92a9a278" +checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" dependencies = [ - "autocfg", "cfg-if 1.0.0", "lazy_static", ] @@ -804,9 +803,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ "cfg-if 1.0.0", "libc", @@ -855,9 +854,9 @@ dependencies = [ [[package]] name = "glib" -version = "0.14.0" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0028bbfd270d0778540294abca11141d59cb474da4c1f61ca1e11f579c49247" +checksum = "dbecad7a3a898ee749d491ce2ae0decb0bce9e736f9747bc49159b1cea5d37f4" dependencies = [ "bitflags", "futures-channel", @@ -874,9 +873,9 @@ dependencies = [ [[package]] name = "glib-macros" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eb7bdf41972a6f6dab5d72c23d22789f400059a43ba0d72b4bb2f8664d946a9" +checksum = "2aad66361f66796bfc73f530c51ef123970eb895ffba991a234fcf7bea89e518" dependencies = [ "anyhow", "heck", @@ -978,18 +977,18 @@ checksum = "65043da274378d68241eb9a8f8f8aa54e349136f7b8e12f63e3ef44043cc30e1" [[package]] name = "heck" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" dependencies = [ "unicode-segmentation", ] [[package]] name = "hermit-abi" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", ] @@ -1063,9 +1062,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" +checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" dependencies = [ "cfg-if 1.0.0", ] @@ -1119,9 +1118,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.50" +version = "0.3.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d99f9e3e84b8f67f846ef5b4cbbc3b1c29f6c759fcbce6f01aa0e73d932a24c" +checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062" dependencies = [ "wasm-bindgen", ] @@ -1151,9 +1150,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.94" +version = "0.2.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e" +checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" [[package]] name = "libloading" @@ -1200,9 +1199,9 @@ checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" [[package]] name = "memoffset" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83fb6581e8ed1f85fd45c116db8405483899489e38406156c25eb743554361d" +checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" dependencies = [ "autocfg", ] @@ -1414,9 +1413,9 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "226b45a5c2ac4dd696ed30fa6b94b057ad909c7b7fc2e0d0808192bced894066" +checksum = "e5adf0198d427ee515335639f275e806ca01acf9f07d7cf14bb36a10532a6169" dependencies = [ "derivative", "num_enum_derive", @@ -1424,11 +1423,11 @@ dependencies = [ [[package]] name = "num_enum_derive" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c0fd9eba1d5db0994a239e09c1be402d35622277e35468ba891aa5e3188ce7e" +checksum = "b1def5a3f69d4707d8a040b12785b98029a39e8c610ae685c7f6265669767482" dependencies = [ - "proc-macro-crate 0.1.5", + "proc-macro-crate 1.0.0", "proc-macro2", "quote", "syn", @@ -1436,9 +1435,9 @@ dependencies = [ [[package]] name = "oboe" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cfb2390bddb9546c0f7448fd1d2abdd39e6075206f960991eb28c7fa7f126c4" +checksum = "dfa187b38ae20374617b7ad418034ed3dc90ac980181d211518bd03537ae8f8d" dependencies = [ "jni", "ndk", @@ -1450,9 +1449,9 @@ dependencies = [ [[package]] name = "oboe-sys" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe069264d082fc820dfa172f79be3f2e088ecfece9b1c47b0c9fd838d2bef103" +checksum = "b88e64835aa3f579c08d182526dc34e3907343d5b97e87b71a40ba5bca7aca9e" dependencies = [ "cc", ] @@ -1468,9 +1467,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.7.2" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" +checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" [[package]] name = "open" @@ -1549,9 +1548,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905" +checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" [[package]] name = "pin-utils" @@ -1640,9 +1639,9 @@ checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" [[package]] name = "proc-macro2" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" +checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" dependencies = [ "unicode-xid", ] @@ -1658,9 +1657,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" dependencies = [ "libc", "rand_chacha", @@ -1670,9 +1669,9 @@ dependencies = [ [[package]] name = "rand_chacha" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", "rand_core", @@ -1680,18 +1679,18 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ "getrandom", ] [[package]] name = "rand_hc" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" dependencies = [ "rand_core", ] @@ -1723,9 +1722,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "742739e41cd49414de871ea5e549afb7e2a3ac77b589bcbebe8c82fab37147fc" +checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee" dependencies = [ "bitflags", ] @@ -1742,9 +1741,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.5.3" +version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce5f1ceb7f74abbce32601642fcf8e8508a8a8991e0621c7d750295b9095702b" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" dependencies = [ "regex-syntax", ] @@ -1855,18 +1854,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.125" +version = "1.0.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" +checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.125" +version = "1.0.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" +checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43" dependencies = [ "proc-macro2", "quote", @@ -1928,9 +1927,9 @@ checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" [[package]] name = "structopt" -version = "0.3.21" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5277acd7ee46e63e5168a80734c9f6ee81b1367a7d8772a2d765df2a3705d28c" +checksum = "69b041cdcb67226aca307e6e7be44c8806423d83e018bd662360a93dabce4d71" dependencies = [ "clap", "lazy_static", @@ -1939,9 +1938,9 @@ dependencies = [ [[package]] name = "structopt-derive" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ba9cdfda491b814720b6b06e0cac513d922fc407582032e8706e9f137976f90" +checksum = "7813934aecf5f51a54775e00068c237de98489463968231a51746bbbc03f9c10" dependencies = [ "heck", "proc-macro-error", @@ -1952,15 +1951,15 @@ dependencies = [ [[package]] name = "strum" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7318c509b5ba57f18533982607f24070a55d353e90d4cae30c467cdb2ad5ac5c" +checksum = "aaf86bbcfd1fa9670b7a129f64fc0c9fcbbfe4f1bc4210e9e98fe71ffc12cde2" [[package]] name = "strum_macros" -version = "0.20.1" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee8bc6b87a5112aeeab1f4a9f7ab634fe6cbefc4850006df31267f4cfb9e3149" +checksum = "d06aaeeee809dbc59eb4556183dd927df67db1540de5be8d3ec0b6636358a5ec" dependencies = [ "heck", "proc-macro2", @@ -1970,15 +1969,15 @@ dependencies = [ [[package]] name = "subtle" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.72" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82" +checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7" dependencies = [ "proc-macro2", "quote", @@ -1987,9 +1986,9 @@ dependencies = [ [[package]] name = "system-deps" -version = "3.1.1" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c248107ad7bc1ac07066a4d003cae9e9a7bc2e27d3418f7a9cdcdc8699dbea70" +checksum = "7ab7dbd121ce66af2176147a48c7e01aaf1f001837a18a7cf4317858606bbdf8" dependencies = [ "anyhow", "cfg-expr", @@ -2028,18 +2027,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.24" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e" +checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.24" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" +checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" dependencies = [ "proc-macro2", "quote", @@ -2059,11 +2058,12 @@ dependencies = [ [[package]] name = "time" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" dependencies = [ "libc", + "wasi", "winapi", ] @@ -2130,9 +2130,9 @@ checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" [[package]] name = "unicode-segmentation" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" +checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" [[package]] name = "unicode-width" @@ -2177,15 +2177,15 @@ dependencies = [ [[package]] name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" +version = "0.10.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" [[package]] name = "wasm-bindgen" -version = "0.2.73" +version = "0.2.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83240549659d187488f91f33c0f8547cbfef0b2088bc470c116d1d260ef623d9" +checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-macro", @@ -2193,9 +2193,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.73" +version = "0.2.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae70622411ca953215ca6d06d3ebeb1e915f0f6613e3b495122878d7ebec7dae" +checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900" dependencies = [ "bumpalo", "lazy_static", @@ -2208,9 +2208,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.73" +version = "0.2.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e734d91443f177bfdb41969de821e15c516931c3c3db3d318fa1b68975d0f6f" +checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2218,9 +2218,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.73" +version = "0.2.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53739ff08c8a68b0fdbcd54c372b8ab800b1449ab3c9d706503bc7dd1621b2c" +checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97" dependencies = [ "proc-macro2", "quote", @@ -2231,15 +2231,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.73" +version = "0.2.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9a543ae66aa233d14bb765ed9af4a33e81b8b58d1584cf1b47ff8cd0b9e4489" +checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f" [[package]] name = "web-sys" -version = "0.3.50" +version = "0.3.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a905d57e488fec8861446d3393670fb50d27a262344013181c2cdf9fff5481be" +checksum = "e828417b379f3df7111d3a2a9e5753706cae29c41f7c4029ee9fd77f3e09e582" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/README.md b/README.md index df7fbe7..26529f0 100644 --- a/README.md +++ b/README.md @@ -115,8 +115,14 @@ Bleachbit is a master at finding and removing temporary files, while Czkawka onl | Cache support | • | | • | | | In active development | Yes | No | Yes | Yes | +## Other apps +There are many similar applications to Czkawka on the Internet, which do some things better and some things worse. +- [DupeGuru](https://github.com/arsenetar/dupeguru) - A lot of options to customize +- [FSlint](https://github.com/pixelb/fslint) - A little outdated, but have a lot of helpful tools +- [Fclones](https://github.com/pkolaczk/fclones) - One of the fastest tools to find duplicates, but only in CLI + ## Contributions -Contributions to this repository are welcome. +Contributions to this repository are welcome. You can help by creating: - Bug reports - memory leaks, unexpected behavior, crashes @@ -132,7 +138,7 @@ You can also help by doing different things: - Recommending it to others ## Name -Czkawka is a Polish word which means _hiccup_. +Czkawka is a Polish word which means _hiccup_. I chose this name because I wanted to hear people speaking other languages pronounce it, so feel free to spell it the way you want. diff --git a/czkawka_gui/src/connect_button_delete.rs b/czkawka_gui/src/connect_button_delete.rs index 667ed3f..0061d5e 100644 --- a/czkawka_gui/src/connect_button_delete.rs +++ b/czkawka_gui/src/connect_button_delete.rs @@ -36,49 +36,122 @@ pub fn connect_button_delete(gui_data: &GuiData) { match to_notebook_main_enum(notebook_main.current_page().unwrap()) { NotebookMainEnum::Duplicate => { - if !check_button_settings_confirm_group_deletion.is_active() || !check_if_deleting_all_files_in_group(&tree_view_duplicate_finder.clone(), ColumnsDuplicates::Color as i32, &window_main, &check_button_settings_confirm_group_deletion) { - tree_remove(&tree_view_duplicate_finder.clone(), ColumnsDuplicates::Name as i32, ColumnsDuplicates::Path as i32, ColumnsDuplicates::Color as i32, &gui_data); + if !check_button_settings_confirm_group_deletion.is_active() + || !check_if_deleting_all_files_in_group( + &tree_view_duplicate_finder.clone(), + ColumnsDuplicates::Color as i32, + ColumnsDuplicates::ActiveSelectButton as i32, + &window_main, + &check_button_settings_confirm_group_deletion, + ) + { + tree_remove( + &tree_view_duplicate_finder.clone(), + ColumnsDuplicates::Name as i32, + ColumnsDuplicates::Path as i32, + ColumnsDuplicates::Color as i32, + ColumnsDuplicates::ActiveSelectButton as i32, + &gui_data, + ); } } NotebookMainEnum::EmptyDirectories => { - empty_folder_remover(&tree_view_empty_folder_finder.clone(), ColumnsEmptyFolders::Name as i32, ColumnsEmptyFolders::Path as i32, &gui_data); + empty_folder_remover( + &tree_view_empty_folder_finder.clone(), + ColumnsEmptyFolders::Name as i32, + ColumnsEmptyFolders::Path as i32, + ColumnsEmptyFolders::ActiveSelectButton as i32, + &gui_data, + ); } NotebookMainEnum::EmptyFiles => { - basic_remove(&tree_view_empty_files_finder.clone(), ColumnsEmptyFiles::Name as i32, ColumnsEmptyFiles::Path as i32, &gui_data); + basic_remove( + &tree_view_empty_files_finder.clone(), + ColumnsEmptyFiles::Name as i32, + ColumnsEmptyFiles::Path as i32, + ColumnsEmptyFiles::ActiveSelectButton as i32, + &gui_data, + ); } NotebookMainEnum::Temporary => { - basic_remove(&tree_view_temporary_files_finder.clone(), ColumnsTemporaryFiles::Name as i32, ColumnsTemporaryFiles::Path as i32, &gui_data); + basic_remove( + &tree_view_temporary_files_finder.clone(), + ColumnsTemporaryFiles::Name as i32, + ColumnsTemporaryFiles::Path as i32, + ColumnsTemporaryFiles::ActiveSelectButton as i32, + &gui_data, + ); } NotebookMainEnum::BigFiles => { - basic_remove(&tree_view_big_files_finder.clone(), ColumnsBigFiles::Name as i32, ColumnsBigFiles::Path as i32, &gui_data); + basic_remove(&tree_view_big_files_finder.clone(), ColumnsBigFiles::Name as i32, ColumnsBigFiles::Path as i32, ColumnsBigFiles::ActiveSelectButton as i32, &gui_data); } NotebookMainEnum::SimilarImages => { if !check_button_settings_confirm_group_deletion.is_active() - || !check_if_deleting_all_files_in_group(&tree_view_similar_images_finder.clone(), ColumnsSimilarImages::Color as i32, &window_main, &check_button_settings_confirm_group_deletion) + || !check_if_deleting_all_files_in_group( + &tree_view_similar_images_finder.clone(), + ColumnsSimilarImages::Color as i32, + ColumnsSimilarImages::ActiveSelectButton as i32, + &window_main, + &check_button_settings_confirm_group_deletion, + ) { tree_remove( &tree_view_similar_images_finder.clone(), ColumnsSimilarImages::Name as i32, ColumnsSimilarImages::Path as i32, ColumnsSimilarImages::Color as i32, + ColumnsSimilarImages::ActiveSelectButton as i32, &gui_data, ); image_preview_similar_images.hide(); } } NotebookMainEnum::Zeroed => { - basic_remove(&tree_view_zeroed_files_finder.clone(), ColumnsZeroedFiles::Name as i32, ColumnsZeroedFiles::Path as i32, &gui_data); + basic_remove( + &tree_view_zeroed_files_finder.clone(), + ColumnsZeroedFiles::Name as i32, + ColumnsZeroedFiles::Path as i32, + ColumnsZeroedFiles::ActiveSelectButton as i32, + &gui_data, + ); } NotebookMainEnum::SameMusic => { - if !check_button_settings_confirm_group_deletion.is_active() || !check_if_deleting_all_files_in_group(&tree_view_same_music_finder.clone(), ColumnsSameMusic::Color as i32, &window_main, &check_button_settings_confirm_group_deletion) { - tree_remove(&tree_view_same_music_finder.clone(), ColumnsSameMusic::Name as i32, ColumnsSameMusic::Path as i32, ColumnsSameMusic::Color as i32, &gui_data); + if !check_button_settings_confirm_group_deletion.is_active() + || !check_if_deleting_all_files_in_group( + &tree_view_same_music_finder.clone(), + ColumnsSameMusic::Color as i32, + ColumnsSameMusic::ActiveSelectButton as i32, + &window_main, + &check_button_settings_confirm_group_deletion, + ) + { + tree_remove( + &tree_view_same_music_finder.clone(), + ColumnsSameMusic::Name as i32, + ColumnsSameMusic::Path as i32, + ColumnsSameMusic::Color as i32, + ColumnsSameMusic::ActiveSelectButton as i32, + &gui_data, + ); } } NotebookMainEnum::Symlinks => { - basic_remove(&tree_view_invalid_symlinks.clone(), ColumnsInvalidSymlinks::Name as i32, ColumnsInvalidSymlinks::Path as i32, &gui_data); + basic_remove( + &tree_view_invalid_symlinks.clone(), + ColumnsInvalidSymlinks::Name as i32, + ColumnsInvalidSymlinks::Path as i32, + ColumnsInvalidSymlinks::ActiveSelectButton as i32, + &gui_data, + ); } NotebookMainEnum::BrokenFiles => { - basic_remove(&tree_view_broken_files.clone(), ColumnsBrokenFiles::Name as i32, ColumnsBrokenFiles::Path as i32, &gui_data); + basic_remove( + &tree_view_broken_files.clone(), + ColumnsBrokenFiles::Name as i32, + ColumnsBrokenFiles::Path as i32, + ColumnsInvalidSymlinks::ActiveSelectButton as i32, + &gui_data, + ); } } }); @@ -127,39 +200,28 @@ pub fn check_if_can_delete_files(check_button_settings_confirm_deletion: >k::C true } -pub fn check_if_deleting_all_files_in_group(tree_view: >k::TreeView, column_color: i32, window_main: >k::Window, check_button_settings_confirm_group_deletion: >k::CheckButton) -> bool { - let selection = tree_view.selection(); - let (selection_rows, tree_model) = selection.selected_rows(); - if selection_rows.is_empty() { - return false; - } - - let mut current_selected_row = 0; +pub fn check_if_deleting_all_files_in_group(tree_view: >k::TreeView, column_color: i32, column_selection: i32, window_main: >k::Window, check_button_settings_confirm_group_deletion: >k::CheckButton) -> bool { + let model = get_list_store(&tree_view); let mut selected_all_records: bool = true; - if let Some(first_iter) = tree_model.iter_first() { - let current_iter = first_iter; - if tree_model.value(¤t_iter, column_color).get::().unwrap() != HEADER_ROW_COLOR { - panic!("First element, should be a header"); // First element should be header - }; + if let Some(iter) = model.iter_first() { + assert_eq!(model.value(&iter, column_color).get::().unwrap(), HEADER_ROW_COLOR); // First element should be header loop { - if !tree_model.iter_next(¤t_iter) { - if selected_all_records { - break; - } + if !model.iter_next(&iter) { break; } - if tree_model.value(¤t_iter, column_color).get::().unwrap() == HEADER_ROW_COLOR { + if model.value(&iter, column_color).get::().unwrap() == HEADER_ROW_COLOR { if selected_all_records { break; } - } else if current_selected_row != selection_rows.len() && selection_rows[current_selected_row] == tree_model.path(¤t_iter).unwrap() { - current_selected_row += 1; + selected_all_records = true; } else { - selected_all_records = false; + if !model.value(&iter, column_selection).get::().unwrap() { + selected_all_records = false; + } } } } else { @@ -217,24 +279,33 @@ pub fn check_if_deleting_all_files_in_group(tree_view: >k::TreeView, column_co false } -pub fn empty_folder_remover(tree_view: >k::TreeView, column_file_name: i32, column_path: i32, gui_data: &GuiData) { +pub fn empty_folder_remover(tree_view: >k::TreeView, column_file_name: i32, column_path: i32, column_selection: i32, gui_data: &GuiData) { let text_view_errors = gui_data.text_view_errors.clone(); let use_trash = gui_data.settings.check_button_settings_use_trash.clone().is_active(); - let selection = tree_view.selection(); + let model = get_list_store(&tree_view); - let (selection_rows, tree_model) = selection.selected_rows(); - if selection_rows.is_empty() { - return; + let mut selected_rows = Vec::new(); + + if let Some(iter) = model.iter_first() { + loop { + if model.value(&iter, column_selection).get::().unwrap() { + selected_rows.push(model.path(&iter).unwrap()); + } + if !model.iter_next(&iter) { + break; + } + } } - let list_store = get_list_store(&tree_view); let mut messages: String = "".to_string(); // Must be deleted from end to start, because when deleting entries, TreePath(and also TreeIter) will points to invalid data - for tree_path in selection_rows.iter().rev() { - let name = tree_model.value(&tree_model.iter(tree_path).unwrap(), column_file_name).get::().unwrap(); - let path = tree_model.value(&tree_model.iter(tree_path).unwrap(), column_path).get::().unwrap(); + for tree_path in selected_rows.iter().rev() { + let iter = model.iter(tree_path).unwrap(); + + let name = model.value(&iter, column_file_name).get::().unwrap(); + let path = model.value(&iter, column_path).get::().unwrap(); // We must check if folder is really empty or contains only other empty folders let mut error_happened = false; @@ -288,14 +359,14 @@ pub fn empty_folder_remover(tree_view: >k::TreeView, column_file_name: i32, co if !use_trash { match fs::remove_dir_all(format!("{}/{}", path, name)) { Ok(_) => { - list_store.remove(&list_store.iter(tree_path).unwrap()); + model.remove(&iter); } Err(_) => error_happened = true, } } else { match trash::delete(format!("{}/{}", path, name)) { Ok(_) => { - list_store.remove(&list_store.iter(tree_path).unwrap()); + model.remove(&iter); } Err(_) => error_happened = true, } @@ -307,39 +378,48 @@ pub fn empty_folder_remover(tree_view: >k::TreeView, column_file_name: i32, co } text_view_errors.buffer().unwrap().set_text(messages.as_str()); - selection.unselect_all(); } -pub fn basic_remove(tree_view: >k::TreeView, column_file_name: i32, column_path: i32, gui_data: &GuiData) { +pub fn basic_remove(tree_view: >k::TreeView, column_file_name: i32, column_path: i32, column_selection: i32, gui_data: &GuiData) { let text_view_errors = gui_data.text_view_errors.clone(); let use_trash = gui_data.settings.check_button_settings_use_trash.clone().is_active(); - let selection = tree_view.selection(); - - let (selection_rows, tree_model) = selection.selected_rows(); - if selection_rows.is_empty() { - return; - } - let list_store = get_list_store(&tree_view); + let model = get_list_store(&tree_view); let mut messages: String = "".to_string(); + let mut selection_rows = Vec::new(); + + if let Some(iter) = model.iter_first() { + loop { + if model.value(&iter, column_selection).get::().unwrap() { + selection_rows.push(model.path(&iter).unwrap()); + } + + if !model.iter_next(&iter) { + break; + } + } + } + // Must be deleted from end to start, because when deleting entries, TreePath(and also TreeIter) will points to invalid data for tree_path in selection_rows.iter().rev() { - let name = tree_model.value(&tree_model.iter(tree_path).unwrap(), column_file_name).get::().unwrap(); - let path = tree_model.value(&tree_model.iter(tree_path).unwrap(), column_path).get::().unwrap(); + let iter = model.iter(tree_path).unwrap(); + + let name = model.value(&iter, column_file_name).get::().unwrap(); + let path = model.value(&iter, column_path).get::().unwrap(); if !use_trash { match fs::remove_file(format!("{}/{}", path, name)) { Ok(_) => { - list_store.remove(&list_store.iter(tree_path).unwrap()); + model.remove(&iter); } Err(_) => messages += format!("Failed to remove file {}/{} because file doesn't exists or you don't have permissions.\n", path, name).as_str(), } } else { match trash::delete(format!("{}/{}", path, name)) { Ok(_) => { - list_store.remove(&list_store.iter(tree_path).unwrap()); + model.remove(&iter); } Err(_) => messages += format!("Failed to remove file {}/{} because file doesn't exists or you don't have permissions.\n", path, name).as_str(), } @@ -347,33 +427,45 @@ pub fn basic_remove(tree_view: >k::TreeView, column_file_name: i32, column_pat } text_view_errors.buffer().unwrap().set_text(messages.as_str()); - selection.unselect_all(); } // Remove all occurrences - remove every element which have same path and name as even non selected ones -pub fn tree_remove(tree_view: >k::TreeView, column_file_name: i32, column_path: i32, column_color: i32, gui_data: &GuiData) { +pub fn tree_remove(tree_view: >k::TreeView, column_file_name: i32, column_path: i32, column_color: i32, column_selection: i32, gui_data: &GuiData) { let text_view_errors = gui_data.text_view_errors.clone(); let use_trash = gui_data.settings.check_button_settings_use_trash.clone().is_active(); - let selection = tree_view.selection(); - - let (selection_rows, tree_model) = selection.selected_rows(); - if selection_rows.is_empty() { - return; - } - let list_store = get_list_store(&tree_view); + let model = get_list_store(&tree_view); let mut messages: String = "".to_string(); let mut vec_path_to_delete: Vec<(String, String)> = Vec::new(); let mut map_with_path_to_delete: BTreeMap> = Default::default(); // BTreeMap> + let mut selection_rows = Vec::new(); + + if let Some(iter) = model.iter_first() { + loop { + if model.value(&iter, column_selection).get::().unwrap() { + // TODO, this maybe isn't required if we will be sure that any header cannot be selected + if model.value(&iter, column_color).get::().unwrap() == MAIN_ROW_COLOR { + selection_rows.push(model.path(&iter).unwrap()); + } + } + + if !model.iter_next(&iter) { + break; + } + } + } + // Save to variable paths of files, and remove it when not removing all occurrences. for tree_path in selection_rows.iter().rev() { - let file_name = tree_model.value(&tree_model.iter(tree_path).unwrap(), column_file_name).get::().unwrap(); - let path = tree_model.value(&tree_model.iter(tree_path).unwrap(), column_path).get::().unwrap(); + let iter = model.iter(tree_path).unwrap(); - list_store.remove(&list_store.iter(tree_path).unwrap()); + let file_name = model.value(&iter, column_file_name).get::().unwrap(); + let path = model.value(&iter, column_path).get::().unwrap(); + + model.remove(&iter); map_with_path_to_delete.entry(path.clone()).or_insert_with(Vec::new); map_with_path_to_delete.get_mut(path.as_str()).unwrap().push(file_name); @@ -405,74 +497,73 @@ pub fn tree_remove(tree_view: >k::TreeView, column_file_name: i32, column_path } // Remove only child from header - if let Some(first_iter) = list_store.iter_first() { + if let Some(first_iter) = model.iter_first() { let mut vec_tree_path_to_delete: Vec = Vec::new(); let mut current_iter = first_iter; - if tree_model.value(¤t_iter, column_color).get::().unwrap() != HEADER_ROW_COLOR { + if model.value(¤t_iter, column_color).get::().unwrap() != HEADER_ROW_COLOR { panic!("First deleted element, should be a header"); // First element should be header }; let mut next_iter; let mut next_next_iter; 'main: loop { - if tree_model.value(¤t_iter, column_color).get::().unwrap() != HEADER_ROW_COLOR { + if model.value(¤t_iter, column_color).get::().unwrap() != HEADER_ROW_COLOR { panic!("First deleted element, should be a header"); // First element should be header }; next_iter = current_iter.clone(); - if !list_store.iter_next(&next_iter) { + if !model.iter_next(&next_iter) { // There is only single header left (H1 -> END) -> (NOTHING) - vec_tree_path_to_delete.push(list_store.path(¤t_iter).unwrap()); + vec_tree_path_to_delete.push(model.path(¤t_iter).unwrap()); break 'main; } - if tree_model.value(&next_iter, column_color).get::().unwrap() == HEADER_ROW_COLOR { + if model.value(&next_iter, column_color).get::().unwrap() == HEADER_ROW_COLOR { // There are two headers each others(we remove just first) -> (H1 -> H2) -> (H2) - vec_tree_path_to_delete.push(list_store.path(¤t_iter).unwrap()); + vec_tree_path_to_delete.push(model.path(¤t_iter).unwrap()); current_iter = next_iter.clone(); continue 'main; } next_next_iter = next_iter.clone(); - if !list_store.iter_next(&next_next_iter) { + if !model.iter_next(&next_next_iter) { // There is only one child of header left, so we remove it with header (H1 -> C1 -> END) -> (NOTHING) - vec_tree_path_to_delete.push(list_store.path(¤t_iter).unwrap()); - vec_tree_path_to_delete.push(list_store.path(&next_iter).unwrap()); + vec_tree_path_to_delete.push(model.path(¤t_iter).unwrap()); + vec_tree_path_to_delete.push(model.path(&next_iter).unwrap()); break 'main; } - if tree_model.value(&next_next_iter, column_color).get::().unwrap() == HEADER_ROW_COLOR { + if model.value(&next_next_iter, column_color).get::().unwrap() == HEADER_ROW_COLOR { // One child between two headers, we can remove them (H1 -> C1 -> H2) -> (H2) - vec_tree_path_to_delete.push(list_store.path(¤t_iter).unwrap()); - vec_tree_path_to_delete.push(list_store.path(&next_iter).unwrap()); + vec_tree_path_to_delete.push(model.path(¤t_iter).unwrap()); + vec_tree_path_to_delete.push(model.path(&next_iter).unwrap()); current_iter = next_next_iter.clone(); continue 'main; } loop { // (H1 -> C1 -> C2 -> Cn -> END) -> (NO CHANGE, BECAUSE IS GOOD) - if !list_store.iter_next(&next_next_iter) { + if !model.iter_next(&next_next_iter) { break 'main; } // Move to next header - if tree_model.value(&next_next_iter, column_color).get::().unwrap() == HEADER_ROW_COLOR { + if model.value(&next_next_iter, column_color).get::().unwrap() == HEADER_ROW_COLOR { current_iter = next_next_iter.clone(); continue 'main; } } } for tree_path in vec_tree_path_to_delete.iter().rev() { - list_store.remove(&list_store.iter(&tree_path).unwrap()); + model.remove(&model.iter(&tree_path).unwrap()); } } // Last step, remove orphan header if exists - if let Some(iter) = list_store.iter_first() { - if !list_store.iter_next(&iter) { - list_store.clear(); + if let Some(iter) = model.iter_first() { + if !model.iter_next(&iter) { + model.clear(); } } text_view_errors.buffer().unwrap().set_text(messages.as_str()); - selection.unselect_all(); } diff --git a/czkawka_gui/src/connect_button_select.rs b/czkawka_gui/src/connect_button_select.rs index f2663d7..3a0b27d 100644 --- a/czkawka_gui/src/connect_button_select.rs +++ b/czkawka_gui/src/connect_button_select.rs @@ -16,20 +16,18 @@ pub fn connect_button_select(gui_data: &GuiData) { // let mode = ["all", "image_size", "reverse", "custom", "date"]; let mut hashmap: HashMap> = Default::default(); { - { - // Remember to update connect_popovers file, because this data are connected to each others - hashmap.insert(NotebookMainEnum::SimilarImages, vec!["all", "image_size", "reverse", "custom", "date"]); - hashmap.insert(NotebookMainEnum::Duplicate, vec!["all", "reverse", "custom", "date"]); - hashmap.insert(NotebookMainEnum::SameMusic, vec!["all", "reverse", "custom", "date"]); + // Remember to update connect_popovers file, because this data are connected to each others + hashmap.insert(NotebookMainEnum::SimilarImages, vec!["all", "image_size", "reverse", "custom", "date"]); + hashmap.insert(NotebookMainEnum::Duplicate, vec!["all", "reverse", "custom", "date"]); + hashmap.insert(NotebookMainEnum::SameMusic, vec!["all", "reverse", "custom", "date"]); - hashmap.insert(NotebookMainEnum::EmptyFiles, vec!["all", "reverse", "custom"]); - hashmap.insert(NotebookMainEnum::EmptyDirectories, vec!["all", "reverse", "custom"]); - hashmap.insert(NotebookMainEnum::BigFiles, vec!["all", "reverse", "custom"]); - hashmap.insert(NotebookMainEnum::Symlinks, vec!["all", "reverse", "custom"]); - hashmap.insert(NotebookMainEnum::Zeroed, vec!["all", "reverse", "custom"]); - hashmap.insert(NotebookMainEnum::Temporary, vec!["all", "reverse", "custom"]); - hashmap.insert(NotebookMainEnum::BrokenFiles, vec!["all", "reverse", "custom"]); - } + hashmap.insert(NotebookMainEnum::EmptyFiles, vec!["all", "reverse", "custom"]); + hashmap.insert(NotebookMainEnum::EmptyDirectories, vec!["all", "reverse", "custom"]); + hashmap.insert(NotebookMainEnum::BigFiles, vec!["all", "reverse", "custom"]); + hashmap.insert(NotebookMainEnum::Symlinks, vec!["all", "reverse", "custom"]); + hashmap.insert(NotebookMainEnum::Zeroed, vec!["all", "reverse", "custom"]); + hashmap.insert(NotebookMainEnum::Temporary, vec!["all", "reverse", "custom"]); + hashmap.insert(NotebookMainEnum::BrokenFiles, vec!["all", "reverse", "custom"]); } let gui_data = gui_data.clone(); diff --git a/czkawka_gui/src/connect_compute_results.rs b/czkawka_gui/src/connect_compute_results.rs index ffa1b64..73552ef 100644 --- a/czkawka_gui/src/connect_compute_results.rs +++ b/czkawka_gui/src/connect_compute_results.rs @@ -114,25 +114,29 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< vector.clone() }; - let values: [(u32, &dyn ToValue); 6] = [ - (0, &name), - (1, (&(format!("{} results", vector.len())))), - (2, (&"".to_string())), // No text in 3 column - (3, (&(0))), // Not used here - (4, &(HEADER_ROW_COLOR.to_string())), - (5, &(TEXT_COLOR.to_string())), + let values: [(u32, &dyn ToValue); 8] = [ + (0, &false), + (1, &false), + (2, &name), + (3, (&(format!("{} results", vector.len())))), + (4, (&"".to_string())), // No text in 3 column + (5, (&(0))), // Not used here + (6, &(HEADER_ROW_COLOR.to_string())), + (7, &(TEXT_COLOR.to_string())), ]; list_store.set(&list_store.append(), &values); for entry in vector { let (directory, file) = split_path(&entry.path); - let values: [(u32, &dyn ToValue); 6] = [ - (0, &file), - (1, &directory), - (2, &(format!("{} - ({})", NaiveDateTime::from_timestamp(entry.modified_date as i64, 0).to_string(), entry.size.file_size(options::BINARY).unwrap()))), - (3, &(entry.modified_date)), - (4, &(MAIN_ROW_COLOR.to_string())), - (5, &(TEXT_COLOR.to_string())), + let values: [(u32, &dyn ToValue); 8] = [ + (0, &true), + (1, &false), + (2, &file), + (3, &directory), + (4, &(format!("{} - ({})", NaiveDateTime::from_timestamp(entry.modified_date as i64, 0).to_string(), entry.size.file_size(options::BINARY).unwrap()))), + (5, &(entry.modified_date)), + (6, &(MAIN_ROW_COLOR.to_string())), + (7, &(TEXT_COLOR.to_string())), ]; list_store.set(&list_store.append(), &values); } @@ -155,29 +159,33 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< vector.clone() }; - let values: [(u32, &dyn ToValue); 6] = [ - (0, &(format!("{} x {} ({} bytes)", vector.len(), size.file_size(options::BINARY).unwrap(), size))), + let values: [(u32, &dyn ToValue); 8] = [ + (0, &false), + (1, &false), + (2, &(format!("{} x {} ({} bytes)", vector.len(), size.file_size(options::BINARY).unwrap(), size))), ( - 1, + 3, &(format!("{} ({} bytes) lost", ((vector.len() - 1) as u64 * *size as u64).file_size(options::BINARY).unwrap(), (vector.len() - 1) as u64 * *size as u64)), ), - (2, &"".to_string()), // No text in 3 column - (3, &(0)), - (4, &(HEADER_ROW_COLOR.to_string())), - (5, &(TEXT_COLOR.to_string())), + (4, &"".to_string()), // No text in 3 column + (5, &(0)), + (6, &(HEADER_ROW_COLOR.to_string())), + (7, &(TEXT_COLOR.to_string())), ]; list_store.set(&list_store.append(), &values); for entry in vector { let (directory, file) = split_path(&entry.path); - let values: [(u32, &dyn ToValue); 6] = [ - (0, &file), - (1, &directory), - (2, &(NaiveDateTime::from_timestamp(entry.modified_date as i64, 0).to_string())), - (3, &(entry.modified_date)), - (4, &(MAIN_ROW_COLOR.to_string())), - (5, &(TEXT_COLOR.to_string())), + let values: [(u32, &dyn ToValue); 8] = [ + (0, &true), + (1, &false), + (2, &file), + (3, &directory), + (4, &(NaiveDateTime::from_timestamp(entry.modified_date as i64, 0).to_string())), + (5, &(entry.modified_date)), + (6, &(MAIN_ROW_COLOR.to_string())), + (7, &(TEXT_COLOR.to_string())), ]; list_store.set(&list_store.append(), &values); @@ -200,28 +208,32 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< } else { vector.clone() }; - let values: [(u32, &dyn ToValue); 6] = [ - (0, &(format!("{} x {} ({} bytes)", vector.len(), size.file_size(options::BINARY).unwrap(), size))), + let values: [(u32, &dyn ToValue); 8] = [ + (0, &false), + (1, &false), + (2, &(format!("{} x {} ({} bytes)", vector.len(), size.file_size(options::BINARY).unwrap(), size))), ( - 1, + 3, &(format!("{} ({} bytes) lost", ((vector.len() - 1) as u64 * *size as u64).file_size(options::BINARY).unwrap(), (vector.len() - 1) as u64 * *size as u64)), ), - (2, &"".to_string()), // No text in 3 column - (3, &(0)), // Not used here - (4, &(HEADER_ROW_COLOR.to_string())), - (5, &(TEXT_COLOR.to_string())), + (4, &"".to_string()), // No text in 3 column + (5, &(0)), // Not used here + (6, &(HEADER_ROW_COLOR.to_string())), + (7, &(TEXT_COLOR.to_string())), ]; list_store.set(&list_store.append(), &values); for entry in vector { let (directory, file) = split_path(&entry.path); - let values: [(u32, &dyn ToValue); 6] = [ - (0, &file), - (1, &directory), - (2, &(NaiveDateTime::from_timestamp(entry.modified_date as i64, 0).to_string())), - (3, &(entry.modified_date)), - (4, &(MAIN_ROW_COLOR.to_string())), - (5, &(TEXT_COLOR.to_string())), + let values: [(u32, &dyn ToValue); 8] = [ + (0, &true), + (1, &false), + (2, &file), + (3, &directory), + (4, &(NaiveDateTime::from_timestamp(entry.modified_date as i64, 0).to_string())), + (5, &(entry.modified_date)), + (6, &(MAIN_ROW_COLOR.to_string())), + (7, &(TEXT_COLOR.to_string())), ]; list_store.set(&list_store.append(), &values); } @@ -281,7 +293,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< for path in vector { let (directory, file) = split_path(&path); - let values: [(u32, &dyn ToValue); 3] = [(0, &file), (1, &directory), (2, &(NaiveDateTime::from_timestamp(hashmap.get(&path).unwrap().modified_date as i64, 0).to_string()))]; + let values: [(u32, &dyn ToValue); 4] = [(0, &false), (1, &file), (2, &directory), (3, &(NaiveDateTime::from_timestamp(hashmap.get(&path).unwrap().modified_date as i64, 0).to_string()))]; list_store.set(&list_store.append(), &values); } print_text_messages_to_text_view(text_messages, &text_view_errors); @@ -330,7 +342,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< for file_entry in vector { let (directory, file) = split_path(&file_entry.path); - let values: [(u32, &dyn ToValue); 3] = [(0, &file), (1, &directory), (2, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string()))]; + let values: [(u32, &dyn ToValue); 4] = [(0, &false), (1, &file), (2, &directory), (3, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string()))]; list_store.set(&list_store.append(), &values); } print_text_messages_to_text_view(text_messages, &text_view_errors); @@ -378,11 +390,12 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< }); for file_entry in vector { let (directory, file) = split_path(&file_entry.path); - let values: [(u32, &dyn ToValue); 4] = [ - (0, &(format!("{} ({} bytes)", size.file_size(options::BINARY).unwrap(), size))), - (1, &file), - (2, &directory), - (3, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())), + let values: [(u32, &dyn ToValue); 5] = [ + (0, &false), + (1, &(format!("{} ({} bytes)", size.file_size(options::BINARY).unwrap(), size))), + (2, &file), + (3, &directory), + (4, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())), ]; list_store.set(&list_store.append(), &values); } @@ -433,7 +446,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< for file_entry in vector { let (directory, file) = split_path(&file_entry.path); - let values: [(u32, &dyn ToValue); 3] = [(0, &file), (1, &directory), (2, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string()))]; + let values: [(u32, &dyn ToValue); 4] = [(0, &false), (1, &file), (2, &directory), (3, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string()))]; list_store.set(&list_store.append(), &values); } print_text_messages_to_text_view(text_messages, &text_view_errors); @@ -487,34 +500,38 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< }; // Header - let values: [(u32, &dyn ToValue); 10] = [ - (0, &"".to_string()), - (1, &"".to_string()), - (2, &(0)), + let values: [(u32, &dyn ToValue); 12] = [ + (0, &false), + (1, &false), + (2, &"".to_string()), (3, &"".to_string()), - (4, &"".to_string()), + (4, &(0)), (5, &"".to_string()), (6, &"".to_string()), - (7, &(0)), - (8, &(HEADER_ROW_COLOR.to_string())), - (9, &(TEXT_COLOR.to_string())), + (7, &"".to_string()), + (8, &"".to_string()), + (9, &(0)), + (10, &(HEADER_ROW_COLOR.to_string())), + (11, &(TEXT_COLOR.to_string())), ]; list_store.set(&list_store.append(), &values); // Meat for file_entry in vec_file_entry.iter() { let (directory, file) = split_path(&file_entry.path); - let values: [(u32, &dyn ToValue); 10] = [ - (0, &(get_text_from_similarity(&file_entry.similarity).to_string())), - (1, &file_entry.size.file_size(options::BINARY).unwrap()), - (2, &file_entry.size), - (3, &file_entry.dimensions), - (4, &file), - (5, &directory), - (6, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())), - (7, &(file_entry.modified_date)), - (8, &(MAIN_ROW_COLOR.to_string())), - (9, &(TEXT_COLOR.to_string())), + let values: [(u32, &dyn ToValue); 12] = [ + (0, &true), + (1, &false), + (2, &(get_text_from_similarity(&file_entry.similarity).to_string())), + (3, &file_entry.size.file_size(options::BINARY).unwrap()), + (4, &file_entry.size), + (5, &file_entry.dimensions), + (6, &file), + (7, &directory), + (8, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())), + (9, &(file_entry.modified_date)), + (10, &(MAIN_ROW_COLOR.to_string())), + (11, &(TEXT_COLOR.to_string())), ]; list_store.set(&list_store.append(), &values); } @@ -570,12 +587,13 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< for file_entry in vector { let (directory, file) = split_path(&file_entry.path); - let values: [(u32, &dyn ToValue); 5] = [ - (0, &(file_entry.size.file_size(options::BINARY).unwrap())), - (1, &(file_entry.size)), - (2, &file), - (3, &directory), - (4, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())), + let values: [(u32, &dyn ToValue); 6] = [ + (0, &false), + (1, &(file_entry.size.file_size(options::BINARY).unwrap())), + (2, &(file_entry.size)), + (3, &file), + (4, &directory), + (5, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())), ]; list_store.set(&list_store.append(), &values); } @@ -639,68 +657,72 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< vec_file_entry.clone() }; - let values: [(u32, &dyn ToValue); 13] = [ - (0, &"".to_string()), - (1, &(0)), + let values: [(u32, &dyn ToValue); 15] = [ + (0, &false), + (1, &false), (2, &"".to_string()), - (3, &"".to_string()), + (3, &(0)), + (4, &"".to_string()), + (5, &"".to_string()), ( - 4, + 6, &(match is_title { true => text.clone(), false => "".to_string(), }), ), ( - 5, + 7, &(match is_artist { true => text.clone(), false => "".to_string(), }), ), ( - 6, + 8, &(match is_album_title { true => text.clone(), false => "".to_string(), }), ), ( - 7, + 9, &(match is_album_artist { true => text.clone(), false => "".to_string(), }), ), ( - 8, + 10, &(match is_year { true => text.clone(), false => "".to_string(), }), ), - (9, &"".to_string()), - (10, &(0)), - (11, &(HEADER_ROW_COLOR.to_string())), - (12, &(TEXT_COLOR.to_string())), + (11, &"".to_string()), + (12, &(0)), + (13, &(HEADER_ROW_COLOR.to_string())), + (14, &(TEXT_COLOR.to_string())), ]; list_store.set(&list_store.append(), &values); for file_entry in vec_file_entry { let (directory, file) = split_path(&file_entry.path); - let values: [(u32, &dyn ToValue); 13] = [ - (0, &file_entry.size.file_size(options::BINARY).unwrap()), - (1, &file_entry.size), - (2, &file), - (3, &directory), - (4, &file_entry.title), - (5, &file_entry.artist), - (6, &file_entry.album_title), - (7, &file_entry.album_artist), - (8, &file_entry.year.to_string()), - (9, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())), - (10, &(file_entry.modified_date)), - (11, &(MAIN_ROW_COLOR.to_string())), - (12, &(TEXT_COLOR.to_string())), + let values: [(u32, &dyn ToValue); 15] = [ + (0, &true), + (1, &false), + (2, &file_entry.size.file_size(options::BINARY).unwrap()), + (3, &file_entry.size), + (4, &file), + (5, &directory), + (6, &file_entry.title), + (7, &file_entry.artist), + (8, &file_entry.album_title), + (9, &file_entry.album_artist), + (10, &file_entry.year.to_string()), + (11, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())), + (12, &(file_entry.modified_date)), + (13, &(MAIN_ROW_COLOR.to_string())), + (14, &(TEXT_COLOR.to_string())), ]; list_store.set(&list_store.append(), &values); } @@ -756,12 +778,13 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< for file_entry in vector { let (directory, file) = split_path(&file_entry.symlink_path); - let values: [(u32, &dyn ToValue); 5] = [ - (0, &file), - (1, &directory), - (2, &file_entry.destination_path.to_string_lossy().to_string()), - (3, &get_text_from_invalid_symlink_cause(&file_entry.type_of_error)), - (4, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())), + let values: [(u32, &dyn ToValue); 6] = [ + (0, &false), + (1, &file), + (2, &directory), + (3, &file_entry.destination_path.to_string_lossy().to_string()), + (4, &get_text_from_invalid_symlink_cause(&file_entry.type_of_error)), + (5, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())), ]; list_store.set(&list_store.append(), &values); } @@ -811,7 +834,13 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver< for file_entry in vector { let (directory, file) = split_path(&file_entry.path); - let values: [(u32, &dyn ToValue); 4] = [(0, &file), (1, &directory), (2, &file_entry.error_string), (3, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string()))]; + let values: [(u32, &dyn ToValue); 5] = [ + (0, &false), + (1, &file), + (2, &directory), + (3, &file_entry.error_string), + (4, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())), + ]; list_store.set(&list_store.append(), &values); } print_text_messages_to_text_view(text_messages, &text_view_errors); diff --git a/czkawka_gui/src/connect_popovers.rs b/czkawka_gui/src/connect_popovers.rs index f0e8d99..7883c26 100644 --- a/czkawka_gui/src/connect_popovers.rs +++ b/czkawka_gui/src/connect_popovers.rs @@ -9,43 +9,99 @@ use gtk::TreeIter; // File length variable allows users to choose duplicates which have shorter file name // e.g. 'tar.gz' will be selected instead 'tar.gz (copy)' etc. -fn popover_select_all(popover: >k::Popover, tree_view: >k::TreeView) { - let selection = tree_view.selection(); +fn popover_select_all(popover: >k::Popover, tree_view: >k::TreeView, column_button_selection: u32) { + let model = get_list_store(&tree_view); - selection.select_all(); - popover.popdown(); -} -fn popover_unselect_all(popover: >k::Popover, tree_view: >k::TreeView) { - let selection = tree_view.selection(); - - selection.unselect_all(); - popover.popdown(); -} -fn popover_reverse(popover: >k::Popover, tree_view: >k::TreeView) { - let selection = tree_view.selection(); - - let (vector_tree_path, tree_model) = selection.selected_rows(); - - if vector_tree_path.is_empty() { - selection.select_all(); - } else { - let tree_iter_all = tree_model.iter_first().unwrap(); // Never should be available button where there is no available records - - let mut current_path_index = 0; - let mut tree_iter_selected: TreeIter; + if let Some(iter) = model.iter_first() { loop { - if current_path_index >= vector_tree_path.len() { - selection.select_iter(&tree_iter_all); - } else { - tree_iter_selected = tree_model.iter(vector_tree_path.get(current_path_index).unwrap()).unwrap(); - if tree_model.path(&tree_iter_all).unwrap() == tree_model.path(&tree_iter_selected).unwrap() { - selection.unselect_iter(&tree_iter_selected); - current_path_index += 1; + model.set_value(&iter, column_button_selection, &true.to_value()); + + if !model.iter_next(&iter) { + break; + } + } + } + popover.popdown(); +} +fn popover_unselect_all(popover: >k::Popover, tree_view: >k::TreeView, column_button_selection: u32) { + let model = get_list_store(&tree_view); + + if let Some(iter) = model.iter_first() { + loop { + model.set_value(&iter, column_button_selection, &false.to_value()); + + if !model.iter_next(&iter) { + break; + } + } + } + popover.popdown(); +} +fn popover_reverse(popover: >k::Popover, tree_view: >k::TreeView, column_button_selection: u32) { + let model = get_list_store(&tree_view); + + if let Some(iter) = model.iter_first() { + loop { + let current_value: bool = model.value(&iter, column_button_selection as i32).get::().unwrap(); + model.set_value(&iter, column_button_selection, &(!current_value).to_value()); + + if !model.iter_next(&iter) { + break; + } + } + } + popover.popdown(); +} + +fn popover_all_except_oldest(popover: >k::Popover, tree_view: >k::TreeView, column_color: i32, column_modification_as_secs: i32, column_file_name: i32, column_button_selection: u32) { + let model = get_list_store(&tree_view); + + if let Some(iter) = model.iter_first() { + let mut end: bool = false; + loop { + let mut tree_iter_array: Vec = Vec::new(); + let mut oldest_index: Option = None; + let mut current_index: usize = 0; + let mut oldest_modification_time: u64 = u64::MAX; + + let mut file_length: usize = 0; + + loop { + let color = model.value(&iter, column_color).get::().unwrap(); + if color == HEADER_ROW_COLOR { + if !model.iter_next(&iter) { + end = true; + } + break; + } + tree_iter_array.push(iter.clone()); + let modification = model.value(&iter, column_modification_as_secs).get::().unwrap(); + let current_file_length = model.value(&iter, column_file_name).get::().unwrap().len(); + if modification < oldest_modification_time || (modification == oldest_modification_time && current_file_length < file_length) { + file_length = current_file_length; + oldest_modification_time = modification; + oldest_index = Some(current_index); + } + + current_index += 1; + + if !model.iter_next(&iter) { + end = true; + break; + } + } + if oldest_index == None { + continue; + } + for (index, tree_iter) in tree_iter_array.iter().enumerate() { + if index != oldest_index.unwrap() { + model.set_value(&tree_iter, column_button_selection, &true.to_value()); } else { - selection.select_iter(&tree_iter_all); + model.set_value(&tree_iter, column_button_selection, &false.to_value()); } } - if !tree_model.iter_next(&tree_iter_all) { + + if end { break; } } @@ -53,240 +109,175 @@ fn popover_reverse(popover: >k::Popover, tree_view: >k::TreeView) { popover.popdown(); } +fn popover_all_except_newest(popover: >k::Popover, tree_view: >k::TreeView, column_color: i32, column_modification_as_secs: i32, column_file_name: i32, column_button_selection: u32) { + let model = get_list_store(&tree_view); -fn popover_all_except_oldest(popover: >k::Popover, tree_view: >k::TreeView, column_color: i32, column_modification_as_secs: i32, column_file_name: i32) { - let selection = tree_view.selection(); - let tree_model = tree_view.model().unwrap(); - - let tree_iter_all = tree_model.iter_first().unwrap(); // Never should be available button where there is no available records - - let mut end: bool = false; - - loop { - let mut tree_iter_array: Vec = Vec::new(); - let mut oldest_index: Option = None; - let mut current_index: usize = 0; - let mut oldest_modification_time: u64 = u64::MAX; - - let mut file_length: usize = 0; - + if let Some(iter) = model.iter_first() { + let mut end: bool = false; loop { - let color = tree_model.value(&tree_iter_all, column_color).get::().unwrap(); - if color == HEADER_ROW_COLOR { - if !tree_model.iter_next(&tree_iter_all) { - end = true; + let mut tree_iter_array: Vec = Vec::new(); + let mut newest_index: Option = None; + let mut current_index: usize = 0; + let mut newest_modification_time: u64 = 0; + + let mut file_length: usize = 0; + + loop { + let color = model.value(&iter, column_color).get::().unwrap(); + if color == HEADER_ROW_COLOR { + if !model.iter_next(&iter) { + end = true; + } + break; } + tree_iter_array.push(iter.clone()); + let modification = model.value(&iter, column_modification_as_secs).get::().unwrap(); + let current_file_length = model.value(&iter, column_file_name).get::().unwrap().len(); + if modification > newest_modification_time || (modification == newest_modification_time && current_file_length < file_length) { + file_length = current_file_length; + newest_modification_time = modification; + newest_index = Some(current_index); + } + + current_index += 1; + + if !model.iter_next(&iter) { + end = true; + break; + } + } + if newest_index == None { + continue; + } + for (index, tree_iter) in tree_iter_array.iter().enumerate() { + if index != newest_index.unwrap() { + model.set_value(&tree_iter, column_button_selection, &true.to_value()); + } else { + model.set_value(&tree_iter, column_button_selection, &false.to_value()); + } + } + + if end { break; } - tree_iter_array.push(tree_iter_all.clone()); - let modification = tree_model.value(&tree_iter_all, column_modification_as_secs).get::().unwrap(); - let current_file_length = tree_model.value(&tree_iter_all, column_file_name).get::().unwrap().len(); - if modification < oldest_modification_time || (modification == oldest_modification_time && current_file_length < file_length) { - file_length = current_file_length; - oldest_modification_time = modification; - oldest_index = Some(current_index); - } - - current_index += 1; - - if !tree_model.iter_next(&tree_iter_all) { - end = true; - break; - } - } - if oldest_index == None { - continue; - } - for (index, tree_iter) in tree_iter_array.iter().enumerate() { - if index != oldest_index.unwrap() { - selection.select_iter(tree_iter); - } else { - selection.unselect_iter(tree_iter); - } - } - - if end { - break; } } popover.popdown(); } -fn popover_all_except_newest(popover: >k::Popover, tree_view: >k::TreeView, column_color: i32, column_modification_as_secs: i32, column_file_name: i32) { - let selection = tree_view.selection(); - let tree_model = tree_view.model().unwrap(); - - let tree_iter_all = tree_model.iter_first().unwrap(); // Never should be available button where there is no available records - - let mut end: bool = false; - - loop { - let mut tree_iter_array: Vec = Vec::new(); - let mut newest_index: Option = None; - let mut current_index: usize = 0; - let mut newest_modification_time: u64 = 0; - - let mut file_length: usize = 0; +fn popover_one_oldest(popover: >k::Popover, tree_view: >k::TreeView, column_color: i32, column_modification_as_secs: i32, column_file_name: i32, column_button_selection: u32) { + let model = get_list_store(&tree_view); + if let Some(iter) = model.iter_first() { + let mut end: bool = false; loop { - let color = tree_model.value(&tree_iter_all, column_color).get::().unwrap(); - if color == HEADER_ROW_COLOR { - if !tree_model.iter_next(&tree_iter_all) { - end = true; + let mut tree_iter_array: Vec = Vec::new(); + let mut oldest_index: Option = None; + let mut current_index: usize = 0; + let mut oldest_modification_time: u64 = u64::MAX; + + let mut file_length: usize = 0; + + loop { + let color = model.value(&iter, column_color).get::().unwrap(); + if color == HEADER_ROW_COLOR { + if !model.iter_next(&iter) { + end = true; + } + break; } + tree_iter_array.push(iter.clone()); + let modification = model.value(&iter, column_modification_as_secs).get::().unwrap(); + let current_file_length = model.value(&iter, column_file_name).get::().unwrap().len(); + if modification < oldest_modification_time || (modification == oldest_modification_time && current_file_length > file_length) { + file_length = current_file_length; + oldest_modification_time = modification; + oldest_index = Some(current_index); + } + + current_index += 1; + + if !model.iter_next(&iter) { + end = true; + break; + } + } + if oldest_index == None { + continue; + } + for (index, tree_iter) in tree_iter_array.iter().enumerate() { + if index == oldest_index.unwrap() { + model.set_value(&tree_iter, column_button_selection, &true.to_value()); + } else { + model.set_value(&tree_iter, column_button_selection, &false.to_value()); + } + } + + if end { break; } - tree_iter_array.push(tree_iter_all.clone()); - let modification = tree_model.value(&tree_iter_all, column_modification_as_secs).get::().unwrap(); - let current_file_length = tree_model.value(&tree_iter_all, column_file_name).get::().unwrap().len(); - if modification > newest_modification_time || (modification == newest_modification_time && current_file_length < file_length) { - file_length = current_file_length; - newest_modification_time = modification; - newest_index = Some(current_index); - } - - current_index += 1; - - if !tree_model.iter_next(&tree_iter_all) { - end = true; - break; - } - } - if newest_index == None { - continue; - } - for (index, tree_iter) in tree_iter_array.iter().enumerate() { - if index != newest_index.unwrap() { - selection.select_iter(tree_iter); - } else { - selection.unselect_iter(tree_iter); - } - } - - if end { - break; } } popover.popdown(); } -fn popover_one_oldest(popover: >k::Popover, tree_view: >k::TreeView, column_color: i32, column_modification_as_secs: i32, column_file_name: i32) { - let selection = tree_view.selection(); - let tree_model = tree_view.model().unwrap(); - - let tree_iter_all = tree_model.iter_first().unwrap(); // Never should be available button where there is no available records - - let mut end: bool = false; - - loop { - let mut tree_iter_array: Vec = Vec::new(); - let mut oldest_index: Option = None; - let mut current_index: usize = 0; - let mut oldest_modification_time: u64 = u64::MAX; - - let mut file_length: usize = 0; +fn popover_one_newest(popover: >k::Popover, tree_view: >k::TreeView, column_color: i32, column_modification_as_secs: i32, column_file_name: i32, column_button_selection: u32) { + let model = get_list_store(&tree_view); + if let Some(iter) = model.iter_first() { + let mut end: bool = false; loop { - let color = tree_model.value(&tree_iter_all, column_color).get::().unwrap(); - if color == HEADER_ROW_COLOR { - if !tree_model.iter_next(&tree_iter_all) { - end = true; + let mut tree_iter_array: Vec = Vec::new(); + let mut newest_index: Option = None; + let mut current_index: usize = 0; + let mut newest_modification_time: u64 = 0; + + let mut file_length: usize = 0; + loop { + let color = model.value(&iter, column_color).get::().unwrap(); + if color == HEADER_ROW_COLOR { + if !model.iter_next(&iter) { + end = true; + } + break; } - break; - } - tree_iter_array.push(tree_iter_all.clone()); - let modification = tree_model.value(&tree_iter_all, column_modification_as_secs).get::().unwrap(); - let current_file_length = tree_model.value(&tree_iter_all, column_file_name).get::().unwrap().len(); - if modification < oldest_modification_time || (modification == oldest_modification_time && current_file_length > file_length) { - file_length = current_file_length; - oldest_modification_time = modification; - oldest_index = Some(current_index); - } - - current_index += 1; - - if !tree_model.iter_next(&tree_iter_all) { - end = true; - break; - } - } - if oldest_index == None { - continue; - } - for (index, tree_iter) in tree_iter_array.iter().enumerate() { - if index == oldest_index.unwrap() { - selection.select_iter(tree_iter); - } else { - selection.unselect_iter(tree_iter); - } - } - - if end { - break; - } - } - - popover.popdown(); -} -fn popover_one_newest(popover: >k::Popover, tree_view: >k::TreeView, column_color: i32, column_modification_as_secs: i32, column_file_name: i32) { - let selection = tree_view.selection(); - let tree_model = tree_view.model().unwrap(); - - let tree_iter_all = tree_model.iter_first().unwrap(); // Never should be available button where there is no available records - - let mut end: bool = false; - - loop { - let mut tree_iter_array: Vec = Vec::new(); - let mut newest_index: Option = None; - let mut current_index: usize = 0; - let mut newest_modification_time: u64 = 0; - - let mut file_length: usize = 0; - loop { - let color = tree_model.value(&tree_iter_all, column_color).get::().unwrap(); - if color == HEADER_ROW_COLOR { - if !tree_model.iter_next(&tree_iter_all) { - end = true; + tree_iter_array.push(iter.clone()); + let modification = model.value(&iter, column_modification_as_secs).get::().unwrap(); + let current_file_length = model.value(&iter, column_file_name).get::().unwrap().len(); + if modification > newest_modification_time || (modification == newest_modification_time && current_file_length > file_length) { + file_length = current_file_length; + newest_modification_time = modification; + newest_index = Some(current_index); } + + current_index += 1; + + if !model.iter_next(&iter) { + end = true; + break; + } + } + if newest_index == None { + continue; + } + for (index, tree_iter) in tree_iter_array.iter().enumerate() { + if index == newest_index.unwrap() { + model.set_value(&tree_iter, column_button_selection, &true.to_value()); + } else { + model.set_value(&tree_iter, column_button_selection, &false.to_value()); + } + } + + if end { break; } - tree_iter_array.push(tree_iter_all.clone()); - let modification = tree_model.value(&tree_iter_all, column_modification_as_secs).get::().unwrap(); - let current_file_length = tree_model.value(&tree_iter_all, column_file_name).get::().unwrap().len(); - if modification > newest_modification_time || (modification == newest_modification_time && current_file_length > file_length) { - file_length = current_file_length; - newest_modification_time = modification; - newest_index = Some(current_index); - } - - current_index += 1; - - if !tree_model.iter_next(&tree_iter_all) { - end = true; - break; - } - } - if newest_index == None { - continue; - } - for (index, tree_iter) in tree_iter_array.iter().enumerate() { - if index == newest_index.unwrap() { - selection.select_iter(tree_iter); - } else { - selection.unselect_iter(tree_iter); - } - } - - if end { - break; } } popover.popdown(); } -fn popover_select_custom(popover: >k::Popover, gui_data: &GuiData, tree_view: >k::TreeView, column_color: Option, column_file_name: i32, column_path: i32) { +fn popover_select_custom(popover: >k::Popover, gui_data: &GuiData, tree_view: >k::TreeView, column_color: Option, column_file_name: i32, column_path: i32, column_button_selection: u32) { popover.popdown(); let wildcard: String; @@ -365,49 +356,48 @@ fn popover_select_custom(popover: >k::Popover, gui_data: &GuiData, tree_view: #[cfg(target_family = "windows")] let wildcard = wildcard.as_str(); - let selection = tree_view.selection(); - let tree_model = tree_view.model().unwrap(); + let model = get_list_store(&tree_view); - let tree_iter = tree_model.iter_first().unwrap(); // Never should be available button where there is no available records + let iter = model.iter_first().unwrap(); // Never should be available button where there is no available records loop { if let Some(column_color) = column_color { - let color = tree_model.value(&tree_iter, column_color).get::().unwrap(); + let color = model.value(&iter, column_color).get::().unwrap(); if color == HEADER_ROW_COLOR { - if !tree_model.iter_next(&tree_iter) { + if !model.iter_next(&iter) { break; } continue; } } - let path = tree_model.value(&tree_iter, column_path).get::().unwrap(); - let name = tree_model.value(&tree_iter, column_file_name).get::().unwrap(); + let path = model.value(&iter, column_path).get::().unwrap(); + let name = model.value(&iter, column_file_name).get::().unwrap(); match wildcard_type { WildcardType::Path => { if Common::regex_check(wildcard, path) { - selection.select_iter(&tree_iter); + model.set_value(&iter, column_button_selection, &true.to_value()); } } WildcardType::Name => { if Common::regex_check(wildcard, name) { - selection.select_iter(&tree_iter); + model.set_value(&iter, column_button_selection, &true.to_value()); } } WildcardType::PathName => { if Common::regex_check(wildcard, format!("{}/{}", path, name)) { - selection.select_iter(&tree_iter); + model.set_value(&iter, column_button_selection, &true.to_value()); } } } - if !tree_model.iter_next(&tree_iter) { + if !model.iter_next(&iter) { break; } } } } -fn popover_unselect_custom(popover: >k::Popover, gui_data: &GuiData, tree_view: >k::TreeView, column_color: Option, column_file_name: i32, column_path: i32) { +fn popover_unselect_custom(popover: >k::Popover, gui_data: &GuiData, tree_view: >k::TreeView, column_color: Option, column_file_name: i32, column_path: i32, column_button_selection: u32) { popover.popdown(); let wildcard: String; @@ -484,166 +474,161 @@ fn popover_unselect_custom(popover: >k::Popover, gui_data: &GuiData, tree_view #[cfg(target_family = "windows")] let wildcard = wildcard.as_str(); - let selection = tree_view.selection(); - let tree_model = tree_view.model().unwrap(); + let model = get_list_store(&tree_view); - let tree_iter = tree_model.iter_first().unwrap(); // Never should be available button where there is no available records + let iter = model.iter_first().unwrap(); // Never should be available button where there is no available records loop { if let Some(column_color) = column_color { - let color = tree_model.value(&tree_iter, column_color).get::().unwrap(); + let color = model.value(&iter, column_color).get::().unwrap(); if color == HEADER_ROW_COLOR { - if !tree_model.iter_next(&tree_iter) { + if !model.iter_next(&iter) { break; } continue; } } - let path = tree_model.value(&tree_iter, column_path).get::().unwrap(); - let name = tree_model.value(&tree_iter, column_file_name).get::().unwrap(); + let path = model.value(&iter, column_path).get::().unwrap(); + let name = model.value(&iter, column_file_name).get::().unwrap(); match wildcard_type { WildcardType::Path => { if Common::regex_check(wildcard, path) { - selection.unselect_iter(&tree_iter); + model.set_value(&iter, column_button_selection, &false.to_value()); } } WildcardType::Name => { if Common::regex_check(wildcard, name) { - selection.unselect_iter(&tree_iter); + model.set_value(&iter, column_button_selection, &false.to_value()); } } WildcardType::PathName => { if Common::regex_check(wildcard, format!("{}/{}", path, name)) { - selection.unselect_iter(&tree_iter); + model.set_value(&iter, column_button_selection, &false.to_value()); } } } - if !tree_model.iter_next(&tree_iter) { + if !model.iter_next(&iter) { break; } } } } -fn popover_all_except_biggest(popover: >k::Popover, tree_view: >k::TreeView, column_color: i32, column_size_as_bytes: i32, column_dimensions: i32) { - let selection = tree_view.selection(); - let tree_model = tree_view.model().unwrap(); - - let tree_iter_all = tree_model.iter_first().unwrap(); // Never should be available button where there is no available records - - let mut end: bool = false; - - loop { - let mut tree_iter_array: Vec = Vec::new(); - let mut biggest_index: Option = None; - let mut current_index: usize = 0; - let mut biggest_size_as_bytes: u64 = 0; - let mut biggest_number_of_pixels: u64 = 0; +fn popover_all_except_biggest(popover: >k::Popover, tree_view: >k::TreeView, column_color: i32, column_size_as_bytes: i32, column_dimensions: i32, column_button_selection: u32) { + let model = get_list_store(&tree_view); + if let Some(iter) = model.iter_first() { + let mut end: bool = false; loop { - let color = tree_model.value(&tree_iter_all, column_color).get::().unwrap(); - if color == HEADER_ROW_COLOR { - if !tree_model.iter_next(&tree_iter_all) { - end = true; + let mut tree_iter_array: Vec = Vec::new(); + let mut biggest_index: Option = None; + let mut current_index: usize = 0; + let mut biggest_size_as_bytes: u64 = 0; + let mut biggest_number_of_pixels: u64 = 0; + + loop { + let color = model.value(&iter, column_color).get::().unwrap(); + if color == HEADER_ROW_COLOR { + if !model.iter_next(&iter) { + end = true; + } + break; } + tree_iter_array.push(iter.clone()); + let size_as_bytes = model.value(&iter, column_size_as_bytes).get::().unwrap(); + let dimensions_string = model.value(&iter, column_dimensions).get::().unwrap(); + + let dimensions = change_dimension_to_krotka(dimensions_string); + let number_of_pixels = dimensions.0 * dimensions.1; + + if number_of_pixels > biggest_number_of_pixels || (number_of_pixels == biggest_number_of_pixels && size_as_bytes > biggest_size_as_bytes) { + biggest_number_of_pixels = number_of_pixels; + biggest_size_as_bytes = size_as_bytes; + biggest_index = Some(current_index); + } + + current_index += 1; + + if !model.iter_next(&iter) { + end = true; + break; + } + } + if biggest_index == None { + continue; + } + for (index, tree_iter) in tree_iter_array.iter().enumerate() { + if index != biggest_index.unwrap() { + model.set_value(&tree_iter, column_button_selection, &true.to_value()); + } else { + model.set_value(&tree_iter, column_button_selection, &false.to_value()); + } + } + + if end { break; } - tree_iter_array.push(tree_iter_all.clone()); - let size_as_bytes = tree_model.value(&tree_iter_all, column_size_as_bytes).get::().unwrap(); - let dimensions_string = tree_model.value(&tree_iter_all, column_dimensions).get::().unwrap(); - - let dimensions = change_dimension_to_krotka(dimensions_string); - let number_of_pixels = dimensions.0 * dimensions.1; - - if number_of_pixels > biggest_number_of_pixels || (number_of_pixels == biggest_number_of_pixels && size_as_bytes > biggest_size_as_bytes) { - biggest_number_of_pixels = number_of_pixels; - biggest_size_as_bytes = size_as_bytes; - biggest_index = Some(current_index); - } - - current_index += 1; - - if !tree_model.iter_next(&tree_iter_all) { - end = true; - break; - } - } - if biggest_index == None { - continue; - } - for (index, tree_iter) in tree_iter_array.iter().enumerate() { - if index != biggest_index.unwrap() { - selection.select_iter(tree_iter); - } else { - selection.unselect_iter(tree_iter); - } - } - - if end { - break; } } popover.popdown(); } -fn popover_all_except_smallest(popover: >k::Popover, tree_view: >k::TreeView, column_color: i32, column_size_as_bytes: i32, column_dimensions: i32) { - let selection = tree_view.selection(); - let tree_model = tree_view.model().unwrap(); - - let tree_iter_all = tree_model.iter_first().unwrap(); // Never should be available button where there is no available records - - let mut end: bool = false; - - loop { - let mut tree_iter_array: Vec = Vec::new(); - let mut smallest_index: Option = None; - let mut current_index: usize = 0; - let mut smallest_size_as_bytes: u64 = u64::MAX; - let mut smallest_number_of_pixels: u64 = u64::MAX; +fn popover_all_except_smallest(popover: >k::Popover, tree_view: >k::TreeView, column_color: i32, column_size_as_bytes: i32, column_dimensions: i32, column_button_selection: u32) { + let model = get_list_store(&tree_view); + if let Some(iter) = model.iter_first() { + let mut end: bool = false; loop { - let color = tree_model.value(&tree_iter_all, column_color).get::().unwrap(); - if color == HEADER_ROW_COLOR { - if !tree_model.iter_next(&tree_iter_all) { - end = true; + let mut tree_iter_array: Vec = Vec::new(); + let mut smallest_index: Option = None; + let mut current_index: usize = 0; + let mut smallest_size_as_bytes: u64 = u64::MAX; + let mut smallest_number_of_pixels: u64 = u64::MAX; + + loop { + let color = model.value(&iter, column_color).get::().unwrap(); + if color == HEADER_ROW_COLOR { + if !model.iter_next(&iter) { + end = true; + } + break; } + tree_iter_array.push(iter.clone()); + let size_as_bytes = model.value(&iter, column_size_as_bytes).get::().unwrap(); + let dimensions_string = model.value(&iter, column_dimensions).get::().unwrap(); + + let dimensions = change_dimension_to_krotka(dimensions_string); + let number_of_pixels = dimensions.0 * dimensions.1; + + if number_of_pixels < smallest_number_of_pixels || (number_of_pixels == smallest_number_of_pixels && size_as_bytes < smallest_size_as_bytes) { + smallest_number_of_pixels = number_of_pixels; + smallest_size_as_bytes = size_as_bytes; + smallest_index = Some(current_index); + } + + current_index += 1; + + if !model.iter_next(&iter) { + end = true; + break; + } + } + if smallest_index == None { + continue; + } + for (index, tree_iter) in tree_iter_array.iter().enumerate() { + if index != smallest_index.unwrap() { + model.set_value(&tree_iter, column_button_selection, &true.to_value()); + } else { + model.set_value(&tree_iter, column_button_selection, &false.to_value()); + } + } + + if end { break; } - tree_iter_array.push(tree_iter_all.clone()); - let size_as_bytes = tree_model.value(&tree_iter_all, column_size_as_bytes).get::().unwrap(); - let dimensions_string = tree_model.value(&tree_iter_all, column_dimensions).get::().unwrap(); - - let dimensions = change_dimension_to_krotka(dimensions_string); - let number_of_pixels = dimensions.0 * dimensions.1; - - if number_of_pixels < smallest_number_of_pixels || (number_of_pixels == smallest_number_of_pixels && size_as_bytes < smallest_size_as_bytes) { - smallest_number_of_pixels = number_of_pixels; - smallest_size_as_bytes = size_as_bytes; - smallest_index = Some(current_index); - } - - current_index += 1; - - if !tree_model.iter_next(&tree_iter_all) { - end = true; - break; - } - } - if smallest_index == None { - continue; - } - for (index, tree_iter) in tree_iter_array.iter().enumerate() { - if index != smallest_index.unwrap() { - selection.select_iter(tree_iter); - } else { - selection.unselect_iter(tree_iter); - } - } - - if end { - break; } } @@ -655,8 +640,9 @@ pub struct PopoverObject { pub notebook_type: NotebookMainEnum, pub available_modes: Vec, pub tree_view: gtk::TreeView, - pub column_path: Option, - pub column_name: Option, + pub column_path: i32, + pub column_name: i32, + pub column_selection: u32, // TODo Change this to i32 after properly implement all things pub column_color: Option, pub column_dimensions: Option, pub column_size: Option, @@ -679,8 +665,9 @@ pub fn connect_popovers(gui_data: &GuiData) { notebook_type: NotebookMainEnum::Duplicate, available_modes: vec!["all", "reverse", "custom", "date"].iter().map(|e| e.to_string()).collect(), tree_view: gui_data.main_notebook.tree_view_duplicate_finder.clone(), - column_path: Some(ColumnsDuplicates::Path as i32), - column_name: Some(ColumnsDuplicates::Name as i32), + column_path: ColumnsDuplicates::Path as i32, + column_name: ColumnsDuplicates::Name as i32, + column_selection: ColumnsDuplicates::ActiveSelectButton as u32, column_color: Some(ColumnsDuplicates::Color as i32), column_dimensions: None, column_size: None, @@ -691,8 +678,9 @@ pub fn connect_popovers(gui_data: &GuiData) { notebook_type: NotebookMainEnum::SameMusic, available_modes: vec!["all", "reverse", "custom", "date"].iter().map(|e| e.to_string()).collect(), tree_view: gui_data.main_notebook.tree_view_same_music_finder.clone(), - column_path: Some(ColumnsSameMusic::Path as i32), - column_name: Some(ColumnsSameMusic::Name as i32), + column_path: ColumnsSameMusic::Path as i32, + column_name: ColumnsSameMusic::Name as i32, + column_selection: ColumnsSameMusic::ActiveSelectButton as u32, column_color: Some(ColumnsSameMusic::Color as i32), column_dimensions: None, column_size: None, @@ -703,8 +691,9 @@ pub fn connect_popovers(gui_data: &GuiData) { notebook_type: NotebookMainEnum::SimilarImages, available_modes: vec!["all", "reverse", "custom", "date"].iter().map(|e| e.to_string()).collect(), tree_view: gui_data.main_notebook.tree_view_similar_images_finder.clone(), - column_path: Some(ColumnsSimilarImages::Path as i32), - column_name: Some(ColumnsSimilarImages::Name as i32), + column_path: ColumnsSimilarImages::Path as i32, + column_name: ColumnsSimilarImages::Name as i32, + column_selection: ColumnsSimilarImages::ActiveSelectButton as u32, column_color: Some(ColumnsSimilarImages::Color as i32), column_dimensions: Some(ColumnsSimilarImages::Dimensions as i32), column_size: Some(ColumnsSimilarImages::Size as i32), @@ -715,8 +704,9 @@ pub fn connect_popovers(gui_data: &GuiData) { notebook_type: NotebookMainEnum::EmptyDirectories, available_modes: vec!["all", "reverse", "custom"].iter().map(|e| e.to_string()).collect(), tree_view: gui_data.main_notebook.tree_view_empty_folder_finder.clone(), - column_path: Some(ColumnsEmptyFolders::Path as i32), - column_name: Some(ColumnsEmptyFolders::Name as i32), + column_path: ColumnsEmptyFolders::Path as i32, + column_name: ColumnsEmptyFolders::Name as i32, + column_selection: ColumnsEmptyFolders::ActiveSelectButton as u32, column_color: None, column_dimensions: None, column_size: None, @@ -727,8 +717,9 @@ pub fn connect_popovers(gui_data: &GuiData) { notebook_type: NotebookMainEnum::EmptyFiles, available_modes: vec!["all", "reverse", "custom"].iter().map(|e| e.to_string()).collect(), tree_view: gui_data.main_notebook.tree_view_empty_files_finder.clone(), - column_path: Some(ColumnsEmptyFiles::Path as i32), - column_name: Some(ColumnsEmptyFiles::Name as i32), + column_path: ColumnsEmptyFiles::Path as i32, + column_name: ColumnsEmptyFiles::Name as i32, + column_selection: ColumnsEmptyFiles::ActiveSelectButton as u32, column_color: None, column_dimensions: None, column_size: None, @@ -739,8 +730,9 @@ pub fn connect_popovers(gui_data: &GuiData) { notebook_type: NotebookMainEnum::Temporary, available_modes: vec!["all", "reverse", "custom"].iter().map(|e| e.to_string()).collect(), tree_view: gui_data.main_notebook.tree_view_temporary_files_finder.clone(), - column_path: Some(ColumnsTemporaryFiles::Path as i32), - column_name: Some(ColumnsTemporaryFiles::Name as i32), + column_path: ColumnsTemporaryFiles::Path as i32, + column_name: ColumnsTemporaryFiles::Name as i32, + column_selection: ColumnsTemporaryFiles::ActiveSelectButton as u32, column_color: None, column_dimensions: None, column_size: None, @@ -751,8 +743,9 @@ pub fn connect_popovers(gui_data: &GuiData) { notebook_type: NotebookMainEnum::BigFiles, available_modes: vec!["all", "reverse", "custom"].iter().map(|e| e.to_string()).collect(), tree_view: gui_data.main_notebook.tree_view_big_files_finder.clone(), - column_path: Some(ColumnsBigFiles::Path as i32), - column_name: Some(ColumnsBigFiles::Name as i32), + column_path: ColumnsBigFiles::Path as i32, + column_name: ColumnsBigFiles::Name as i32, + column_selection: ColumnsBigFiles::ActiveSelectButton as u32, column_color: None, column_dimensions: None, column_size: None, @@ -763,8 +756,9 @@ pub fn connect_popovers(gui_data: &GuiData) { notebook_type: NotebookMainEnum::Zeroed, available_modes: vec!["all", "reverse", "custom"].iter().map(|e| e.to_string()).collect(), tree_view: gui_data.main_notebook.tree_view_zeroed_files_finder.clone(), - column_path: Some(ColumnsZeroedFiles::Path as i32), - column_name: Some(ColumnsZeroedFiles::Name as i32), + column_path: ColumnsZeroedFiles::Path as i32, + column_name: ColumnsZeroedFiles::Name as i32, + column_selection: ColumnsZeroedFiles::ActiveSelectButton as u32, column_color: None, column_dimensions: None, column_size: None, @@ -775,8 +769,9 @@ pub fn connect_popovers(gui_data: &GuiData) { notebook_type: NotebookMainEnum::BrokenFiles, available_modes: vec!["all", "reverse", "custom"].iter().map(|e| e.to_string()).collect(), tree_view: gui_data.main_notebook.tree_view_broken_files.clone(), - column_path: Some(ColumnsBrokenFiles::Path as i32), - column_name: Some(ColumnsBrokenFiles::Name as i32), + column_path: ColumnsBrokenFiles::Path as i32, + column_name: ColumnsBrokenFiles::Name as i32, + column_selection: ColumnsBrokenFiles::ActiveSelectButton as u32, column_color: None, column_dimensions: None, column_size: None, @@ -787,8 +782,9 @@ pub fn connect_popovers(gui_data: &GuiData) { notebook_type: NotebookMainEnum::Symlinks, available_modes: vec!["all", "reverse", "custom"].iter().map(|e| e.to_string()).collect(), tree_view: gui_data.main_notebook.tree_view_invalid_symlinks.clone(), - column_path: Some(ColumnsInvalidSymlinks::Path as i32), - column_name: Some(ColumnsInvalidSymlinks::Name as i32), + column_path: ColumnsInvalidSymlinks::Path as i32, + column_name: ColumnsInvalidSymlinks::Name as i32, + column_selection: ColumnsInvalidSymlinks::ActiveSelectButton as u32, column_color: None, column_dimensions: None, column_size: None, @@ -803,7 +799,7 @@ pub fn connect_popovers(gui_data: &GuiData) { let vec_popover_objects = popover_objects.clone(); buttons_popover_select_all.connect_clicked(move |_| { let object_popover = find_name(&to_notebook_main_enum(notebook_main.current_page().unwrap()), &vec_popover_objects).unwrap(); - popover_select_all(&popover_select, &object_popover.tree_view); + popover_select_all(&popover_select, &object_popover.tree_view, object_popover.column_selection); }); let popover_select = gui_data.popovers.popover_select.clone(); @@ -812,7 +808,7 @@ pub fn connect_popovers(gui_data: &GuiData) { let vec_popover_objects = popover_objects.clone(); buttons_popover_unselect_all.connect_clicked(move |_| { let object_popover = find_name(&to_notebook_main_enum(notebook_main.current_page().unwrap()), &vec_popover_objects).unwrap(); - popover_unselect_all(&popover_select, &object_popover.tree_view); + popover_unselect_all(&popover_select, &object_popover.tree_view, object_popover.column_selection); }); let popover_select = gui_data.popovers.popover_select.clone(); @@ -821,7 +817,7 @@ pub fn connect_popovers(gui_data: &GuiData) { let vec_popover_objects = popover_objects.clone(); buttons_popover_reverse.connect_clicked(move |_| { let object_popover = find_name(&to_notebook_main_enum(notebook_main.current_page().unwrap()), &vec_popover_objects).unwrap(); - popover_reverse(&popover_select, &object_popover.tree_view); + popover_reverse(&popover_select, &object_popover.tree_view, object_popover.column_selection); }); let popover_select = gui_data.popovers.popover_select.clone(); @@ -835,7 +831,8 @@ pub fn connect_popovers(gui_data: &GuiData) { &object_popover.tree_view, object_popover.column_color.unwrap(), object_popover.column_modification_as_secs.unwrap(), - object_popover.column_name.unwrap(), + object_popover.column_name, + object_popover.column_selection, ); }); @@ -850,7 +847,8 @@ pub fn connect_popovers(gui_data: &GuiData) { &object_popover.tree_view, object_popover.column_color.unwrap(), object_popover.column_modification_as_secs.unwrap(), - object_popover.column_name.unwrap(), + object_popover.column_name, + object_popover.column_selection, ); }); @@ -865,7 +863,8 @@ pub fn connect_popovers(gui_data: &GuiData) { &object_popover.tree_view, object_popover.column_color.unwrap(), object_popover.column_modification_as_secs.unwrap(), - object_popover.column_name.unwrap(), + object_popover.column_name, + object_popover.column_selection, ); }); @@ -880,7 +879,8 @@ pub fn connect_popovers(gui_data: &GuiData) { &object_popover.tree_view, object_popover.column_color.unwrap(), object_popover.column_modification_as_secs.unwrap(), - object_popover.column_name.unwrap(), + object_popover.column_name, + object_popover.column_selection, ); }); @@ -896,8 +896,9 @@ pub fn connect_popovers(gui_data: &GuiData) { &gui_data_clone, &object_popover.tree_view, object_popover.column_color, - object_popover.column_name.unwrap(), - object_popover.column_path.unwrap(), + object_popover.column_name, + object_popover.column_path, + object_popover.column_selection, ); }); @@ -913,8 +914,9 @@ pub fn connect_popovers(gui_data: &GuiData) { &gui_data_clone, &object_popover.tree_view, object_popover.column_color, - object_popover.column_name.unwrap(), - object_popover.column_path.unwrap(), + object_popover.column_name, + object_popover.column_path, + object_popover.column_selection, ); }); @@ -930,6 +932,7 @@ pub fn connect_popovers(gui_data: &GuiData) { object_popover.column_color.unwrap(), object_popover.column_size_as_bytes.unwrap(), object_popover.column_dimensions.unwrap(), + object_popover.column_selection, ); }); @@ -945,6 +948,7 @@ pub fn connect_popovers(gui_data: &GuiData) { object_popover.column_color.unwrap(), object_popover.column_size_as_bytes.unwrap(), object_popover.column_dimensions.unwrap(), + object_popover.column_selection, ); }); } diff --git a/czkawka_gui/src/create_tree_view.rs b/czkawka_gui/src/create_tree_view.rs index fbe742b..ffeb11a 100644 --- a/czkawka_gui/src/create_tree_view.rs +++ b/czkawka_gui/src/create_tree_view.rs @@ -3,6 +3,27 @@ use gtk::prelude::*; use gtk::TreeViewColumn; pub fn create_tree_view_duplicates(tree_view: &mut gtk::TreeView) { + let model = get_list_store(tree_view); + + let renderer = gtk::CellRendererToggle::new(); + renderer.connect_toggled(move |_r, path| { + let iter = model.iter(&path).unwrap(); + let mut fixed = model + .value(&iter, ColumnsDuplicates::ActiveSelectButton as i32) + .get::() + .unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err)); + fixed = !fixed; + model.set_value(&iter, ColumnsDuplicates::ActiveSelectButton as u32, &fixed.to_value()); + }); + let column = gtk::TreeViewColumn::new(); + column.pack_start(&renderer, true); + column.set_resizable(false); + column.set_fixed_width(30); + column.add_attribute(&renderer, "visible", ColumnsDuplicates::VisibleSelectButton as i32); + column.add_attribute(&renderer, "active", ColumnsDuplicates::ActiveSelectButton as i32); + column.add_attribute(&renderer, "cell-background", ColumnsDuplicates::Color as i32); + tree_view.append_column(&column); + let renderer = gtk::CellRendererText::new(); let column: gtk::TreeViewColumn = TreeViewColumn::new(); column.pack_start(&renderer, true); @@ -40,6 +61,25 @@ pub fn create_tree_view_duplicates(tree_view: &mut gtk::TreeView) { } pub fn create_tree_view_empty_folders(tree_view: &mut gtk::TreeView) { + let model = get_list_store(tree_view); + + let renderer = gtk::CellRendererToggle::new(); + renderer.connect_toggled(move |_r, path| { + let iter = model.iter(&path).unwrap(); + let mut fixed = model + .value(&iter, ColumnsEmptyFolders::ActiveSelectButton as i32) + .get::() + .unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err)); + fixed = !fixed; + model.set_value(&iter, ColumnsEmptyFolders::ActiveSelectButton as u32, &fixed.to_value()); + }); + let column = gtk::TreeViewColumn::new(); + column.pack_start(&renderer, true); + column.set_resizable(false); + column.set_fixed_width(30); + column.add_attribute(&renderer, "active", ColumnsEmptyFolders::ActiveSelectButton as i32); + tree_view.append_column(&column); + let renderer = gtk::CellRendererText::new(); let column: gtk::TreeViewColumn = TreeViewColumn::new(); column.pack_start(&renderer, true); @@ -71,6 +111,25 @@ pub fn create_tree_view_empty_folders(tree_view: &mut gtk::TreeView) { } pub fn create_tree_view_big_files(tree_view: &mut gtk::TreeView) { + let model = get_list_store(tree_view); + + let renderer = gtk::CellRendererToggle::new(); + renderer.connect_toggled(move |_r, path| { + let iter = model.iter(&path).unwrap(); + let mut fixed = model + .value(&iter, ColumnsBigFiles::ActiveSelectButton as i32) + .get::() + .unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err)); + fixed = !fixed; + model.set_value(&iter, ColumnsBigFiles::ActiveSelectButton as u32, &fixed.to_value()); + }); + let column = gtk::TreeViewColumn::new(); + column.pack_start(&renderer, true); + column.set_resizable(false); + column.set_fixed_width(30); + column.add_attribute(&renderer, "active", ColumnsBigFiles::ActiveSelectButton as i32); + tree_view.append_column(&column); + let renderer = gtk::CellRendererText::new(); let column: gtk::TreeViewColumn = TreeViewColumn::new(); column.pack_start(&renderer, true); @@ -111,6 +170,25 @@ pub fn create_tree_view_big_files(tree_view: &mut gtk::TreeView) { } pub fn create_tree_view_temporary_files(tree_view: &mut gtk::TreeView) { + let model = get_list_store(tree_view); + + let renderer = gtk::CellRendererToggle::new(); + renderer.connect_toggled(move |_r, path| { + let iter = model.iter(&path).unwrap(); + let mut fixed = model + .value(&iter, ColumnsTemporaryFiles::ActiveSelectButton as i32) + .get::() + .unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err)); + fixed = !fixed; + model.set_value(&iter, ColumnsTemporaryFiles::ActiveSelectButton as u32, &fixed.to_value()); + }); + let column = gtk::TreeViewColumn::new(); + column.pack_start(&renderer, true); + column.set_resizable(false); + column.set_fixed_width(30); + column.add_attribute(&renderer, "active", ColumnsTemporaryFiles::ActiveSelectButton as i32); + tree_view.append_column(&column); + let renderer = gtk::CellRendererText::new(); let column: gtk::TreeViewColumn = TreeViewColumn::new(); column.pack_start(&renderer, true); @@ -142,6 +220,25 @@ pub fn create_tree_view_temporary_files(tree_view: &mut gtk::TreeView) { } pub fn create_tree_view_empty_files(tree_view: &mut gtk::TreeView) { + let model = get_list_store(tree_view); + + let renderer = gtk::CellRendererToggle::new(); + renderer.connect_toggled(move |_r, path| { + let iter = model.iter(&path).unwrap(); + let mut fixed = model + .value(&iter, ColumnsEmptyFiles::ActiveSelectButton as i32) + .get::() + .unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err)); + fixed = !fixed; + model.set_value(&iter, ColumnsEmptyFiles::ActiveSelectButton as u32, &fixed.to_value()); + }); + let column = gtk::TreeViewColumn::new(); + column.pack_start(&renderer, true); + column.set_resizable(false); + column.set_fixed_width(30); + column.add_attribute(&renderer, "active", ColumnsEmptyFiles::ActiveSelectButton as i32); + tree_view.append_column(&column); + let renderer = gtk::CellRendererText::new(); let column: gtk::TreeViewColumn = TreeViewColumn::new(); column.pack_start(&renderer, true); @@ -173,6 +270,27 @@ pub fn create_tree_view_empty_files(tree_view: &mut gtk::TreeView) { } pub fn create_tree_view_similar_images(tree_view: &mut gtk::TreeView) { + let model = get_list_store(tree_view); + + let renderer = gtk::CellRendererToggle::new(); + renderer.connect_toggled(move |_r, path| { + let iter = model.iter(&path).unwrap(); + let mut fixed = model + .value(&iter, ColumnsSimilarImages::ActiveSelectButton as i32) + .get::() + .unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err)); + fixed = !fixed; + model.set_value(&iter, ColumnsSimilarImages::ActiveSelectButton as u32, &fixed.to_value()); + }); + let column = gtk::TreeViewColumn::new(); + column.pack_start(&renderer, true); + column.set_resizable(false); + column.set_fixed_width(30); + column.add_attribute(&renderer, "visible", ColumnsSimilarImages::VisibleSelectButton as i32); + column.add_attribute(&renderer, "active", ColumnsSimilarImages::ActiveSelectButton as i32); + column.add_attribute(&renderer, "cell-background", ColumnsSimilarImages::Color as i32); + tree_view.append_column(&column); + let renderer = gtk::CellRendererText::new(); let column: gtk::TreeViewColumn = TreeViewColumn::new(); column.pack_start(&renderer, true); @@ -253,6 +371,25 @@ pub fn create_tree_view_directories(tree_view: &mut gtk::TreeView) { } pub fn create_tree_view_zeroed_files(tree_view: &mut gtk::TreeView) { + let model = get_list_store(tree_view); + + let renderer = gtk::CellRendererToggle::new(); + renderer.connect_toggled(move |_r, path| { + let iter = model.iter(&path).unwrap(); + let mut fixed = model + .value(&iter, ColumnsZeroedFiles::ActiveSelectButton as i32) + .get::() + .unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err)); + fixed = !fixed; + model.set_value(&iter, ColumnsZeroedFiles::ActiveSelectButton as u32, &fixed.to_value()); + }); + let column = gtk::TreeViewColumn::new(); + column.pack_start(&renderer, true); + column.set_resizable(false); + column.set_fixed_width(30); + column.add_attribute(&renderer, "active", ColumnsZeroedFiles::ActiveSelectButton as i32); + tree_view.append_column(&column); + let renderer = gtk::CellRendererText::new(); let column: gtk::TreeViewColumn = TreeViewColumn::new(); column.pack_start(&renderer, true); @@ -293,6 +430,27 @@ pub fn create_tree_view_zeroed_files(tree_view: &mut gtk::TreeView) { } pub fn create_tree_view_same_music(tree_view: &mut gtk::TreeView) { + let model = get_list_store(tree_view); + + let renderer = gtk::CellRendererToggle::new(); + renderer.connect_toggled(move |_r, path| { + let iter = model.iter(&path).unwrap(); + let mut fixed = model + .value(&iter, ColumnsSameMusic::ActiveSelectButton as i32) + .get::() + .unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err)); + fixed = !fixed; + model.set_value(&iter, ColumnsSameMusic::ActiveSelectButton as u32, &fixed.to_value()); + }); + let column = gtk::TreeViewColumn::new(); + column.pack_start(&renderer, true); + column.set_resizable(false); + column.set_fixed_width(30); + column.add_attribute(&renderer, "visible", ColumnsSameMusic::VisibleSelectButton as i32); + column.add_attribute(&renderer, "active", ColumnsSameMusic::ActiveSelectButton as i32); + column.add_attribute(&renderer, "cell-background", ColumnsSameMusic::Color as i32); + tree_view.append_column(&column); + let renderer = gtk::CellRendererText::new(); let column: gtk::TreeViewColumn = TreeViewColumn::new(); column.pack_start(&renderer, true); @@ -396,6 +554,25 @@ pub fn create_tree_view_same_music(tree_view: &mut gtk::TreeView) { } pub fn create_tree_view_invalid_symlinks(tree_view: &mut gtk::TreeView) { + let model = get_list_store(tree_view); + + let renderer = gtk::CellRendererToggle::new(); + renderer.connect_toggled(move |_r, path| { + let iter = model.iter(&path).unwrap(); + let mut fixed = model + .value(&iter, ColumnsInvalidSymlinks::ActiveSelectButton as i32) + .get::() + .unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err)); + fixed = !fixed; + model.set_value(&iter, ColumnsInvalidSymlinks::ActiveSelectButton as u32, &fixed.to_value()); + }); + let column = gtk::TreeViewColumn::new(); + column.pack_start(&renderer, true); + column.set_resizable(false); + column.set_fixed_width(30); + column.add_attribute(&renderer, "active", ColumnsInvalidSymlinks::ActiveSelectButton as i32); + tree_view.append_column(&column); + let renderer = gtk::CellRendererText::new(); let column: gtk::TreeViewColumn = TreeViewColumn::new(); column.pack_start(&renderer, true); @@ -445,6 +622,25 @@ pub fn create_tree_view_invalid_symlinks(tree_view: &mut gtk::TreeView) { } pub fn create_tree_view_broken_files(tree_view: &mut gtk::TreeView) { + let model = get_list_store(tree_view); + + let renderer = gtk::CellRendererToggle::new(); + renderer.connect_toggled(move |_r, path| { + let iter = model.iter(&path).unwrap(); + let mut fixed = model + .value(&iter, ColumnsBrokenFiles::ActiveSelectButton as i32) + .get::() + .unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err)); + fixed = !fixed; + model.set_value(&iter, ColumnsBrokenFiles::ActiveSelectButton as u32, &fixed.to_value()); + }); + let column = gtk::TreeViewColumn::new(); + column.pack_start(&renderer, true); + column.set_resizable(false); + column.set_fixed_width(30); + column.add_attribute(&renderer, "active", ColumnsBrokenFiles::ActiveSelectButton as i32); + tree_view.append_column(&column); + let renderer = gtk::CellRendererText::new(); let column: gtk::TreeViewColumn = TreeViewColumn::new(); column.pack_start(&renderer, true); diff --git a/czkawka_gui/src/help_functions.rs b/czkawka_gui/src/help_functions.rs index bdf8cf7..28eb58c 100644 --- a/czkawka_gui/src/help_functions.rs +++ b/czkawka_gui/src/help_functions.rs @@ -28,9 +28,12 @@ pub enum Message { BrokenFiles(BrokenFiles), } +#[derive(Debug)] pub enum ColumnsDuplicates { // Columns for duplicate treeview - Name = 0, + VisibleSelectButton = 0, + ActiveSelectButton, + Name, Path, Modification, ModificationAsSecs, @@ -40,7 +43,8 @@ pub enum ColumnsDuplicates { pub enum ColumnsEmptyFolders { // Columns for empty folder treeview - Name = 0, + ActiveSelectButton = 0, + Name, Path, Modification, } @@ -49,23 +53,28 @@ pub enum ColumnsDirectory { Path = 0, } pub enum ColumnsBigFiles { - Size = 0, + ActiveSelectButton = 0, + Size, Name, Path, Modification, } pub enum ColumnsEmptyFiles { - Name = 0, + ActiveSelectButton = 0, + Name, Path, Modification, } pub enum ColumnsTemporaryFiles { - Name = 0, + ActiveSelectButton = 0, + Name, Path, Modification, } pub enum ColumnsSimilarImages { - Similarity = 0, + VisibleSelectButton = 0, + ActiveSelectButton, + Similarity, Size, SizeAsBytes, Dimensions, @@ -77,14 +86,17 @@ pub enum ColumnsSimilarImages { TextColor, } pub enum ColumnsZeroedFiles { - Size = 0, + ActiveSelectButton = 0, + Size, SizeAsBytes, Name, Path, Modification, } pub enum ColumnsSameMusic { - Size = 0, + VisibleSelectButton = 0, + ActiveSelectButton, + Size, SizeAsBytes, Name, Path, @@ -99,7 +111,8 @@ pub enum ColumnsSameMusic { TextColor, } pub enum ColumnsInvalidSymlinks { - Name = 0, + ActiveSelectButton = 0, + Name, Path, DestinationPath, TypeOfError, @@ -107,7 +120,8 @@ pub enum ColumnsInvalidSymlinks { } pub enum ColumnsBrokenFiles { - Name = 0, + ActiveSelectButton = 0, + Name, Path, ErrorType, Modification, diff --git a/czkawka_gui/src/initialize_gui.rs b/czkawka_gui/src/initialize_gui.rs index 7fa65ac..02bcddc 100644 --- a/czkawka_gui/src/initialize_gui.rs +++ b/czkawka_gui/src/initialize_gui.rs @@ -52,7 +52,9 @@ pub fn initialize_gui(gui_data: &mut GuiData) { { // Duplicate Files { - let col_types: [glib::types::Type; 6] = [ + let col_types: [glib::types::Type; 8] = [ + glib::types::Type::BOOL, + glib::types::Type::BOOL, glib::types::Type::STRING, glib::types::Type::STRING, glib::types::Type::STRING, @@ -93,11 +95,24 @@ pub fn initialize_gui(gui_data: &mut GuiData) { return gtk::Inhibit(false); } if gui_data.settings.check_button_settings_confirm_group_deletion.is_active() - && check_if_deleting_all_files_in_group(&tree_view.clone(), ColumnsDuplicates::Color as i32, &gui_data.window_main, &gui_data.settings.check_button_settings_confirm_group_deletion) + && check_if_deleting_all_files_in_group( + &tree_view.clone(), + ColumnsDuplicates::Color as i32, + ColumnsDuplicates::ActiveSelectButton as i32, + &gui_data.window_main, + &gui_data.settings.check_button_settings_confirm_group_deletion, + ) { return gtk::Inhibit(false); } - tree_remove(&tree_view, ColumnsDuplicates::Name as i32, ColumnsDuplicates::Path as i32, ColumnsDuplicates::Color as i32, &gui_data); + tree_remove( + &tree_view, + ColumnsDuplicates::Name as i32, + ColumnsDuplicates::Path as i32, + ColumnsDuplicates::Color as i32, + ColumnsDuplicates::ActiveSelectButton as i32, + &gui_data, + ); } } gtk::Inhibit(false) @@ -105,7 +120,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) { } // Empty Folders { - let col_types: [glib::types::Type; 3] = [glib::types::Type::STRING, glib::types::Type::STRING, glib::types::Type::STRING]; + let col_types: [glib::types::Type; 4] = [glib::types::Type::BOOL, glib::types::Type::STRING, glib::types::Type::STRING, glib::types::Type::STRING]; let list_store: gtk::ListStore = gtk::ListStore::new(&col_types); let mut tree_view: gtk::TreeView = TreeView::with_model(&list_store); @@ -126,7 +141,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) { if let Some(button_number) = e.keycode() { // Handle delete button if button_number == 119 { - empty_folder_remover(&tree_view, ColumnsEmptyFolders::Name as i32, ColumnsEmptyFolders::Path as i32, &gui_data); + empty_folder_remover(&tree_view, ColumnsEmptyFolders::Name as i32, ColumnsEmptyFolders::Path as i32, ColumnsEmptyFolders::ActiveSelectButton as i32, &gui_data); } } gtk::Inhibit(false) @@ -134,7 +149,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) { } // Empty Files { - let col_types: [glib::types::Type; 3] = [glib::types::Type::STRING, glib::types::Type::STRING, glib::types::Type::STRING]; + let col_types: [glib::types::Type; 4] = [glib::types::Type::BOOL, glib::types::Type::STRING, glib::types::Type::STRING, glib::types::Type::STRING]; let list_store: gtk::ListStore = gtk::ListStore::new(&col_types); let mut tree_view: gtk::TreeView = TreeView::with_model(&list_store); @@ -155,7 +170,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) { if let Some(button_number) = e.keycode() { // Handle delete button if button_number == 119 { - basic_remove(&tree_view, ColumnsEmptyFiles::Name as i32, ColumnsEmptyFiles::Path as i32, &gui_data); + basic_remove(&tree_view, ColumnsEmptyFiles::Name as i32, ColumnsEmptyFiles::Path as i32, ColumnsEmptyFiles::ActiveSelectButton as i32, &gui_data); } } gtk::Inhibit(false) @@ -163,7 +178,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) { } // Temporary Files { - let col_types: [glib::types::Type; 3] = [glib::types::Type::STRING, glib::types::Type::STRING, glib::types::Type::STRING]; + let col_types: [glib::types::Type; 4] = [glib::types::Type::BOOL, glib::types::Type::STRING, glib::types::Type::STRING, glib::types::Type::STRING]; let list_store: gtk::ListStore = gtk::ListStore::new(&col_types); let mut tree_view: gtk::TreeView = TreeView::with_model(&list_store); @@ -184,7 +199,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) { if let Some(button_number) = e.keycode() { // Handle delete button if button_number == 119 { - basic_remove(&tree_view, ColumnsTemporaryFiles::Name as i32, ColumnsTemporaryFiles::Path as i32, &gui_data); + basic_remove(&tree_view, ColumnsTemporaryFiles::Name as i32, ColumnsTemporaryFiles::Path as i32, ColumnsTemporaryFiles::ActiveSelectButton as i32, &gui_data); } } gtk::Inhibit(false) @@ -192,7 +207,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) { } // Big Files { - let col_types: [glib::types::Type; 4] = [glib::types::Type::STRING, glib::types::Type::STRING, glib::types::Type::STRING, glib::types::Type::STRING]; + let col_types: [glib::types::Type; 5] = [glib::types::Type::BOOL, glib::types::Type::STRING, glib::types::Type::STRING, glib::types::Type::STRING, glib::types::Type::STRING]; let list_store: gtk::ListStore = gtk::ListStore::new(&col_types); let mut tree_view: gtk::TreeView = TreeView::with_model(&list_store); @@ -213,7 +228,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) { if let Some(button_number) = e.keycode() { // Handle delete button if button_number == 119 { - basic_remove(&tree_view, ColumnsBigFiles::Name as i32, ColumnsBigFiles::Path as i32, &gui_data); + basic_remove(&tree_view, ColumnsBigFiles::Name as i32, ColumnsBigFiles::Path as i32, ColumnsBigFiles::ActiveSelectButton as i32, &gui_data); } } gtk::Inhibit(false) @@ -224,7 +239,9 @@ pub fn initialize_gui(gui_data: &mut GuiData) { let image_preview_similar_images_clone = image_preview_similar_images.clone(); image_preview_similar_images.hide(); - let col_types: [glib::types::Type; 10] = [ + let col_types: [glib::types::Type; 12] = [ + glib::types::Type::BOOL, + glib::types::Type::BOOL, glib::types::Type::STRING, glib::types::Type::STRING, glib::types::Type::U64, @@ -271,11 +288,24 @@ pub fn initialize_gui(gui_data: &mut GuiData) { return gtk::Inhibit(false); } if gui_data.settings.check_button_settings_confirm_group_deletion.is_active() - && check_if_deleting_all_files_in_group(&tree_view.clone(), ColumnsSimilarImages::Color as i32, &gui_data.window_main, &gui_data.settings.check_button_settings_confirm_group_deletion) + && check_if_deleting_all_files_in_group( + &tree_view.clone(), + ColumnsSimilarImages::Color as i32, + ColumnsSimilarImages::ActiveSelectButton as i32, + &gui_data.window_main, + &gui_data.settings.check_button_settings_confirm_group_deletion, + ) { return gtk::Inhibit(false); } - tree_remove(&tree_view, ColumnsSimilarImages::Name as i32, ColumnsSimilarImages::Path as i32, ColumnsSimilarImages::Color as i32, &gui_data); + tree_remove( + &tree_view, + ColumnsSimilarImages::Name as i32, + ColumnsSimilarImages::Path as i32, + ColumnsSimilarImages::Color as i32, + ColumnsSimilarImages::ActiveSelectButton as i32, + &gui_data, + ); image_preview_similar_images_clone.hide(); } } @@ -285,7 +315,14 @@ pub fn initialize_gui(gui_data: &mut GuiData) { } // Zeroed Files { - let col_types: [glib::types::Type; 5] = [glib::types::Type::STRING, glib::types::Type::U64, glib::types::Type::STRING, glib::types::Type::STRING, glib::types::Type::STRING]; + let col_types: [glib::types::Type; 6] = [ + glib::types::Type::BOOL, + glib::types::Type::STRING, + glib::types::Type::U64, + glib::types::Type::STRING, + glib::types::Type::STRING, + glib::types::Type::STRING, + ]; let list_store: gtk::ListStore = gtk::ListStore::new(&col_types); let mut tree_view: gtk::TreeView = TreeView::with_model(&list_store); @@ -306,7 +343,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) { if let Some(button_number) = e.keycode() { // Handle delete button if button_number == 119 { - basic_remove(&tree_view, ColumnsZeroedFiles::Name as i32, ColumnsZeroedFiles::Path as i32, &gui_data); + basic_remove(&tree_view, ColumnsZeroedFiles::Name as i32, ColumnsZeroedFiles::Path as i32, ColumnsZeroedFiles::ActiveSelectButton as i32, &gui_data); } } gtk::Inhibit(false) @@ -314,7 +351,9 @@ pub fn initialize_gui(gui_data: &mut GuiData) { } // Same Music { - let col_types: [glib::types::Type; 13] = [ + let col_types: [glib::types::Type; 15] = [ + glib::types::Type::BOOL, + glib::types::Type::BOOL, glib::types::Type::STRING, glib::types::Type::U64, glib::types::Type::STRING, @@ -357,11 +396,24 @@ pub fn initialize_gui(gui_data: &mut GuiData) { return gtk::Inhibit(false); } if gui_data.settings.check_button_settings_confirm_group_deletion.is_active() - && check_if_deleting_all_files_in_group(&tree_view.clone(), ColumnsSameMusic::Color as i32, &gui_data.window_main, &gui_data.settings.check_button_settings_confirm_group_deletion) + && check_if_deleting_all_files_in_group( + &tree_view.clone(), + ColumnsSameMusic::Color as i32, + ColumnsSameMusic::ActiveSelectButton as i32, + &gui_data.window_main, + &gui_data.settings.check_button_settings_confirm_group_deletion, + ) { return gtk::Inhibit(false); } - tree_remove(&tree_view, ColumnsSameMusic::Name as i32, ColumnsSameMusic::Path as i32, ColumnsSameMusic::Color as i32, &gui_data); + tree_remove( + &tree_view, + ColumnsSameMusic::Name as i32, + ColumnsSameMusic::Path as i32, + ColumnsSameMusic::Color as i32, + ColumnsSameMusic::ActiveSelectButton as i32, + &gui_data, + ); } } gtk::Inhibit(false) @@ -369,7 +421,14 @@ pub fn initialize_gui(gui_data: &mut GuiData) { } // Invalid Symlinks { - let col_types: [glib::types::Type; 5] = [glib::types::Type::STRING, glib::types::Type::STRING, glib::types::Type::STRING, glib::types::Type::STRING, glib::types::Type::STRING]; + let col_types: [glib::types::Type; 6] = [ + glib::types::Type::BOOL, + glib::types::Type::STRING, + glib::types::Type::STRING, + glib::types::Type::STRING, + glib::types::Type::STRING, + glib::types::Type::STRING, + ]; let list_store: gtk::ListStore = gtk::ListStore::new(&col_types); let mut tree_view: gtk::TreeView = TreeView::with_model(&list_store); @@ -390,7 +449,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) { if let Some(button_number) = e.keycode() { // Handle delete button if button_number == 119 { - basic_remove(&tree_view, ColumnsInvalidSymlinks::Name as i32, ColumnsInvalidSymlinks::Path as i32, &gui_data); + basic_remove(&tree_view, ColumnsInvalidSymlinks::Name as i32, ColumnsInvalidSymlinks::Path as i32, ColumnsInvalidSymlinks::ActiveSelectButton as i32, &gui_data); } } gtk::Inhibit(false) @@ -398,7 +457,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) { } // Broken Files { - let col_types: [glib::types::Type; 4] = [glib::types::Type::STRING, glib::types::Type::STRING, glib::types::Type::STRING, glib::types::Type::STRING]; + let col_types: [glib::types::Type; 5] = [glib::types::Type::BOOL, glib::types::Type::STRING, glib::types::Type::STRING, glib::types::Type::STRING, glib::types::Type::STRING]; let list_store: gtk::ListStore = gtk::ListStore::new(&col_types); let mut tree_view: gtk::TreeView = TreeView::with_model(&list_store); @@ -419,7 +478,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) { if let Some(button_number) = e.keycode() { // Handle delete button if button_number == 119 { - basic_remove(&tree_view, ColumnsBrokenFiles::Name as i32, ColumnsBrokenFiles::Path as i32, &gui_data); + basic_remove(&tree_view, ColumnsBrokenFiles::Name as i32, ColumnsBrokenFiles::Path as i32, ColumnsBrokenFiles::ActiveSelectButton as i32, &gui_data); } } gtk::Inhibit(false) diff --git a/czkawka_gui/src/main.rs b/czkawka_gui/src/main.rs index 8348331..8e0f355 100644 --- a/czkawka_gui/src/main.rs +++ b/czkawka_gui/src/main.rs @@ -1,5 +1,6 @@ // Remove console window in Windows OS #![windows_subsystem = "windows"] +#![allow(clippy::collapsible_else_if)] mod connect_about_buttons; mod connect_button_delete; diff --git a/instructions/Instruction.md b/instructions/Instruction.md index 2ba30ef..fb1d0a7 100644 --- a/instructions/Instruction.md +++ b/instructions/Instruction.md @@ -3,7 +3,7 @@ - [GUI](#gui-gtk) - [CLI](#cli) - [Config / Cache files](#configcache-files) -- [Tips and tricks](#tips-and-tricks) +- [Tips, tricks and known bugs](#tips-tricks-and-known-bugs) - [Tools](#tools) Czkawka for now contains two independent frontends - the terminal and graphical interface which share the core module. @@ -15,7 +15,7 @@ This code also has good support for multi-threading. ### GUI overview The GUI is built from different pieces: -- Red - Program settings, contains info about included/excluded directories which user may want to check. Also, there is a tab with allowed extensions, which allows users to choose which type of files they want to check. Next category is Excluded items, which allows to discard specific path by using `*` wildcard - so `/home/*` means that e.g. `/home/rafal/` will be ignored but not `/home/czkawka/`. The last one is settings tab which allows to save configuration of the program, reset and load it when needed. +- Red - Program settings, contains info about included/excluded directories which user may want to check. Also, there is a tab with allowed extensions, which allows users to choose which type of files they want to check. Next category is Excluded items, which allows to discard specific path by using `*` wildcard - so `/home/ra*` means that e.g. `/home/rafal/` will be ignored but not `/home/czkawka/`. The last one is settings tab which allows to save configuration of the program, reset and load it when needed. - Green - This allows to choose which tool we want to use. - Blue - Here are settings for the current tool, which we want/need to configure - Pink - Window in which results of searching are printed @@ -85,12 +85,19 @@ Linux - `/home/username/.cache/czkawka` Mac - `/Users/Username/Library/Caches/pl.Qarmin.Czkawka` Windows - `C:\Users\Username\AppData\Local\Qarmin\Czkawka\cache` -## Tips and Tricks +## Tips, Tricks and Known Bugs - **Manually adding multiple directories** You can manually edit config file `czkawka_gui_config.txt` and add/remove/change directories as you want. After setting required values, configuration must be loaded to Czkawka. - **Slow checking of little number similar images** If you checked before a large number of images (several tens of thousands) and they are still present on the disk, then the required information about all of them is loaded from and saved to the cache, even if you are working with only few image files. You can rename cache file `cache_similar_image.txt`(to be able to use it again) or delete it - cache will then regenerate but with smaller number of entries and this way it should load and save a lot of faster. +- **Not all columns are visible** + For now it is possible that some columns will not be visible when some are too wide. There are 2 workarounds for now + - View can be scrolled via horizontal scroll bar + - Size of other columns can be slimmed + + This is handled via https://github.com/qarmin/czkawka/issues/169 +![AA](https://user-images.githubusercontent.com/41945903/125684641-728e264a-34ab-41b1-9853-ab45dc25551f.png) # Tools